Skip to content

Commit

Permalink
fix(algod): fix AlgodClient.WaitForConfirmation not using correct w…
Browse files Browse the repository at this point in the history
…ait time

Previously, `AlgodClient.WaitForConfirmation` was ignorant of how often the blocks would be
confirmed, and it would just poll every time interval. Now, it has been refactored to use the
`AlgodClient.WaitForBlock` method to check every block until a maxWaitRounds amount of rounds has
passed.
  • Loading branch information
jasonboukheir committed Jun 19, 2022
1 parent 3eccd0b commit 169be0b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 12 deletions.
44 changes: 33 additions & 11 deletions Runtime/CareBoo.AlgoSdk/NodeServices/Algod/AlgodClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ public AlgodClient(string address, params Header[] headers) : this(address, null

public Header[] Headers => headers;

/// <summary>
/// Send a signed transaction struct
/// </summary>
/// <param name="txn">The signed transaction struct to send</param>
/// <typeparam name="T">The type of the signed transaction.</typeparam>
/// <returns>A response from the algod service.</returns>
public AlgoApiRequest.Sent<PostTransactionsResponse> SendTransaction<T>(SignedTxn<T> txn)
where T : struct, ITransaction, IEquatable<T>
{
Expand All @@ -68,26 +74,42 @@ public AlgoApiRequest.Sent<PostTransactionsResponse> SendTransaction<T>(SignedTx
/// Utility method to wait for a transaction to be confirmed given a transaction id.
/// </summary>
/// <param name="txid">The transaction id to wait for.</param>
/// <param name="pollInterval">An optional <see cref="TimeSpan"/> to control how often this method polls the algod service.</param>
/// <param name="maxWaitRounds">How many rounds should this method wait for confirmation before cancelling early?</param>
/// <param name="cancellationToken">An optional token for cancelling this task early.</param>
/// <returns>The algod response that either caused an error or showed a confirmed round.</returns>
public async UniTask<AlgoApiResponse<PendingTransactionResponse>> WaitForConfirmation(
string txid,
Optional<TimeSpan> pollInterval = default,
uint maxWaitRounds = default,
CancellationToken cancellationToken = default
)
{
await UniTask.Delay(TimeSpan.FromSeconds(4), cancellationToken: cancellationToken);
var pollInt = pollInterval.Else(TimeSpan.FromMilliseconds(100));
var response = await PendingTransactionInformation(txid)
.WithCancellation(cancellationToken);
while (!response.Error && response.Payload.ConfirmedRound == default)
if (maxWaitRounds == 0)
{
maxWaitRounds = 1000;
}

var statusResponse = await GetStatus();
if (statusResponse.Error)
{
return statusResponse.Cast<PendingTransactionResponse>();
}

var lastRound = statusResponse.Payload.LastRound;
var currentRound = statusResponse.Payload.LastRound + 1;

while (currentRound < lastRound + maxWaitRounds)
{
await UniTask.Delay(pollInt, cancellationToken: cancellationToken);
response = await PendingTransactionInformation(txid)
.WithCancellation(cancellationToken);
var txnInfoResponse = await PendingTransactionInformation(txid);
var (txnInfoError, txnInfo) = txnInfoResponse;
if (txnInfoError || !string.IsNullOrEmpty(txnInfo.PoolError) || txnInfo.ConfirmedRound > 0)
{
return txnInfoResponse;
}

await WaitForBlock(currentRound);
currentRound++;
}
return response;
return new AlgoApiResponse(new ErrorResponse { Message = $"Waiting for transaction id {txid} timed out" });
}

[Obsolete("Call AlgodClient.GetGenesis instead.")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public struct AlgoApiResponse : IAlgoApiResponse
readonly Result status;
readonly long responseCode;
readonly ContentType contentType;
ErrorResponse error;
readonly ErrorResponse error;

public AlgoApiResponse(UnityWebRequest completedRequest)
{
Expand All @@ -34,6 +34,15 @@ public AlgoApiResponse(UnityWebRequest completedRequest)
completedRequest.Dispose();
}

public AlgoApiResponse(ErrorResponse error)
{
data = null;
status = Result.ProtocolError;
responseCode = 0;
contentType = ContentType.None;
this.error = error;
}

public byte[] Data => data;

public long ResponseCode => responseCode;
Expand Down Expand Up @@ -122,6 +131,11 @@ public AlgoApiResponse(AlgoApiResponse response, T payload)

public string GetText() => rawResponse.GetText();

public AlgoApiResponse<U> Cast<U>()
{
return new AlgoApiResponse<U>(rawResponse);
}

public static implicit operator AlgoApiResponse<T>(AlgoApiResponse response)
{
return new AlgoApiResponse<T>(response);
Expand Down

0 comments on commit 169be0b

Please sign in to comment.