Average Transaction Time: Algorand vs Others - time check using Python.

Average Transaction Time: Algorand vs Others - time check using Python.

By Ddev | Ddev@ALgorand | 29 Jun 2020


For a Blockchain to be tagged "fast", it's transaction time must be relatively low, at least not tandem to PayPal's, hehehe. This is relative to block time finality. A block is simply final when numbers of transactions are added to the ledger. Each transaction would have seen confirmation i.e moment the value sent by account A to account B increased his balance. Such transaction is final and block it is added is final meaning, no reversal can take place. For simplicity, I will not dive deeper into block finality. See a walk through on what block finality is. A Blockchain is able to handle increasing or a relatively high constant number of transactions if the time it takes a transaction to be added to block or time it takes to mine a block is low, mostly within seconds. 

Although EOS is said to have near-instant transaction time, but there are many reasons you do not want to have your smart contract deployed on EOS or use as Assets' haven or rather porting. EOS is typically flooded with gambling dApps except you're not in the league. According to Kraken, average transaction time for Ether to reflect on Kraken is 6 minutes. This is because Kraken requires at least 30 confirmation to ensure that it is a valid transaction. That happens to transactions passing from Ethereum platform to an exchange. Usually, effecting a transfer of Ether from a decentralized wallet to another would consume between 20 secs and 40 secs of time in the absence of congestion. 


Some times, it takes longer where the network is clogged with transactions and it may last for minutes or even hours. Trying to make a  change to the state of the blockchain during congestion raises the gas price. If Sender specified lesser gas than network's, transaction may spend more time in pool. On the Bitcoin blockchain, the case is far from comparison. Designers of Algorand protocol do not only crave for speed, scalability and decentralization but achieving security and dynamic fee that enable performing transactions with considerably low fee. Sending transactions between accounts on Algorand is confirmed between 5 secs and 8 secs. Reading to the latter is largely influenced by reading, network request, response and the service provider. 



Checking Transaction Time Using Python : decorator, time and log modules. 


To establish the fact, I have created a decorator.py file and testing will be on Algorand Testnet since it mirrors the Mainnet. 


from algosdk import algod
from algosdk import  transaction
import datetime, sys, time
import logging

# Connecting to algorand testnet
class Connect():
    def __init__(self):
        self.algod_address = "https://testnet-algorand.api.purestake.io/ps1"# declaring the third party API
        self.algod_token = "eVXi2wPlDE8uF15mkil5Z2FzRm20GTJg8r3R7ldv" # <-----shortened - my personal API token // Get your from https://purestake.com
        self.headers = {"X-API-Key": self.algod_token}

    def connectToNetwork(self):       
        # establish connection
        return algod.AlgodClient(self.algod_token, self.algod_address, self.headers)

sendr_ky = "QZkBrhS8lENmn30GyKMPufFPdjG88Knz0Fj279+jxVdvpJWOFxXz9CWLZ2tSAsnfk0TIcKtg..............."
ctt = Connect()
connecting = ctt.connectToNetwork()
# Get suggeted parameters from the network
params = connecting.suggested_params()


Using a decorator, my_timer() expects a function as an input, wraps it in wrapFunc(). Returns of functions will be logged in to a file created in line 2 of my_timer(). Note that sendtransaction() will not terminate until transaction process is completed. It sends transaction and wait until token arrives at destination, then returns codes in the If block.


def my_timer(transfer_func):
    logging.basicConfig(filename='{}.log'.format(transfer_func.__name__), level=logging.INFO)
    def wrapFunc(*args, **kwargs):
        import time
        start_time = datetime.datetime.now()
        operation = transfer_func(*args)
        end_time = datetime.datetime.now()
        cnfm_time = (end_time - start_time)
        info = '{} ran in: {} secs'.format(transfer_func.__name__, cnfm_time)
        logging.info(" ...@Total transaction time... \n Ran with args: {}.\n Start time: {}\n Operation Performed: {}\n End: {} \n Info: {}".format(args, start_time, transfer_func.__name__, end_time, info))
        return operation
    return wrapFunc



//set decorator

def sendtransaction(senderAddr, rec): //swap for transferFunc()
    extime_1 = datetime.datetime.now()
    logging.basicConfig(filename='{}.log'.format('sendtransaction'), level=logging.INFO)//log File
    init_bal = connecting.account_info(rec)['amount']
    bal = (bool(init_bal == init_bal))
    note = "Your account is funded".encode()
    send_time_start = datetime.datetime.now() - extime_1
    //transaction parameters
    txn_start = datetime.datetime.now()
    txn = {
        "sender": senderAddr,
        "receiver": rec,
        "fee": params.get('minFee'),
        "flat_fee": True,
        "amt": 1000000,
        "first": params.get('lastRound'),
        "last": params.get('lastRound') + 1000,
        "note": note,
        "gen": params.get('genesisID'),
        "gh": params.get('genesishashb64')
    # validate token transfer
    preTrxn = transaction.PaymentTxn(**txn)
    trxn = preTrxn.sign(sendr_ky)
    txn_ID = connecting.send_transaction(trxn, headers={'content-type': 'application/x-binary'})

    expected_bal = init_bal + txn['amt']
    while (bal):
        if (connecting.account_info(rec)['amount'] == expected_bal):
            confirmed = "Confirmed!"
            end = datetime.datetime.now()
            actual_comfirm = end - txn_start
            trxnID = "Transaction confirmed with Id: {} in {}".format(txn_ID, actual_comfirm)
            logging.info(" ...@last epoch time... \n {}!\n Initiat balance: {}.\n Additional time spent: {}.\n Transaction sent time: {}.\n Transaction end: {}.\n Time Used: {}.\n Current balance: {}.\n".format(confirmed, init_bal, send_time_start, txn_start, end, actual_comfirm, connecting.account_info(rec)['amount']))
            wait = "Not yet confirmed..."

sendtransaction(sent_frm, rec_addr)


Now, let's run the function as shown above. You should get these information below in your sendtransaction.log


  • Analyzing the log shows the receiver's balance captured in line 6.
  • Additional time spent Approximately 1 second which represents time it took to analyze line 1 to line 7 of sendtransaction()
  • Time used represents the difference between time at which transaction is being prepared starting from txn of type dict parameters and exact time Algo reflects in recipient's account - end in the while loop which is 6 seconds 810274ms.
  • Then, recipient's current balance is returned. 
  • If we could account for network request and response time, we would be left with about 5 seconds which shows how long it takes to deduct value from sender's account and increase recipient's with same amount.



Again, to be sure we are on the right path, let us run the sendtransaction() One more time. 




Although, while running this code, my network was a bit unstable, yet you may get different time timestamp but it should be within same window. 


I'm a crypto lover, a developer(python, Solidity, Javascript, CSS, HTML), ambassador, blockchain enthusiast and a writer. I am always learning.


A technology company that built and developed the world’s first open, permissionless, pure proof-of-stake blockchain protocol that, without forking, provides the necessary security, scalability, and decentralization needed for today’s economy. With an award-winning team, we enable traditional finance and decentralized financial businesses to embrace the world of frictionless finance.

Send a $0.01 microtip in crypto to the author, and earn yourself as you read!

20% to author / 80% to me.
We pay the tips from our rewards pool.