DEV Community

BC
BC

Posted on

wait-for-block-after implementation in Algorand

Algorand has an API to get status after waiting for a specified round

I saw it gets used in the waitForConfirmation function called something like:

In Golang:

status, err = client.StatusAfterBlock(currentRound).Do(context.Background()) 
Enter fullscreen mode Exit fullscreen mode

In Python:

client.status_after_block(current_round) 
Enter fullscreen mode Exit fullscreen mode

The implementation for this API is that basically Algorand will block the http request until it gets that specified round, or a timeout (1 minute) happens. The key part of the source code is like this:

 select { case <-v2.Shutdown: return internalError(ctx, err, errServiceShuttingDown, v2.Log) case <-time.After(1 * time.Minute): case <-ledger.Wait(basics.Round(round + 1)): } // Return status after the wait return v2.GetStatus(ctx) 
Enter fullscreen mode Exit fullscreen mode

Reference

The waitForConfirmation in Python:

def wait_for_confirmation(client, transaction_id, timeout): start_round = client.status()["last-round"] + 1 current_round = start_round while current_round < start_round + timeout: try: pending_txn = client.pending_transaction_info(transaction_id) except Exception: return if pending_txn.get("confirmed-round", 0) > 0: return pending_txn elif pending_txn["pool-error"]: raise Exception( 'pool error: {}'.format(pending_txn["pool-error"])) client.status_after_block(current_round) current_round += 1 raise Exception( 'pending tx not found in timeout rounds, timeout value = : {}'.format(timeout)) 
Enter fullscreen mode Exit fullscreen mode

The waitForConfirmation in Go:

func waitForConfirmation(txID string, client *algod.Client, timeout uint64) (models.PendingTransactionInfoResponse, error) { pt := new(models.PendingTransactionInfoResponse) if client == nil || txID == "" || timeout < 0 { fmt.Printf("Bad arguments for waitForConfirmation") var msg = errors.New("Bad arguments for waitForConfirmation") return *pt, msg } status, err := client.Status().Do(context.Background()) if err != nil { fmt.Printf("error getting algod status: %s\n", err) var msg = errors.New(strings.Join([]string{"error getting algod status: "}, err.Error())) return *pt, msg } startRound := status.LastRound + 1 currentRound := startRound for currentRound < (startRound + timeout) { *pt, _, err = client.PendingTransactionInformation(txID).Do(context.Background()) if err != nil { fmt.Printf("error getting pending transaction: %s\n", err) var msg = errors.New(strings.Join([]string{"error getting pending transaction: "}, err.Error())) return *pt, msg } if pt.ConfirmedRound > 0 { fmt.Printf("Transaction "+txID+" confirmed in round %d\n", pt.ConfirmedRound) return *pt, nil } if pt.PoolError != "" { fmt.Printf("There was a pool error, then the transaction has been rejected!") var msg = errors.New("There was a pool error, then the transaction has been rejected") return *pt, msg } fmt.Printf("waiting for confirmation\n") status, err = client.StatusAfterBlock(currentRound).Do(context.Background()) currentRound++ } msg := errors.New("Tx not found in round range") return *pt, msg } 
Enter fullscreen mode Exit fullscreen mode

The above code are taken from the "how-to" section in this page.

Top comments (0)