Skip to content

Commit

Permalink
Merge pull request #90 from tyronbrand/new-gRPC-methods
Browse files Browse the repository at this point in the history
new gRPC methods
  • Loading branch information
tyronbrand authored Oct 16, 2022
2 parents f5892c7 + 8c1bf8e commit 452c00b
Show file tree
Hide file tree
Showing 15 changed files with 383 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Flow.Net.Sdk.Client.Grpc;
using Flow.Net.Sdk.Core.Client;
using System;
using System.Threading.Tasks;

namespace Flow.Net.Examples.TransactionExamples
{
public class GetTransactionResultByIndexExample : ExampleBase
{
public static async Task RunAsync(IFlowClient flowClient)
{
Console.WriteLine("\nRunning GetTransactionExample\n");
FlowClient = flowClient;
await PrepTransactionId();
await Demo();
Console.WriteLine("\nGetTransactionExample Complete\n");
}

private static async Task Demo()
{
if(FlowClient is FlowGrpcClient grpcClient)
{
var block = await grpcClient.GetLatestBlockAsync();
}
}

private static async Task<string> PrepTransactionId()
{
return await RandomTransactionAsync();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Flow.Net.Sdk.Client.Grpc;
using Flow.Net.Sdk.Core.Client;
using System;
using System.Threading.Tasks;

namespace Flow.Net.Examples.TransactionExamples
{
public class GetTransactionResultsByBlockIdExample : ExampleBase
{
public static async Task RunAsync(IFlowClient flowClient)
{
Console.WriteLine("\nRunning GetTransactionResultsByBlockId\n");
FlowClient = flowClient;
await PrepTransactionId();
await Demo();
Console.WriteLine("\nGetTransactionResultsByBlockId Complete\n");
}

private static async Task Demo()
{
if(FlowClient is FlowGrpcClient grpcClient)
{
var block = await grpcClient.GetLatestBlockAsync();

var response = await grpcClient.GetTransactionResultsByBlockIdAsync(block.Header.Id);
}
}

private static async Task<string> PrepTransactionId()
{
return await RandomTransactionAsync();
}
}
}
84 changes: 80 additions & 4 deletions src/Flow.Net.Sdk.Client.Grpc/FlowGrpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ public async Task<FlowTransactionId> SendTransactionAsync(FlowTransaction flowTr
}
}

public Task<FlowTransactionResult> WaitForSealAsync(string transactionId, int delayMs = 1000, int timeoutMs = 30000) => WaitForSealAsync(transactionId, delayMs, timeoutMs, new CallOptions(), CancellationToken.None);
public Task<FlowTransactionResult> WaitForSealAsync(string transactionId, int delayMs = 1000, int timeoutMs = 30000) => WaitForSealAsync(transactionId, delayMs, timeoutMs, new CallOptions());

/// <summary>
/// Waits for transaction result status to be sealed.
Expand All @@ -574,10 +574,9 @@ public async Task<FlowTransactionId> SendTransactionAsync(FlowTransaction flowTr
/// <param name="delayMs"></param>
/// <param name="timeoutMs"></param>
/// <param name="options"></param>
/// <param name="cancellationToken"></param>
/// <returns><see cref="FlowTransactionResult"/></returns>
/// <exception cref="FlowException"></exception>
public async Task<FlowTransactionResult> WaitForSealAsync(string transactionId, int delayMs, int timeoutMs, CallOptions options, CancellationToken cancellationToken)
public async Task<FlowTransactionResult> WaitForSealAsync(string transactionId, int delayMs, int timeoutMs, CallOptions options)
{
var startTime = DateTime.UtcNow;
while (true)
Expand All @@ -595,7 +594,7 @@ public async Task<FlowTransactionResult> WaitForSealAsync(string transactionId,
if (DateTime.UtcNow.Subtract(startTime).TotalMilliseconds > timeoutMs)
throw new FlowException("Timed out waiting for seal.");

await Task.Delay(delayMs, cancellationToken).ConfigureAwait(false);
await Task.Delay(delayMs).ConfigureAwait(false);
}
}

Expand All @@ -618,5 +617,82 @@ public async Task<FlowTransactionResult> WaitForSealAsync(string transactionId,
throw new FlowException("GetLatestProtocolStateSnapshot request failed.", exception);
}
}

/// <summary>
/// Gets the result of a transaction at a specified block and index
/// </summary>
/// <param name="blockId"></param>
/// <param name="index"></param>
/// <param name="options"></param>
/// <returns><see cref="FlowTransactionResult"/></returns>
/// <exception cref="FlowException"></exception>
public async Task<FlowTransactionResult> GetTransactionResultByIndexAsync(string blockId, uint index, CallOptions options = new CallOptions())
{
try
{
var response = await _client.GetTransactionResultByIndexAsync(
new GetTransactionByIndexRequest
{
BlockId = blockId.HexToByteString(),
Index = index
}, options).ConfigureAwait(false);

return response.ToFlowTransactionResult();
}
catch (Exception exception)
{
throw new FlowException("GetTransactionResultByIndex request failed.", exception);
}
}

/// <summary>
/// Gets all the transaction results for a specified block
/// </summary>
/// <param name="blockId"></param>
/// <param name="options"></param>
/// <returns><see cref="IEnumerable{T}" /> of <see cref="FlowTransactionResult"/></returns>
/// <exception cref="FlowException"></exception>
public async Task<IEnumerable<FlowTransactionResult>> GetTransactionResultsByBlockIdAsync(string blockId, CallOptions options = new CallOptions())
{
try
{
var response = await _client.GetTransactionResultsByBlockIDAsync(
new GetTransactionsByBlockIDRequest
{
BlockId = blockId.HexToByteString()
}, options).ConfigureAwait(false);

return response.ToFlowTransactionsResult();
}
catch (Exception exception)
{
throw new FlowException("GetTransactionResultsByBlockId request failed.", exception);
}
}

/// <summary>
/// Gets all the transactions for a specified block
/// </summary>
/// <param name="blockId"></param>
/// <param name="options"></param>
/// <returns></returns>
/// <exception cref="FlowException"></exception>
public async Task<IEnumerable<FlowTransaction>> GetTransactionsByBlockIdAsync(string blockId, CallOptions options = new CallOptions())
{
try
{
var response = await _client.GetTransactionsByBlockIDAsync(
new GetTransactionsByBlockIDRequest
{
BlockId = blockId.HexToByteString(),
}, options).ConfigureAwait(false);

return response.ToFlowTransactions();
}
catch (Exception exception)
{
throw new FlowException("GetTransactionsByBlockId request failed.", exception);
}
}
}
}
80 changes: 76 additions & 4 deletions src/Flow.Net.Sdk.Client.Grpc/FlowGrpcConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ public static FlowCollection ToFlowCollection(this CollectionResponse collection
};
}

public static IEnumerable<FlowTransactionResult> ToFlowTransactionsResult(this TransactionResultsResponse transactionResultsResponse)
{
var result = new List<FlowTransactionResult>();

foreach(var item in transactionResultsResponse.TransactionResults)
result.Add(item.ToFlowTransactionResult());

return result;
}

public static FlowTransactionResult ToFlowTransactionResult(this TransactionResultResponse transactionResultResponse)
{
var events = transactionResultResponse.Events.Select(@event => @event.ToFlowEvent()).ToList();
Expand All @@ -81,7 +91,10 @@ public static FlowTransactionResult ToFlowTransactionResult(this TransactionResu
ErrorMessage = transactionResultResponse.ErrorMessage,
Status = (TransactionStatus)Enum.Parse(typeof(TransactionStatus), transactionResultResponse.Status.ToString()),
StatusCode = transactionResultResponse.StatusCode,
Events = events
Events = events,
BlockHeight = transactionResultResponse.BlockHeight,
CollectionId = transactionResultResponse.CollectionId.ByteStringToHex(),
TransactionId = transactionResultResponse.TransactionId.ByteStringToHex(),
};
}

Expand Down Expand Up @@ -141,7 +154,8 @@ public static FlowBlockHeader ToFlowBlockHeader(this BlockHeaderResponse blockHe
Height = blockHeaderResponse.Block.Height,
Id = blockHeaderResponse.Block.Id.ByteStringToHex(),
ParentId = blockHeaderResponse.Block.ParentId.ByteStringToHex(),
Timestamp = blockHeaderResponse.Block.Timestamp.ToDateTimeOffset()
Timestamp = blockHeaderResponse.Block.Timestamp.ToDateTimeOffset(),
ParentVoterSignature = blockHeaderResponse.Block.ParentVoterIndices.ToArray()
};
}

Expand All @@ -164,7 +178,9 @@ public static FlowBlock ToFlowBlock(this BlockResponse blockResponse)
blockCollectionGuarantees.Add(
new FlowCollectionGuarantee
{
CollectionId = collectionGuarantee.CollectionId.ByteStringToHex()
CollectionId = collectionGuarantee.CollectionId.ByteStringToHex(),
Signature = collectionGuarantee.Signature.ToByteArray(),
SignerIds = collectionGuarantee.SignerIds.Select(s => s.ByteStringToString())
});
}

Expand All @@ -175,7 +191,7 @@ public static FlowBlock ToFlowBlock(this BlockResponse blockResponse)
Height = blockResponse.Block.Height,
Id = blockResponse.Block.Id.ByteStringToHex(),
ParentId = blockResponse.Block.ParentId.ByteStringToHex(),
Timestamp = blockResponse.Block.Timestamp.ToDateTimeOffset(),
Timestamp = blockResponse.Block.Timestamp.ToDateTimeOffset()
},
Payload = new FlowBlockPayload
{
Expand Down Expand Up @@ -317,6 +333,52 @@ public static Protos.entities.Transaction FromFlowTransaction(this FlowTransacti
return tx;
}

public static IEnumerable<FlowTransaction> ToFlowTransactions(this TransactionsResponse transactions)
{
var result = new List<FlowTransaction>();

foreach(var transaction in transactions.Transactions)
result.Add(transaction.ToFlowTransaction());

return result;
}

public static FlowTransaction ToFlowTransaction(this Protos.entities.Transaction transaction)
{
var tx = new FlowTransaction
{
Script = transaction.Script.ByteStringToString(),
Payer = new FlowAddress(transaction.Payer.ByteStringToHex()),
GasLimit = transaction.GasLimit,
ReferenceBlockId = transaction.ReferenceBlockId.ByteStringToHex(),
ProposalKey = transaction.ProposalKey.ToFlowProposalKey()
};

foreach(var arg in transaction.Arguments)
tx.Arguments.Add(CadenceExtensions.Decode(arg.ByteStringToString()));

foreach (var authorizer in transaction.Authorizers)
tx.Authorizers.Add(new FlowAddress(authorizer.ByteStringToHex()));

foreach(var payloadSignature in transaction.PayloadSignatures)
tx.PayloadSignatures.Add(payloadSignature.ToFlowSignature());

foreach(var envelopeSignature in transaction.EnvelopeSignatures)
tx.EnvelopeSignatures.Add(envelopeSignature.ToFlowSignature());

return tx;
}

private static FlowProposalKey ToFlowProposalKey(this Protos.entities.Transaction.Types.ProposalKey proposalKey)
{
return new FlowProposalKey
{
Address = new FlowAddress(proposalKey.Address.ByteStringToHex()),
KeyId = proposalKey.KeyId,
SequenceNumber = proposalKey.SequenceNumber
};
}

private static Protos.entities.Transaction.Types.ProposalKey FromFlowProposalKey(this FlowProposalKey flowProposalKey)
{
return new Protos.entities.Transaction.Types.ProposalKey
Expand All @@ -336,5 +398,15 @@ private static Protos.entities.Transaction.Types.Signature FromFlowSignature(thi
Signature_ = flowSignature.Signature.BytesToByteString()
};
}

private static FlowSignature ToFlowSignature(this Protos.entities.Transaction.Types.Signature signature)
{
return new FlowSignature
{
Address = new FlowAddress(signature.Address.ByteStringToHex()),
KeyId = signature.KeyId,
Signature = signature.ToByteArray()
};
}
}
}
36 changes: 35 additions & 1 deletion src/Flow.Net.Sdk.Client.Grpc/Protos/access/access.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ service AccessAPI {
// GetTransactionResult gets the result of a transaction.
rpc GetTransactionResult(GetTransactionRequest)
returns (TransactionResultResponse);
// GetTransactionResultByIndex gets the result of a transaction at a specified
// block and index
rpc GetTransactionResultByIndex(GetTransactionByIndexRequest)
returns (TransactionResultResponse);
// GetTransactionResultsByBlockID gets all the transaction results for a
// specified block
rpc GetTransactionResultsByBlockID(GetTransactionsByBlockIDRequest)
returns (TransactionResultsResponse);
// GetTransactionsByBlockID gets all the transactions for a specified block
rpc GetTransactionsByBlockID(GetTransactionsByBlockIDRequest)
returns (TransactionsResponse);

// Accounts

Expand Down Expand Up @@ -145,14 +156,17 @@ message BlockHeaderResponse {

message GetLatestBlockRequest {
bool is_sealed = 1;
bool full_block_response = 2;
}

message GetBlockByIDRequest {
bytes id = 1;
bool full_block_response = 2;
}

message GetBlockByHeightRequest {
uint64 height = 1;
bool full_block_response = 2;
}

message BlockResponse {
Expand Down Expand Up @@ -183,6 +197,23 @@ message GetTransactionRequest {
bytes id = 1;
}

message GetTransactionByIndexRequest {
bytes block_id = 1;
uint32 index = 2;
}

message GetTransactionsByBlockIDRequest {
bytes block_id = 1;
}

message TransactionResultsResponse {
repeated TransactionResultResponse transaction_results = 1;
}

message TransactionsResponse {
repeated entities.Transaction transactions = 1;
}

message TransactionResponse {
entities.Transaction transaction = 1;
}
Expand All @@ -193,6 +224,9 @@ message TransactionResultResponse {
string error_message = 3;
repeated entities.Event events = 4;
bytes block_id = 5;
bytes transaction_id = 6;
bytes collection_id = 7;
uint64 block_height = 8;
}

// Accounts
Expand Down Expand Up @@ -288,4 +322,4 @@ message GetExecutionResultForBlockIDRequest {

message ExecutionResultForBlockIDResponse {
entities.ExecutionResult execution_result = 1;
}
}
Loading

0 comments on commit 452c00b

Please sign in to comment.