github.com/algorand/go-algorand-sdk@v1.24.0/future/waitForConfirmation.go (about)

     1  package future
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/algorand/go-algorand-sdk/client/v2/algod"
     8  	"github.com/algorand/go-algorand-sdk/client/v2/common"
     9  	"github.com/algorand/go-algorand-sdk/client/v2/common/models"
    10  )
    11  
    12  // `WaitForConfirmation` waits for a pending transaction to be accepted by the network
    13  // `txid`: The ID of the pending transaction to wait for
    14  // `waitRounds`: The number of rounds to block before exiting with an error.
    15  func WaitForConfirmation(c *algod.Client, txid string, waitRounds uint64, ctx context.Context, headers ...*common.Header) (txInfo models.PendingTransactionInfoResponse, err error) {
    16  	response, err := c.Status().Do(ctx, headers...)
    17  	if err != nil {
    18  		return
    19  	}
    20  
    21  	lastRound := response.LastRound
    22  	currentRound := lastRound + 1
    23  
    24  	for {
    25  		// Check that the `waitRounds` has not passed
    26  		if currentRound > lastRound+waitRounds {
    27  			err = fmt.Errorf("Wait for transaction id %s timed out", txid)
    28  			return
    29  		}
    30  
    31  		txInfo, _, err = c.PendingTransactionInformation(txid).Do(ctx, headers...)
    32  		if err == nil {
    33  			if len(txInfo.PoolError) != 0 {
    34  				// The transaction has been rejected
    35  				err = fmt.Errorf("Transaction rejected: %s", txInfo.PoolError)
    36  				return
    37  			}
    38  
    39  			if txInfo.ConfirmedRound > 0 {
    40  				// The transaction has been confirmed
    41  				return
    42  			}
    43  		}
    44  		// ignore errors from PendingTransactionInformation, since it may return 404 if the algod
    45  		// instance is behind a load balancer and the request goes to a different algod than the
    46  		// one we submitted the transaction to
    47  		err = nil
    48  
    49  		// Wait until the block for the `currentRound` is confirmed
    50  		response, err = c.StatusAfterBlock(currentRound).Do(ctx, headers...)
    51  		if err != nil {
    52  			return
    53  		}
    54  
    55  		// Increment the `currentRound`
    56  		currentRound += 1
    57  	}
    58  }