diff --git a/access/grpc/client.go b/access/grpc/client.go index 73c174f0f..c9d308dfb 100644 --- a/access/grpc/client.go +++ b/access/grpc/client.go @@ -239,11 +239,11 @@ func (c *Client) GetAccountKeyAtBlockHeight(ctx context.Context, address flow.Ad return c.grpc.GetAccountKeyAtBlockHeight(ctx, address, keyIndex, height) } -func (c *Client) GetAccountKeysAtLatestBlock(ctx context.Context, address flow.Address) ([]flow.AccountKey, error) { +func (c *Client) GetAccountKeysAtLatestBlock(ctx context.Context, address flow.Address) ([]*flow.AccountKey, error) { return c.grpc.GetAccountKeysAtLatestBlock(ctx, address) } -func (c *Client) GetAccountKeysAtBlockHeight(ctx context.Context, address flow.Address, height uint64) ([]flow.AccountKey, error) { +func (c *Client) GetAccountKeysAtBlockHeight(ctx context.Context, address flow.Address, height uint64) ([]*flow.AccountKey, error) { return c.grpc.GetAccountKeysAtBlockHeight(ctx, address, height) } diff --git a/access/grpc/convert/convert.go b/access/grpc/convert/convert.go index b93003231..5c2ce0ea8 100644 --- a/access/grpc/convert/convert.go +++ b/access/grpc/convert/convert.go @@ -150,8 +150,8 @@ func MessageToAccountKey(m *entities.AccountKey) (*flow.AccountKey, error) { }, nil } -func MessageToAccountKeys(m []*entities.AccountKey) ([]flow.AccountKey, error) { - var accountKeys []flow.AccountKey +func MessageToAccountKeys(m []*entities.AccountKey) ([]*flow.AccountKey, error) { + var accountKeys []*flow.AccountKey for _, entity := range m { accountKey, err := MessageToAccountKey(entity) @@ -159,7 +159,7 @@ func MessageToAccountKeys(m []*entities.AccountKey) ([]flow.AccountKey, error) { return nil, err } - accountKeys = append(accountKeys, *accountKey) + accountKeys = append(accountKeys, accountKey) } return accountKeys, nil @@ -347,12 +347,16 @@ func QuorumCertificateToMessage(qc flow.QuorumCertificate) (*entities.QuorumCert }, nil } -func MessageToBlockDigest(m *access.SubscribeBlockDigestsResponse) flow.BlockDigest { +func MessageToBlockDigest(m *access.SubscribeBlockDigestsResponse) (flow.BlockDigest, error) { + if m == nil { + return flow.BlockDigest{}, ErrEmptyMessage + } + return flow.BlockDigest{ BlockID: flow.BytesToID(m.GetBlockId()), Height: m.GetBlockHeight(), Timestamp: m.GetBlockTimestamp().AsTime(), - } + }, nil } func BlockDigestToMessage(blockDigest flow.BlockDigest) *access.SubscribeBlockDigestsResponse { diff --git a/access/grpc/grpc.go b/access/grpc/grpc.go index c2f668908..7e9e9138d 100644 --- a/access/grpc/grpc.go +++ b/access/grpc/grpc.go @@ -26,6 +26,7 @@ import ( "errors" "fmt" "io" + "reflect" "github.com/onflow/flow/protobuf/go/flow/entities" "google.golang.org/grpc" @@ -703,7 +704,7 @@ func (c *BaseClient) GetAccountKeyAtBlockHeight( func (c *BaseClient) GetAccountKeysAtLatestBlock( ctx context.Context, address flow.Address, -) ([]flow.AccountKey, error) { +) ([]*flow.AccountKey, error) { request := &access.GetAccountKeysAtLatestBlockRequest{ Address: address.Bytes(), } @@ -725,7 +726,7 @@ func (c *BaseClient) GetAccountKeysAtBlockHeight( ctx context.Context, address flow.Address, height uint64, -) ([]flow.AccountKey, error) { +) ([]*flow.AccountKey, error) { request := &access.GetAccountKeysAtBlockHeightRequest{ Address: address.Bytes(), BlockHeight: height, @@ -1188,16 +1189,11 @@ func (c *BaseClient) SubscribeBlocksFromStartBlockID( return nil, nil, newRPCError(err) } - blocksChan := make(chan flow.Block) - errChan := make(chan error) - - go func() { - defer close(blocksChan) - defer close(errChan) - receiveBlocksFromClient(ctx, subscribeClient, blocksChan, errChan) - }() + convertBlockResponse := func(response *access.SubscribeBlocksResponse) (flow.Block, error) { + return convert.MessageToBlock(response.GetBlock()) + } - return blocksChan, errChan, nil + return subscribe(ctx, subscribeClient.Recv, convertBlockResponse) } func (c *BaseClient) SubscribeBlocksFromStartHeight( @@ -1221,16 +1217,11 @@ func (c *BaseClient) SubscribeBlocksFromStartHeight( return nil, nil, newRPCError(err) } - blocksChan := make(chan flow.Block) - errChan := make(chan error) - - go func() { - defer close(blocksChan) - defer close(errChan) - receiveBlocksFromClient(ctx, subscribeClient, blocksChan, errChan) - }() + convertBlockResponse := func(response *access.SubscribeBlocksResponse) (flow.Block, error) { + return convert.MessageToBlock(response.GetBlock()) + } - return blocksChan, errChan, nil + return subscribe(ctx, subscribeClient.Recv, convertBlockResponse) } func (c *BaseClient) SubscribeBlocksFromLatest( @@ -1252,16 +1243,11 @@ func (c *BaseClient) SubscribeBlocksFromLatest( return nil, nil, newRPCError(err) } - blocksChan := make(chan flow.Block) - errChan := make(chan error) - - go func() { - defer close(blocksChan) - defer close(errChan) - receiveBlocksFromClient(ctx, subscribeClient, blocksChan, errChan) - }() + convertBlockResponse := func(response *access.SubscribeBlocksResponse) (flow.Block, error) { + return convert.MessageToBlock(response.GetBlock()) + } - return blocksChan, errChan, nil + return subscribe(ctx, subscribeClient.Recv, convertBlockResponse) } func (c *BaseClient) SendAndSubscribeTransactionStatuses( @@ -1301,7 +1287,6 @@ func (c *BaseClient) SendAndSubscribeTransactionStatuses( messageIndex := uint64(0) for { - // Receive the next txResult response txResultsResponse, err := subscribeClient.Recv() if err != nil { if err == io.EOF { @@ -1336,48 +1321,6 @@ func (c *BaseClient) SendAndSubscribeTransactionStatuses( return txStatusChan, errChan, nil } -func receiveBlocksFromClient[Client interface { - Recv() (*access.SubscribeBlocksResponse, error) -}]( - ctx context.Context, - client Client, - blocksChan chan<- flow.Block, - errChan chan<- error, -) { - sendErr := func(err error) { - select { - case <-ctx.Done(): - case errChan <- err: - } - } - - for { - // Receive the next block response - blockResponse, err := client.Recv() - if err != nil { - if err == io.EOF { - // End of stream, return gracefully - return - } - - sendErr(fmt.Errorf("error receiving block: %w", err)) - return - } - - block, err := convert.MessageToBlock(blockResponse.GetBlock()) - if err != nil { - sendErr(fmt.Errorf("error converting message to block: %w", err)) - return - } - - select { - case <-ctx.Done(): - return - case blocksChan <- block: - } - } -} - func (c *BaseClient) SubscribeBlockHeadersFromStartBlockID( ctx context.Context, startBlockID flow.Identifier, @@ -1399,16 +1342,11 @@ func (c *BaseClient) SubscribeBlockHeadersFromStartBlockID( return nil, nil, newRPCError(err) } - blockHeaderChan := make(chan flow.BlockHeader) - errChan := make(chan error) - - go func() { - defer close(blockHeaderChan) - defer close(errChan) - receiveBlockHeadersFromClient(ctx, subscribeClient, blockHeaderChan, errChan) - }() + convertBlockHeaderResponse := func(response *access.SubscribeBlockHeadersResponse) (flow.BlockHeader, error) { + return convert.MessageToBlockHeader(response.GetHeader()) + } - return blockHeaderChan, errChan, nil + return subscribe(ctx, subscribeClient.Recv, convertBlockHeaderResponse) } func (c *BaseClient) SubscribeBlockHeadersFromStartHeight( @@ -1432,16 +1370,11 @@ func (c *BaseClient) SubscribeBlockHeadersFromStartHeight( return nil, nil, newRPCError(err) } - blockHeaderChan := make(chan flow.BlockHeader) - errChan := make(chan error) - - go func() { - defer close(blockHeaderChan) - defer close(errChan) - receiveBlockHeadersFromClient(ctx, subscribeClient, blockHeaderChan, errChan) - }() + convertBlockHeaderResponse := func(response *access.SubscribeBlockHeadersResponse) (flow.BlockHeader, error) { + return convert.MessageToBlockHeader(response.GetHeader()) + } - return blockHeaderChan, errChan, nil + return subscribe(ctx, subscribeClient.Recv, convertBlockHeaderResponse) } func (c *BaseClient) SubscribeBlockHeadersFromLatest( @@ -1463,58 +1396,11 @@ func (c *BaseClient) SubscribeBlockHeadersFromLatest( return nil, nil, newRPCError(err) } - blockHeaderChan := make(chan flow.BlockHeader) - errChan := make(chan error) - - go func() { - defer close(blockHeaderChan) - defer close(errChan) - receiveBlockHeadersFromClient(ctx, subscribeClient, blockHeaderChan, errChan) - }() - - return blockHeaderChan, errChan, nil -} - -func receiveBlockHeadersFromClient[Client interface { - Recv() (*access.SubscribeBlockHeadersResponse, error) -}]( - ctx context.Context, - client Client, - blockHeadersChan chan<- flow.BlockHeader, - errChan chan<- error, -) { - sendErr := func(err error) { - select { - case <-ctx.Done(): - case errChan <- err: - } + convertBlockHeaderResponse := func(response *access.SubscribeBlockHeadersResponse) (flow.BlockHeader, error) { + return convert.MessageToBlockHeader(response.GetHeader()) } - for { - // Receive the next blockHeader response - blockHeaderResponse, err := client.Recv() - if err != nil { - if err == io.EOF { - // End of stream, return gracefully - return - } - - sendErr(fmt.Errorf("error receiving blockHeader: %w", err)) - return - } - - blockHeader, err := convert.MessageToBlockHeader(blockHeaderResponse.GetHeader()) - if err != nil { - sendErr(fmt.Errorf("error converting message to block header: %w", err)) - return - } - - select { - case <-ctx.Done(): - return - case blockHeadersChan <- blockHeader: - } - } + return subscribe(ctx, subscribeClient.Recv, convertBlockHeaderResponse) } func (c *BaseClient) SubscribeAccountStatusesFromStartHeight( @@ -1537,16 +1423,11 @@ func (c *BaseClient) SubscribeAccountStatusesFromStartHeight( return nil, nil, newRPCError(err) } - accountStatutesChan := make(chan flow.AccountStatus) - errChan := make(chan error) - - go func() { - defer close(accountStatutesChan) - defer close(errChan) - receiveAccountStatusesFromStream(ctx, subscribeClient, accountStatutesChan, errChan) - }() + convertAccountStatusResponse := func(response *executiondata.SubscribeAccountStatusesResponse) (flow.AccountStatus, error) { + return convert.MessageToAccountStatus(response) + } - return accountStatutesChan, errChan, nil + return subscribeContinuouslyIndexed(ctx, subscribeClient.Recv, convertAccountStatusResponse) } func (c *BaseClient) SubscribeAccountStatusesFromStartBlockID( @@ -1569,16 +1450,11 @@ func (c *BaseClient) SubscribeAccountStatusesFromStartBlockID( return nil, nil, newRPCError(err) } - accountStatutesChan := make(chan flow.AccountStatus) - errChan := make(chan error) - - go func() { - defer close(accountStatutesChan) - defer close(errChan) - receiveAccountStatusesFromStream(ctx, subscribeClient, accountStatutesChan, errChan) - }() + convertAccountStatusResponse := func(response *executiondata.SubscribeAccountStatusesResponse) (flow.AccountStatus, error) { + return convert.MessageToAccountStatus(response) + } - return accountStatutesChan, errChan, nil + return subscribeContinuouslyIndexed(ctx, subscribeClient.Recv, convertAccountStatusResponse) } func (c *BaseClient) SubscribeAccountStatusesFromLatestBlock( @@ -1599,64 +1475,11 @@ func (c *BaseClient) SubscribeAccountStatusesFromLatestBlock( return nil, nil, newRPCError(err) } - accountStatutesChan := make(chan flow.AccountStatus) - errChan := make(chan error) - - go func() { - defer close(accountStatutesChan) - defer close(errChan) - receiveAccountStatusesFromStream(ctx, subscribeClient, accountStatutesChan, errChan) - }() - - return accountStatutesChan, errChan, nil -} - -func receiveAccountStatusesFromStream[Stream interface { - Recv() (*executiondata.SubscribeAccountStatusesResponse, error) -}]( - ctx context.Context, - stream Stream, - accountStatutesChan chan<- flow.AccountStatus, - errChan chan<- error, -) { - sendErr := func(err error) { - select { - case <-ctx.Done(): - case errChan <- err: - } + convertAccountStatusResponse := func(response *executiondata.SubscribeAccountStatusesResponse) (flow.AccountStatus, error) { + return convert.MessageToAccountStatus(response) } - var nextExpectedMsgIndex uint64 - for { - accountStatusResponse, err := stream.Recv() - if err != nil { - if err == io.EOF { - // End of stream, return gracefully - return - } - - sendErr(fmt.Errorf("error receiving account status: %w", err)) - return - } - - accountStatus, err := convert.MessageToAccountStatus(accountStatusResponse) - if err != nil { - sendErr(fmt.Errorf("error converting message to account status: %w", err)) - return - } - - if accountStatus.MessageIndex != nextExpectedMsgIndex { - sendErr(fmt.Errorf("message received out of order")) - return - } - nextExpectedMsgIndex = accountStatus.MessageIndex + 1 - - select { - case <-ctx.Done(): - return - case accountStatutesChan <- accountStatus: - } - } + return subscribeContinuouslyIndexed(ctx, subscribeClient.Recv, convertAccountStatusResponse) } func (c *BaseClient) SubscribeBlockDigestsFromStartBlockID( @@ -1680,16 +1503,11 @@ func (c *BaseClient) SubscribeBlockDigestsFromStartBlockID( return nil, nil, newRPCError(err) } - blocksChan := make(chan flow.BlockDigest) - errChan := make(chan error) - - go func() { - defer close(blocksChan) - defer close(errChan) - receiveBlockDigestFromClient(ctx, subscribeClient, blocksChan, errChan) - }() + convertBlockDigestResponse := func(response *access.SubscribeBlockDigestsResponse) (flow.BlockDigest, error) { + return convert.MessageToBlockDigest(response) + } - return blocksChan, errChan, nil + return subscribe(ctx, subscribeClient.Recv, convertBlockDigestResponse) } func (c *BaseClient) SubscribeBlockDigestsFromStartHeight( @@ -1713,16 +1531,11 @@ func (c *BaseClient) SubscribeBlockDigestsFromStartHeight( return nil, nil, newRPCError(err) } - blocksChan := make(chan flow.BlockDigest) - errChan := make(chan error) - - go func() { - defer close(blocksChan) - defer close(errChan) - receiveBlockDigestFromClient(ctx, subscribeClient, blocksChan, errChan) - }() + convertBlockDigestResponse := func(response *access.SubscribeBlockDigestsResponse) (flow.BlockDigest, error) { + return convert.MessageToBlockDigest(response) + } - return blocksChan, errChan, nil + return subscribe(ctx, subscribeClient.Recv, convertBlockDigestResponse) } func (c *BaseClient) SubscribeBlockDigestsFromLatest( @@ -1744,26 +1557,85 @@ func (c *BaseClient) SubscribeBlockDigestsFromLatest( return nil, nil, newRPCError(err) } - blocksChan := make(chan flow.BlockDigest) + convertBlockDigestResponse := func(response *access.SubscribeBlockDigestsResponse) (flow.BlockDigest, error) { + return convert.MessageToBlockDigest(response) + } + + return subscribe(ctx, subscribeClient.Recv, convertBlockDigestResponse) +} + +// subscribe sets up a generic subscription that continuously receives and processes messages +// from a data source. It does not enforce any message ordering or indexing. The function takes +// three parameters: a receive() function for getting the next message, a convertResponse() function +// for transforming the message into the desired response type, and a context for cancellation. +// It returns two channels: one for the converted responses and another for errors. The function +// runs in a separate goroutine and handles errors gracefully, signaling completion when the +// context is canceled or an error occurs. +func subscribe[Response any, ClientResponse any]( + ctx context.Context, + receive func() (*ClientResponse, error), + convertResponse func(*ClientResponse) (Response, error), +) (<-chan Response, <-chan error, error) { + subChan := make(chan Response) errChan := make(chan error) + sendErr := func(err error) { + select { + case <-ctx.Done(): + case errChan <- err: + } + } + go func() { - defer close(blocksChan) + defer close(subChan) defer close(errChan) - receiveBlockDigestFromClient(ctx, subscribeClient, blocksChan, errChan) + + for { + resp, err := receive() + if err != nil { + if err == io.EOF { + return + } + + sendErr(fmt.Errorf("error receiving %s: %w", reflect.TypeOf(resp).Name(), err)) + return + } + + response, err := convertResponse(resp) + if err != nil { + sendErr(fmt.Errorf("error converting %s: %w", reflect.TypeOf(resp).Name(), err)) + return + } + + select { + case <-ctx.Done(): + return + case subChan <- response: + } + } }() - return blocksChan, errChan, nil + return subChan, errChan, nil } -func receiveBlockDigestFromClient[Client interface { - Recv() (*access.SubscribeBlockDigestsResponse, error) -}]( +type IndexedMessage interface { + GetMessageIndex() uint64 +} + +// subscribeContinuouslyIndexed is a specialized version of the subscription function for cases +// where messages contain an index to ensure order. The Response type must implement the +// IndexedMessage interface, providing a GetMessageIndex method. The function checks that each +// received message's index matches the expected sequence, starting from zero and incrementing +// by one. If a message arrives out of order, an error is sent. This function helps clients +// detect any missed messages and ensures consistent message processing. +func subscribeContinuouslyIndexed[Response IndexedMessage, ClientResponse any]( ctx context.Context, - client Client, - blockDigestsChan chan<- flow.BlockDigest, - errChan chan<- error, -) { + receive func() (*ClientResponse, error), + convertResponse func(*ClientResponse) (Response, error), +) (<-chan Response, <-chan error, error) { + subChan := make(chan Response) + errChan := make(chan error) + sendErr := func(err error) { select { case <-ctx.Done(): @@ -1771,25 +1643,42 @@ func receiveBlockDigestFromClient[Client interface { } } - for { - // Receive the next blockDigest response - blockDigestResponse, err := client.Recv() - if err != nil { - if err == io.EOF { - // End of stream, return gracefully + go func() { + defer close(subChan) + defer close(errChan) + + var nextExpectedMessageIndex uint64 + + for { + resp, err := receive() + if err != nil { + if err == io.EOF { + return + } + + sendErr(fmt.Errorf("error receiving %s: %w", reflect.TypeOf(resp).Name(), err)) return } - sendErr(fmt.Errorf("error receiving blockDigest: %w", err)) - return - } + response, err := convertResponse(resp) + if err != nil { + sendErr(fmt.Errorf("error converting %s: %w", reflect.TypeOf(resp).Name(), err)) + return + } - blockDigest := convert.MessageToBlockDigest(blockDigestResponse) + if response.GetMessageIndex() != nextExpectedMessageIndex { + sendErr(fmt.Errorf("message received out of order")) + return + } + nextExpectedMessageIndex += 1 - select { - case <-ctx.Done(): - return - case blockDigestsChan <- blockDigest: + select { + case <-ctx.Done(): + return + case subChan <- response: + } } - } + }() + + return subChan, errChan, nil } diff --git a/access/grpc/grpc_test.go b/access/grpc/grpc_test.go index 30844d9a7..7aa83b6df 100644 --- a/access/grpc/grpc_test.go +++ b/access/grpc/grpc_test.go @@ -1069,7 +1069,7 @@ func TestClient_GetAccountKeysAtLatestBlock(t *testing.T) { keys, err := c.GetAccountKeysAtLatestBlock(ctx, account.Address) require.NoError(t, err) - assert.Equal(t, *account.Keys[index], keys[index]) + assert.Equal(t, *account.Keys[index], *keys[index]) })) t.Run("Not found error", clientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockRPCClient, c *BaseClient) { @@ -1105,7 +1105,7 @@ func TestClient_GetAccountKeysAtBlockHeight(t *testing.T) { keys, err := c.GetAccountKeysAtBlockHeight(ctx, account.Address, height) require.NoError(t, err) - assert.Equal(t, *account.Keys[index], keys[index]) + assert.Equal(t, *account.Keys[index], *keys[index]) })) t.Run("Not found error", clientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockRPCClient, c *BaseClient) { @@ -1734,6 +1734,28 @@ func TestClient_GetExecutionResultByID(t *testing.T) { } func TestClient_SubscribeExecutionData(t *testing.T) { + generateExecutionDataResponse := func(t *testing.T, blockID flow.Identifier, height uint64) *executiondata.SubscribeExecutionDataResponse { + return &executiondata.SubscribeExecutionDataResponse{ + BlockHeight: height, + BlockExecutionData: &entities.BlockExecutionData{ + BlockId: blockID[:], + ChunkExecutionData: []*entities.ChunkExecutionData{}, + }, + BlockTimestamp: timestamppb.Now(), + } + } + + assertSubscribeExecutionDataArgs := func(t *testing.T, expected *executiondata.SubscribeExecutionDataRequest) func(args mock.Arguments) { + return func(args mock.Arguments) { + actual, ok := args.Get(1).(*executiondata.SubscribeExecutionDataRequest) + require.True(t, ok) + + assert.Equal(t, expected.EventEncodingVersion, actual.EventEncodingVersion) + assert.Equal(t, expected.StartBlockHeight, actual.StartBlockHeight) + assert.Equal(t, expected.StartBlockId, actual.StartBlockId) + } + } + ids := test.IdentifierGenerator() t.Run("Happy Path - by height", executionDataClientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockExecutionDataRPCClient, c *BaseClient) { @@ -1746,7 +1768,7 @@ func TestClient_SubscribeExecutionData(t *testing.T) { } ctx, cancel := context.WithCancel(ctx) - stream := &mockExecutionDataStream{ctx: ctx} + stream := &mockClientStream[executiondata.SubscribeExecutionDataResponse]{ctx: ctx} for i := startHeight; i < startHeight+responseCount; i++ { stream.responses = append(stream.responses, generateExecutionDataResponse(t, ids.New(), i)) } @@ -1788,7 +1810,7 @@ func TestClient_SubscribeExecutionData(t *testing.T) { } ctx, cancel := context.WithCancel(ctx) - stream := &mockExecutionDataStream{ctx: ctx} + stream := &mockClientStream[executiondata.SubscribeExecutionDataResponse]{ctx: ctx} for i := startHeight; i < startHeight+responseCount; i++ { stream.responses = append(stream.responses, generateExecutionDataResponse(t, ids.New(), i)) } @@ -1828,7 +1850,7 @@ func TestClient_SubscribeExecutionData(t *testing.T) { EventEncodingVersion: entities.EventEncodingVersion_CCF_V0, } - stream := &mockExecutionDataStream{ + stream := &mockClientStream[executiondata.SubscribeExecutionDataResponse]{ err: status.Error(codes.Internal, "internal error"), } @@ -1841,7 +1863,7 @@ func TestClient_SubscribeExecutionData(t *testing.T) { wg := sync.WaitGroup{} wg.Add(1) - go assertNoEvents(t, eventCh, wg.Done) + go assertNoData(t, eventCh, wg.Done, "events") i := 0 for err := range errCh { @@ -1864,7 +1886,7 @@ func TestClient_SubscribeExecutionData(t *testing.T) { EventEncodingVersion: entities.EventEncodingVersion_CCF_V0, } - stream := &mockExecutionDataStream{ctx: ctx} + stream := &mockClientStream[executiondata.SubscribeExecutionDataResponse]{ctx: ctx} stream.responses = append(stream.responses, &executiondata.SubscribeExecutionDataResponse{ BlockHeight: startHeight, BlockExecutionData: nil, // nil BlockExecutionData should cause an error @@ -1879,7 +1901,7 @@ func TestClient_SubscribeExecutionData(t *testing.T) { wg := sync.WaitGroup{} wg.Add(1) - go assertNoEvents(t, eventCh, wg.Done) + go assertNoData(t, eventCh, wg.Done, "events") i := 0 for err := range errCh { @@ -1907,6 +1929,34 @@ func TestClient_SubscribeEvents(t *testing.T) { return res } + generateEventResponse := func(t *testing.T, blockID flow.Identifier, height uint64, events []flow.Event, encoding flow.EventEncodingVersion) *executiondata.SubscribeEventsResponse { + responseEvents := make([]*entities.Event, 0, len(events)) + for _, e := range events { + eventMsg, err := convert.EventToMessage(e, encoding) + require.NoError(t, err) + responseEvents = append(responseEvents, eventMsg) + } + + return &executiondata.SubscribeEventsResponse{ + BlockHeight: height, + BlockId: blockID[:], + Events: responseEvents, + } + } + + assertSubscribeEventsArgs := func(t *testing.T, expected *executiondata.SubscribeEventsRequest) func(args mock.Arguments) { + return func(args mock.Arguments) { + actual, ok := args.Get(1).(*executiondata.SubscribeEventsRequest) + require.True(t, ok) + + assert.Equal(t, expected.Filter, actual.Filter) + assert.Equal(t, expected.EventEncodingVersion, actual.EventEncodingVersion) + assert.Equal(t, expected.HeartbeatInterval, actual.HeartbeatInterval) + assert.Equal(t, expected.StartBlockHeight, actual.StartBlockHeight) + assert.Equal(t, expected.StartBlockId, actual.StartBlockId) + } + } + t.Run("Happy Path - by height", executionDataClientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockExecutionDataRPCClient, c *BaseClient) { responseCount := uint64(1000) startHeight := uint64(10) @@ -1928,7 +1978,7 @@ func TestClient_SubscribeEvents(t *testing.T) { } ctx, cancel := context.WithCancel(ctx) - stream := &mockEventStream{ctx: ctx} + stream := &mockClientStream[executiondata.SubscribeEventsResponse]{ctx: ctx} for i := startHeight; i < startHeight+responseCount; i++ { stream.responses = append(stream.responses, generateEventResponse(t, ids.New(), i, getEvents(2), flow.EventEncodingVersionCCF)) } @@ -1981,7 +2031,7 @@ func TestClient_SubscribeEvents(t *testing.T) { } ctx, cancel := context.WithCancel(ctx) - stream := &mockEventStream{ctx: ctx} + stream := &mockClientStream[executiondata.SubscribeEventsResponse]{ctx: ctx} for i := startHeight; i < startHeight+responseCount; i++ { stream.responses = append(stream.responses, generateEventResponse(t, ids.New(), i, getEvents(2), flow.EventEncodingVersionCCF)) } @@ -2028,7 +2078,7 @@ func TestClient_SubscribeEvents(t *testing.T) { StartBlockHeight: startHeight, } - stream := &mockEventStream{ + stream := &mockClientStream[executiondata.SubscribeEventsResponse]{ err: status.Error(codes.Internal, "internal error"), } @@ -2041,7 +2091,7 @@ func TestClient_SubscribeEvents(t *testing.T) { wg := sync.WaitGroup{} wg.Add(1) - go assertNoEvents(t, eventCh, wg.Done) + go assertNoData(t, eventCh, wg.Done, "events") i := 0 for err := range errCh { @@ -2071,7 +2121,7 @@ func TestClient_SubscribeEvents(t *testing.T) { StartBlockHeight: startHeight, } - stream := &mockEventStream{ctx: ctx} + stream := &mockClientStream[executiondata.SubscribeEventsResponse]{ctx: ctx} stream.responses = append(stream.responses, generateEventResponse(t, ids.New(), startHeight, getEvents(2), flow.EventEncodingVersionCCF)) // corrupt the event payload @@ -2086,7 +2136,7 @@ func TestClient_SubscribeEvents(t *testing.T) { wg := sync.WaitGroup{} wg.Add(1) - go assertNoEvents(t, eventCh, wg.Done) + go assertNoData(t, eventCh, wg.Done, "events") i := 0 for err := range errCh { @@ -2134,7 +2184,7 @@ func TestClient_SubscribeAccountStatuses(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockAccountStatutesClientStream{ + stream := &mockClientStream[executiondata.SubscribeAccountStatusesResponse]{ ctx: ctx, responses: generateAccountStatusesResponses(responseCount), } @@ -2175,7 +2225,7 @@ func TestClient_SubscribeAccountStatuses(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockAccountStatutesClientStream{ + stream := &mockClientStream[executiondata.SubscribeAccountStatusesResponse]{ ctx: ctx, responses: generateAccountStatusesResponses(responseCount), } @@ -2217,7 +2267,7 @@ func TestClient_SubscribeAccountStatuses(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockAccountStatutesClientStream{ + stream := &mockClientStream[executiondata.SubscribeAccountStatusesResponse]{ ctx: ctx, responses: generateAccountStatusesResponses(responseCount), } @@ -2256,7 +2306,7 @@ func TestClient_SubscribeAccountStatuses(t *testing.T) { t.Run("Stream returns error", executionDataClientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockExecutionDataRPCClient, c *BaseClient) { ctx, cancel := context.WithCancel(ctx) - stream := &mockAccountStatutesClientStream{ + stream := &mockClientStream[executiondata.SubscribeAccountStatusesResponse]{ ctx: ctx, err: status.Error(codes.Internal, "internal error"), } @@ -2270,7 +2320,7 @@ func TestClient_SubscribeAccountStatuses(t *testing.T) { wg := sync.WaitGroup{} wg.Add(1) - go assertNoAccountStatuses(t, accountStatuses, wg.Done) + go assertNoData(t, accountStatuses, wg.Done, "account statuses") errorCount := 0 for e := range errCh { @@ -2295,7 +2345,7 @@ func TestClient_SubscribeAccountStatuses(t *testing.T) { ctx, cancel := context.WithCancel(ctx) defer cancel() - stream := &mockAccountStatutesClientStream{ + stream := &mockClientStream[executiondata.SubscribeAccountStatusesResponse]{ ctx: ctx, err: status.Error(codes.Internal, "message received out of order"), responses: generateUnorderedAccountStatusesResponses(2), @@ -2338,123 +2388,6 @@ func TestClient_SubscribeAccountStatuses(t *testing.T) { })) } -func generateEventResponse(t *testing.T, blockID flow.Identifier, height uint64, events []flow.Event, encoding flow.EventEncodingVersion) *executiondata.SubscribeEventsResponse { - responseEvents := make([]*entities.Event, 0, len(events)) - for _, e := range events { - eventMsg, err := convert.EventToMessage(e, encoding) - require.NoError(t, err) - responseEvents = append(responseEvents, eventMsg) - } - - return &executiondata.SubscribeEventsResponse{ - BlockHeight: height, - BlockId: blockID[:], - Events: responseEvents, - } -} - -func generateExecutionDataResponse(t *testing.T, blockID flow.Identifier, height uint64) *executiondata.SubscribeExecutionDataResponse { - return &executiondata.SubscribeExecutionDataResponse{ - BlockHeight: height, - BlockExecutionData: &entities.BlockExecutionData{ - BlockId: blockID[:], - ChunkExecutionData: []*entities.ChunkExecutionData{}, - }, - BlockTimestamp: timestamppb.Now(), - } -} - -func assertSubscribeEventsArgs(t *testing.T, expected *executiondata.SubscribeEventsRequest) func(args mock.Arguments) { - return func(args mock.Arguments) { - actual, ok := args.Get(1).(*executiondata.SubscribeEventsRequest) - require.True(t, ok) - - assert.Equal(t, expected.Filter, actual.Filter) - assert.Equal(t, expected.EventEncodingVersion, actual.EventEncodingVersion) - assert.Equal(t, expected.HeartbeatInterval, actual.HeartbeatInterval) - assert.Equal(t, expected.StartBlockHeight, actual.StartBlockHeight) - assert.Equal(t, expected.StartBlockId, actual.StartBlockId) - } -} - -func assertSubscribeExecutionDataArgs(t *testing.T, expected *executiondata.SubscribeExecutionDataRequest) func(args mock.Arguments) { - return func(args mock.Arguments) { - actual, ok := args.Get(1).(*executiondata.SubscribeExecutionDataRequest) - require.True(t, ok) - - assert.Equal(t, expected.EventEncodingVersion, actual.EventEncodingVersion) - assert.Equal(t, expected.StartBlockHeight, actual.StartBlockHeight) - assert.Equal(t, expected.StartBlockId, actual.StartBlockId) - } -} - -func assertNoErrors(t *testing.T, errCh <-chan error, done func()) { - defer done() - for err := range errCh { - require.NoError(t, err) - } -} - -func assertNoEvents[T any](t *testing.T, eventCh <-chan T, done func()) { - defer done() - for range eventCh { - t.Fatal("should not receive events") - } -} - -func assertNoAccountStatuses(t *testing.T, accountStatusesChan <-chan flow.AccountStatus, done func()) { - defer done() - for range accountStatusesChan { - require.FailNow(t, "should not receive account statuses") - } -} - -type mockEventStream struct { - grpc.ClientStream - - ctx context.Context - err error - offset int - responses []*executiondata.SubscribeEventsResponse -} - -func (m *mockEventStream) Recv() (*executiondata.SubscribeEventsResponse, error) { - if m.err != nil { - return nil, m.err - } - - if m.offset >= len(m.responses) { - <-m.ctx.Done() - return nil, io.EOF - } - defer func() { m.offset++ }() - - return m.responses[m.offset], nil -} - -type mockExecutionDataStream struct { - grpc.ClientStream - - ctx context.Context - err error - offset int - responses []*executiondata.SubscribeExecutionDataResponse -} - -func (m *mockExecutionDataStream) Recv() (*executiondata.SubscribeExecutionDataResponse, error) { - if m.err != nil { - return nil, m.err - } - - if m.offset >= len(m.responses) { - <-m.ctx.Done() - return nil, io.EOF - } - defer func() { m.offset++ }() - - return m.responses[m.offset], nil -} - func TestClient_SubscribeBlocks(t *testing.T) { blocks := test.BlockGenerator() @@ -2478,7 +2411,7 @@ func TestClient_SubscribeBlocks(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockBlockClientStream[access.SubscribeBlocksResponse]{ + stream := &mockClientStream[access.SubscribeBlocksResponse]{ ctx: ctx, responses: generateBlockResponses(responseCount), } @@ -2509,7 +2442,7 @@ func TestClient_SubscribeBlocks(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockBlockClientStream[access.SubscribeBlocksResponse]{ + stream := &mockClientStream[access.SubscribeBlocksResponse]{ ctx: ctx, responses: generateBlockResponses(responseCount), } @@ -2541,7 +2474,7 @@ func TestClient_SubscribeBlocks(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockBlockClientStream[access.SubscribeBlocksResponse]{ + stream := &mockClientStream[access.SubscribeBlocksResponse]{ ctx: ctx, responses: generateBlockResponses(responseCount), } @@ -2571,7 +2504,7 @@ func TestClient_SubscribeBlocks(t *testing.T) { t.Run("Stream returns error", clientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockRPCClient, c *BaseClient) { ctx, cancel := context.WithCancel(ctx) defer cancel() - stream := &mockBlockClientStream[access.SubscribeBlocksResponse]{ + stream := &mockClientStream[access.SubscribeBlocksResponse]{ ctx: ctx, err: status.Error(codes.Internal, "internal error"), } @@ -2585,7 +2518,7 @@ func TestClient_SubscribeBlocks(t *testing.T) { wg := sync.WaitGroup{} wg.Add(1) - go assertNoBlocks(t, blockCh, wg.Done) + go assertNoData(t, blockCh, wg.Done, "blocks") errorCount := 0 for e := range errCh { @@ -2599,36 +2532,6 @@ func TestClient_SubscribeBlocks(t *testing.T) { })) } -type mockBlockClientStream[SubscribeBlocksResponse any] struct { - grpc.ClientStream - - ctx context.Context - err error - offset int - responses []*SubscribeBlocksResponse -} - -func (s *mockBlockClientStream[SubscribeBlocksResponse]) Recv() (*SubscribeBlocksResponse, error) { - if s.err != nil { - return nil, s.err - } - - if s.offset >= len(s.responses) { - <-s.ctx.Done() - return nil, io.EOF - } - defer func() { s.offset++ }() - - return s.responses[s.offset], nil -} - -func assertNoBlocks[T any](t *testing.T, blocksCh <-chan T, done func()) { - defer done() - for range blocksCh { - require.FailNow(t, "should not receive blocks") - } -} - func TestClient_SendAndSubscribeTransactionStatuses(t *testing.T) { transactions := test.TransactionGenerator() @@ -2656,7 +2559,7 @@ func TestClient_SendAndSubscribeTransactionStatuses(t *testing.T) { tx := transactions.New() ctx, cancel := context.WithCancel(ctx) - stream := &mockTransactionStatusesClientStream{ + stream := &mockClientStream[access.SendAndSubscribeTransactionStatusesResponse]{ ctx: ctx, responses: generateTransactionStatusResponses(responseCount, flow.EventEncodingVersionCCF), } @@ -2691,7 +2594,7 @@ func TestClient_SendAndSubscribeTransactionStatuses(t *testing.T) { tx := transactions.New() ctx, cancel := context.WithCancel(ctx) - stream := &mockTransactionStatusesClientStream{ + stream := &mockClientStream[access.SendAndSubscribeTransactionStatusesResponse]{ ctx: ctx, responses: generateTransactionStatusResponses(responseCount, flow.EventEncodingVersionJSONCDC), } @@ -2722,7 +2625,7 @@ func TestClient_SendAndSubscribeTransactionStatuses(t *testing.T) { t.Run("Stream returns error", clientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockRPCClient, c *BaseClient) { ctx, cancel := context.WithCancel(ctx) - stream := &mockTransactionStatusesClientStream{ + stream := &mockClientStream[access.SendAndSubscribeTransactionStatusesResponse]{ ctx: ctx, err: status.Error(codes.Internal, "internal error"), } @@ -2736,7 +2639,7 @@ func TestClient_SendAndSubscribeTransactionStatuses(t *testing.T) { wg := sync.WaitGroup{} wg.Add(1) - go assertNoTxResults(t, txResultChan, wg.Done) + go assertNoData(t, txResultChan, wg.Done, "transaction statutes") errorCount := 0 for e := range errCh { @@ -2753,36 +2656,6 @@ func TestClient_SendAndSubscribeTransactionStatuses(t *testing.T) { } -type mockTransactionStatusesClientStream struct { - grpc.ClientStream - - ctx context.Context - err error - offset int - responses []*access.SendAndSubscribeTransactionStatusesResponse -} - -func (m *mockTransactionStatusesClientStream) Recv() (*access.SendAndSubscribeTransactionStatusesResponse, error) { - if m.err != nil { - return nil, m.err - } - - if m.offset >= len(m.responses) { - <-m.ctx.Done() - return nil, io.EOF - } - defer func() { m.offset++ }() - - return m.responses[m.offset], nil -} - -func assertNoTxResults[TxStatus any](t *testing.T, txResultChan <-chan TxStatus, done func()) { - defer done() - for range txResultChan { - require.FailNow(t, "should not receive txStatus") - } -} - func TestClient_SubscribeBlockHeaders(t *testing.T) { blockHeaders := test.BlockHeaderGenerator() @@ -2806,7 +2679,7 @@ func TestClient_SubscribeBlockHeaders(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockBlockHeaderClientStream[access.SubscribeBlockHeadersResponse]{ + stream := &mockClientStream[access.SubscribeBlockHeadersResponse]{ ctx: ctx, responses: generateBlockHeaderResponses(responseCount), } @@ -2837,7 +2710,7 @@ func TestClient_SubscribeBlockHeaders(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockBlockHeaderClientStream[access.SubscribeBlockHeadersResponse]{ + stream := &mockClientStream[access.SubscribeBlockHeadersResponse]{ ctx: ctx, responses: generateBlockHeaderResponses(responseCount), } @@ -2869,7 +2742,7 @@ func TestClient_SubscribeBlockHeaders(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockBlockHeaderClientStream[access.SubscribeBlockHeadersResponse]{ + stream := &mockClientStream[access.SubscribeBlockHeadersResponse]{ ctx: ctx, responses: generateBlockHeaderResponses(responseCount), } @@ -2898,7 +2771,7 @@ func TestClient_SubscribeBlockHeaders(t *testing.T) { t.Run("Stream returns error", clientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockRPCClient, c *BaseClient) { ctx, cancel := context.WithCancel(ctx) - stream := &mockBlockHeaderClientStream[access.SubscribeBlockHeadersResponse]{ + stream := &mockClientStream[access.SubscribeBlockHeadersResponse]{ ctx: ctx, err: status.Error(codes.Internal, "internal error"), } @@ -2912,7 +2785,7 @@ func TestClient_SubscribeBlockHeaders(t *testing.T) { wg := sync.WaitGroup{} wg.Add(1) - go assertNoBlockHeaders(t, blockHeadersCh, wg.Done) + go assertNoData(t, blockHeadersCh, wg.Done, "block headers") errorCount := 0 for e := range errCh { @@ -2928,36 +2801,6 @@ func TestClient_SubscribeBlockHeaders(t *testing.T) { })) } -type mockBlockHeaderClientStream[SubscribeBlockHeadersResponse any] struct { - grpc.ClientStream - - ctx context.Context - err error - offset int - responses []*SubscribeBlockHeadersResponse -} - -func (s *mockBlockHeaderClientStream[SubscribeBlockHeadersResponse]) Recv() (*SubscribeBlockHeadersResponse, error) { - if s.err != nil { - return nil, s.err - } - - if s.offset >= len(s.responses) { - <-s.ctx.Done() - return nil, io.EOF - } - defer func() { s.offset++ }() - - return s.responses[s.offset], nil -} - -func assertNoBlockHeaders[BlockHeader any](t *testing.T, blockHeadersChan <-chan BlockHeader, done func()) { - defer done() - for range blockHeadersChan { - require.FailNow(t, "should not receive block headers") - } -} - func TestClient_SubscribeBlockDigest(t *testing.T) { blockHeaders := test.BlockHeaderGenerator() @@ -2984,7 +2827,7 @@ func TestClient_SubscribeBlockDigest(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockBlockDigestClientStream[access.SubscribeBlockDigestsResponse]{ + stream := &mockClientStream[access.SubscribeBlockDigestsResponse]{ ctx: ctx, responses: generateBlockDigestResponses(responseCount), } @@ -3002,7 +2845,8 @@ func TestClient_SubscribeBlockDigest(t *testing.T) { for i := uint64(0); i < responseCount; i++ { actualDigest := <-blockDigestsCh - expectedDigest := convert.MessageToBlockDigest(stream.responses[i]) + expectedDigest, err := convert.MessageToBlockDigest(stream.responses[i]) + require.NoError(t, err) require.Equal(t, expectedDigest, actualDigest) } cancel() @@ -3014,7 +2858,7 @@ func TestClient_SubscribeBlockDigest(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockBlockDigestClientStream[access.SubscribeBlockDigestsResponse]{ + stream := &mockClientStream[access.SubscribeBlockDigestsResponse]{ ctx: ctx, responses: generateBlockDigestResponses(responseCount), } @@ -3033,7 +2877,8 @@ func TestClient_SubscribeBlockDigest(t *testing.T) { for i := uint64(0); i < responseCount; i++ { actualDigest := <-blockDigestsCh - expectedDigest := convert.MessageToBlockDigest(stream.responses[i]) + expectedDigest, err := convert.MessageToBlockDigest(stream.responses[i]) + require.NoError(t, err) require.Equal(t, expectedDigest, actualDigest) } cancel() @@ -3045,7 +2890,7 @@ func TestClient_SubscribeBlockDigest(t *testing.T) { responseCount := uint64(100) ctx, cancel := context.WithCancel(ctx) - stream := &mockBlockDigestClientStream[access.SubscribeBlockDigestsResponse]{ + stream := &mockClientStream[access.SubscribeBlockDigestsResponse]{ ctx: ctx, responses: generateBlockDigestResponses(responseCount), } @@ -3063,7 +2908,8 @@ func TestClient_SubscribeBlockDigest(t *testing.T) { for i := uint64(0); i < responseCount; i++ { actualDigest := <-blockDigestsCh - expectedDigest := convert.MessageToBlockDigest(stream.responses[i]) + expectedDigest, err := convert.MessageToBlockDigest(stream.responses[i]) + require.NoError(t, err) require.Equal(t, expectedDigest, actualDigest) } cancel() @@ -3073,7 +2919,7 @@ func TestClient_SubscribeBlockDigest(t *testing.T) { t.Run("Stream returns error", clientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockRPCClient, c *BaseClient) { ctx, cancel := context.WithCancel(ctx) - stream := &mockBlockDigestClientStream[access.SubscribeBlockDigestsResponse]{ + stream := &mockClientStream[access.SubscribeBlockDigestsResponse]{ ctx: ctx, err: status.Error(codes.Internal, "internal error"), } @@ -3087,7 +2933,7 @@ func TestClient_SubscribeBlockDigest(t *testing.T) { wg := sync.WaitGroup{} wg.Add(1) - go assertNoBlockDigests(t, blockDigestsCh, wg.Done) + go assertNoData(t, blockDigestsCh, wg.Done, "block digests") errorCount := 0 for e := range errCh { @@ -3103,55 +2949,39 @@ func TestClient_SubscribeBlockDigest(t *testing.T) { })) } -type mockBlockDigestClientStream[SubscribeBlockDigestsResponse any] struct { - grpc.ClientStream - - ctx context.Context - err error - offset int - responses []*SubscribeBlockDigestsResponse -} - -func (s *mockBlockDigestClientStream[SubscribeBlockDigestsResponse]) Recv() (*SubscribeBlockDigestsResponse, error) { - if s.err != nil { - return nil, s.err - } - - if s.offset >= len(s.responses) { - <-s.ctx.Done() - return nil, io.EOF +func assertNoErrors(t *testing.T, errCh <-chan error, done func()) { + defer done() + for err := range errCh { + require.NoError(t, err) } - defer func() { s.offset++ }() - - return s.responses[s.offset], nil } -func assertNoBlockDigests[BlockDigest any](t *testing.T, blockDigestsChan <-chan BlockDigest, done func()) { +func assertNoData[T any](t *testing.T, dataCh <-chan T, done func(), topicNameForError string) { defer done() - for range blockDigestsChan { - require.FailNow(t, "should not receive block digests") + for range dataCh { + t.Fatalf("should not receive %s", topicNameForError) } } -type mockAccountStatutesClientStream struct { +type mockClientStream[Response any] struct { grpc.ClientStream ctx context.Context err error offset int - responses []*executiondata.SubscribeAccountStatusesResponse + responses []*Response } -func (m *mockAccountStatutesClientStream) Recv() (*executiondata.SubscribeAccountStatusesResponse, error) { - if m.err != nil { - return nil, m.err +func (s *mockClientStream[Response]) Recv() (*Response, error) { + if s.err != nil { + return nil, s.err } - if m.offset >= len(m.responses) { - <-m.ctx.Done() + if s.offset >= len(s.responses) { + <-s.ctx.Done() return nil, io.EOF } - defer func() { m.offset++ }() + defer func() { s.offset++ }() - return m.responses[m.offset], nil + return s.responses[s.offset], nil } diff --git a/access/http/handler.go b/access/http/handler.go index 26c720571..6f5fb1bf8 100644 --- a/access/http/handler.go +++ b/access/http/handler.go @@ -408,7 +408,7 @@ func (h *httpHandler) getExecutionResults( u := h.mustBuildURL("/execution_results", opts...) q := u.Query() - q.Add("block_ids", strings.Join(blockIDs, ",")) + q.Add("block_id", strings.Join(blockIDs, ",")) u.RawQuery = q.Encode() var results []models.ExecutionResult diff --git a/access/http/handler_test.go b/access/http/handler_test.go index e65bdf597..977e09fb3 100644 --- a/access/http/handler_test.go +++ b/access/http/handler_test.go @@ -569,7 +569,7 @@ func TestHandler_GetExecResult(t *testing.T) { u, _ := url.Parse("/execution_results") q := u.Query() - q.Add("block_ids", strings.Join(ids, ",")) + q.Add("block_id", strings.Join(ids, ",")) u.RawQuery = q.Encode() req.SetData(*u, fixture) diff --git a/account.go b/account.go index a2baee8cd..f91e9045b 100644 --- a/account.go +++ b/account.go @@ -166,6 +166,10 @@ type AccountStatus struct { Results []*AccountStatusResult } +func (a AccountStatus) GetMessageIndex() uint64 { + return a.MessageIndex +} + type AccountStatusResult struct { Address Address Events []Event diff --git a/examples/Makefile b/examples/Makefile index 171615660..eb5f4ad52 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,5 +1,5 @@ .PHONY: all -all: get-blocks get-accounts get-events get-collection get-network-parameters get-transactions execute-script send-transaction create-account add-account-key deploy-contract storage-usage transaction-arguments single-party single-party-multisig multi-party multi-party-multisig user-signature user-signature-validate-all user-signature-validate-any http-grpc-clients modify-account +all: get-blocks get-accounts get-events get-collection get-network-parameters get-transactions execute-script send-transactions create-account add-account-key deploy-contract storage-usage transaction-arguments single-party single-party-multisig multi-party multi-party-multisig user-signature user-signature-validate-all user-signature-validate-any http-grpc-clients modify-account get-execution-data .PHONY: create-account create-account: @@ -47,7 +47,7 @@ multi-party-multisig: .PHONY: user-signature user-signature: - go run ./user_signature/main.go + go run ./verify_signature/user_signature/main.go .PHONY: get-blocks get-blocks: @@ -77,8 +77,8 @@ get-transactions: execute-script: go run ./execute_script/main.go -.PHONY: send-transaction -send-transaction: +.PHONY: send-transactions +send-transactions: go run ./send_transactions/main.go .PHONY: user-signature-validate-all @@ -97,6 +97,21 @@ http-grpc-clients: modify-account: go run ./modify_account/main.go +.PHONY: get-execution-data +get-execution-data: + go run ./get_execution_data/main.go + +.PHONY: stream-events +stream-events: + go run ./stream_events/main.go + +.PHONY: stream-events-reconnect +stream-events-reconnect: + go run ./stream_events_reconnect/main.go + +.PHONY: stream-execution-data +stream-execution-data: + go run ./stream_execution_data/main.go .PHONY: stream-blocks stream-blocks: go run ./stream_blocks/main.go diff --git a/examples/deploy_contract/main.go b/examples/deploy_contract/main.go index e55e77d59..5e20ac508 100644 --- a/examples/deploy_contract/main.go +++ b/examples/deploy_contract/main.go @@ -216,7 +216,7 @@ func GenerateMintScript(nftCodeAddr flow.Address) []byte { import GreatToken from 0x%s transaction { - prepare(acct: auth(Storage) &Account) { + prepare(acct: auth(Storage, Capabilities) &Account) { let minter = acct.storage.borrow<&GreatToken.GreatNFTMinter>(from: /storage/GreatNFTMinter)! if let nft <- acct.storage.load<@GreatToken.GreatNFT>(from: /storage/GreatNFT) { destroy nft @@ -236,7 +236,7 @@ func GenerateGetNFTIDScript(nftCodeAddr, userAddr flow.Address) []byte { template := ` import GreatToken from 0x%s - pub fun main(): Int { + access(all) fun main(): Int { let acct = getAccount(0x%s) let nft = acct.capabilities.borrow<&GreatToken.GreatNFT>(/public/GreatNFT)! return nft.id() diff --git a/examples/examples.go b/examples/examples.go index 33074f237..527fbdc85 100644 --- a/examples/examples.go +++ b/examples/examples.go @@ -111,7 +111,7 @@ func RandomTransaction(flowClient access.Client) *flow.Transaction { tx := flow.NewTransaction(). SetPayer(serviceAcctAddr). SetProposalKey(serviceAcctAddr, serviceAcctKey.Index, serviceAcctKey.SequenceNumber). - SetScript([]byte("transaction { prepare(auth: AuthAccount) {} }")). + SetScript([]byte("transaction { prepare(signer: auth(Storage) &Account) {} }")). AddAuthorizer(serviceAcctAddr). SetReferenceBlockID(GetReferenceBlockId(flowClient)) diff --git a/examples/execute_script/main.go b/examples/execute_script/main.go index 162669b62..d4b504719 100644 --- a/examples/execute_script/main.go +++ b/examples/execute_script/main.go @@ -20,6 +20,7 @@ package main import ( "context" + "errors" "fmt" "github.com/onflow/flow-go-sdk/access/http" @@ -41,7 +42,7 @@ func demo() { examples.Handle(err) script := []byte(` - pub fun main(a: Int): Int { + access(all) fun main(a: Int): Int { return a + 10 } `) @@ -52,10 +53,10 @@ func demo() { fmt.Printf("\nValue: %s", value.String()) complexScript := []byte(` - pub struct User { - pub var balance: UFix64 - pub var address: Address - pub var name: String + access(all) struct User { + access(all) var balance: UFix64 + access(all) var address: Address + access(all) var name: String init(name: String, address: Address, balance: UFix64) { self.name = name @@ -64,7 +65,7 @@ func demo() { } } - pub fun main(name: String): User { + access(all) fun main(name: String): User { return User( name: name, address: 0x1, @@ -78,7 +79,7 @@ func demo() { } type User struct { - balance uint64 + balance string address flow.Address name string } @@ -88,15 +89,28 @@ func printComplexScript(value cadence.Value, err error) { fmt.Printf("\nString value: %s", value.String()) s := value.(cadence.Struct) + balanceCdc, ok := s.FieldsMappedByName()["balance"].(cadence.UFix64) + if !ok { + examples.Handle(errors.New("incorrect balance")) + } + addressCdc, ok := s.FieldsMappedByName()["address"].(cadence.Address) + if !ok { + examples.Handle(errors.New("incorrect address")) + } + nameCdc, ok := s.FieldsMappedByName()["name"].(cadence.String) + if !ok { + examples.Handle(errors.New("incorrect name")) + } + u := User{ - balance: s.Fields[0].ToGoValue().(uint64), - address: s.Fields[1].ToGoValue().([flow.AddressLength]byte), - name: s.Fields[2].ToGoValue().(string), + balance: balanceCdc.String(), + address: flow.BytesToAddress(addressCdc.Bytes()), + name: nameCdc.String(), } fmt.Printf("\nName: %s", u.name) - fmt.Printf("\nAddress: %s", u.address.String()) - fmt.Printf("\nBalance: %d", u.balance) + fmt.Printf("\nAddress: 0x%s", u.address.String()) + fmt.Printf("\nBalance: %s", u.balance) } func prepareDemo() { diff --git a/examples/flow.json b/examples/flow.json index c35509238..13f1b9e43 100644 --- a/examples/flow.json +++ b/examples/flow.json @@ -6,11 +6,31 @@ } }, "contracts": { - "FlowServiceAccount": "f8d6e0586b0a20c7", - "FlowFees": "e5a8b7f23e8b548f", - "FlowStorageFees": "f8d6e0586b0a20c7", - "FlowToken": "0ae53cb6e3f42a79", - "FungibleToken": "ee82856bf20e2aa6" + "FlowServiceAccount": { + "aliases": { + "emulator": "f8d6e0586b0a20c7" + } + }, + "FlowFees": { + "aliases": { + "emulator": "e5a8b7f23e8b548f" + } + }, + "FlowStorageFees": { + "aliases": { + "emulator": "f8d6e0586b0a20c7" + } + }, + "FlowToken": { + "aliases": { + "emulator": "0ae53cb6e3f42a79" + } + }, + "FungibleToken": { + "aliases": { + "emulator": "ee82856bf20e2aa6" + } + } }, "networks": { "emulator": "127.0.0.1:3569", diff --git a/examples/get_events/main.go b/examples/get_events/main.go index 2c248ef3d..68e12aeb6 100644 --- a/examples/get_events/main.go +++ b/examples/get_events/main.go @@ -84,10 +84,10 @@ func preapreDemo() (*flow.Account, *flow.Transaction) { // Deploy a contract with an event defined contract := ` - pub contract EventDemo { - pub event Add(x: Int, y: Int, sum: Int) + access(all) contract EventDemo { + access(all) event Add(x: Int, y: Int, sum: Int) - pub fun add(x: Int, y: Int) { + access(all) fun add(x: Int, y: Int) { let sum = x + y emit Add(x: x, y: y, sum: sum) } @@ -105,7 +105,7 @@ func preapreDemo() (*flow.Account, *flow.Transaction) { import EventDemo from 0x%s transaction { - prepare(auth: AuthAccount) {} + prepare(signer: auth(Storage) &Account) {} execute { EventDemo.add(x: 2, y: 3) } diff --git a/examples/get_execution_data/main.go b/examples/get_execution_data/main.go index 315cb462e..313c84cd5 100644 --- a/examples/get_execution_data/main.go +++ b/examples/get_execution_data/main.go @@ -34,11 +34,10 @@ func main() { func demo() { ctx := context.Background() - flowClient, err := grpc.NewClient("access-003.devnet46.nodes.onflow.org:9000") + flowClient, err := grpc.NewClient(grpc.TestnetHost) examples.Handle(err) - // block, err := flowClient.GetLatestBlock(ctx, true) - block, err := flowClient.GetBlockByID(ctx, flow.HexToID("7582cc6e1bb5ca1784e309ca63013e9b7ecf34b74bf7fdb029aa0faa0deb7958err")) + block, err := flowClient.GetLatestBlock(ctx, true) examples.Handle(err) fmt.Printf("Block Height: %d\n", block.Height) fmt.Printf("Block ID: %s\n", block.ID) diff --git a/examples/go.mod b/examples/go.mod index 0108d8023..44d61f9b6 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -7,11 +7,11 @@ toolchain go1.22.4 replace github.com/onflow/flow-go-sdk => ../ require ( - github.com/onflow/cadence v1.2.1 + github.com/onflow/cadence v1.2.2 github.com/onflow/flow-go-sdk v1.2.2 github.com/onflow/flowkit v1.19.0 github.com/spf13/afero v1.11.0 - google.golang.org/grpc v1.67.1 + google.golang.org/grpc v1.64.1 ) require ( @@ -74,6 +74,7 @@ require ( github.com/psiemens/sconfig v0.1.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/cobra v1.8.0 // indirect @@ -96,13 +97,14 @@ require ( go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect - golang.org/x/crypto v0.26.0 // indirect + go.uber.org/goleak v1.3.0 // indirect + golang.org/x/crypto v0.28.0 // indirect golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect diff --git a/examples/go.sum b/examples/go.sum index 547b56b93..52d307729 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -33,8 +33,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg= -github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50 h1:DBmgJDC9dTfkVyGgipamEh2BpGYxScCH1TOF1LL1cXc= +github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50/go.mod h1:5e1+Vvlzido69INQaVO6d87Qn543Xr6nooe9Kz7oBFM= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= @@ -79,8 +79,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= -github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/ethereum/go-ethereum v1.13.10 h1:Ppdil79nN+Vc+mXfge0AuUgmKWuVv4eMqzoIVSdqZek= github.com/ethereum/go-ethereum v1.13.10/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -111,8 +111,8 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= -github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -281,8 +281,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onflow/atree v0.8.0 h1:qg5c6J1gVDNObughpEeWm8oxqhPGdEyGrda121GM4u0= github.com/onflow/atree v0.8.0/go.mod h1:yccR+LR7xc1Jdic0mrjocbHvUD7lnVvg8/Ct1AA5zBo= -github.com/onflow/cadence v1.2.1 h1:hmSsgX3rTsp2E5qTSl1JXINt8qepdRrHTwDSYqN5Nxs= -github.com/onflow/cadence v1.2.1/go.mod h1:fJxxOAp1wnWDfOHT8GOc1ypsU0RR5E3z51AhG8Yf5jg= +github.com/onflow/cadence v1.2.2 h1:LwigF/2lPiXlwX5rFn71KeMpmW5Iu/f/JtsPLLULBCc= +github.com/onflow/cadence v1.2.2/go.mod h1:PYX1xLejqswtDsQzN93x/VpfSKNyjUk6hrkc/mpv7xs= github.com/onflow/crypto v0.25.2 h1:GjHunqVt+vPcdqhxxhAXiMIF3YiLX7gTuTR5O+VG2ns= github.com/onflow/crypto v0.25.2/go.mod h1:fY7eLqUdMKV8EGOw301unP8h7PvLVy8/6gVR++/g0BY= github.com/onflow/flow-core-contracts/lib/go/templates v1.4.0 h1:u2DAG8pk0xFH7TwS70t1gSZ/FtIIZWMSNyiu4SeXBYg= @@ -345,8 +345,8 @@ github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6us github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slok/go-http-metrics v0.10.0 h1:rh0LaYEKza5eaYRGDXujKrOln57nHBi4TtVhmNEpbgM= github.com/slok/go-http-metrics v0.10.0/go.mod h1:lFqdaS4kWMfUKCSukjC47PdCeTk+hXDUVm8kLHRqJ38= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -380,6 +380,7 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -436,8 +437,8 @@ go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v8 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= @@ -449,8 +450,8 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= @@ -474,11 +475,11 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -497,13 +498,14 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -511,8 +513,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= @@ -554,8 +556,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/examples/great-token.cdc b/examples/great-token.cdc index ed17cbce2..0539506e6 100644 --- a/examples/great-token.cdc +++ b/examples/great-token.cdc @@ -1,22 +1,22 @@ -pub contract GreatToken { +access(all) contract GreatToken { - pub resource interface NFT { - pub fun id(): Int { + access(all) resource interface NFT { + access(all) fun id(): Int { post { result > 0 } } } - pub resource GreatNFT: NFT { - priv let _id: Int - priv let _special: Bool + access(all) resource GreatNFT: NFT { + access(self) let _id: Int + access(self) let _special: Bool - pub fun id(): Int { + access(all) fun id(): Int { return self._id } - pub fun isSpecial(): Bool { + access(all) fun isSpecial(): Bool { return self._special } @@ -29,11 +29,11 @@ pub contract GreatToken { } } - pub resource GreatNFTMinter { - pub var nextID: Int - pub let specialMod: Int + access(all) resource GreatNFTMinter { + access(all) var nextID: Int + access(all) let specialMod: Int - pub fun mint(): @GreatNFT { + access(all) fun mint(): @GreatNFT { var isSpecial = self.nextID % self.specialMod == 0 let nft <- create GreatNFT(id: self.nextID, isSpecial: isSpecial) self.nextID = self.nextID + 1 @@ -50,7 +50,7 @@ pub contract GreatToken { } } - pub fun createGreatNFTMinter(firstID: Int, specialMod: Int): @GreatNFTMinter { + access(all) fun createGreatNFTMinter(firstID: Int, specialMod: Int): @GreatNFTMinter { return <-create GreatNFTMinter(firstID: firstID, specialMod: specialMod) } } diff --git a/examples/modify_account/main.go b/examples/modify_account/main.go index 26b672d59..f2d4e5ed7 100644 --- a/examples/modify_account/main.go +++ b/examples/modify_account/main.go @@ -76,7 +76,7 @@ func contractsString(contracts map[string][]byte) string { func ModifyAccountDemo() { ctx := context.Background() - flowClient, err := grpc.NewClient("127.0.0.1:3569") + flowClient, err := grpc.NewClient(grpc.EmulatorHost) examples.Handle(err) serviceAcctAddr, _, _ := examples.ServiceAccount(flowClient) @@ -101,7 +101,7 @@ func ModifyAccountDemo() { serviceAcctAddr, templates.Contract{ Name: "Foo", - Source: "pub contract Foo {}", + Source: "access(all) contract Foo {}", }, ) prepareAndSendTx(ctx, flowClient, *addContractTx) @@ -114,7 +114,7 @@ func ModifyAccountDemo() { serviceAcctAddr, templates.Contract{ Name: "Foo", - Source: "pub contract Foo { pub fun hello() {} }", + Source: "access(all) contract Foo { access(all) fun hello() {} }", }, ) prepareAndSendTx(ctx, flowClient, *updateTx) diff --git a/examples/send_transactions/main.go b/examples/send_transactions/main.go index 9bdcd754b..66249bbc1 100644 --- a/examples/send_transactions/main.go +++ b/examples/send_transactions/main.go @@ -40,14 +40,14 @@ func demo() { tx := flow.NewTransaction(). SetPayer(serviceAcctAddr). SetProposalKey(serviceAcctAddr, serviceAcctKey.Index, serviceAcctKey.SequenceNumber). - SetScript([]byte(`transaction { - - prepare(acc: &Account) {} - - execute { - log("test") - } -}`)). + SetScript([]byte(` + transaction { + prepare(signer: auth(Storage) &Account) {} + execute { + log("test") + } + } + `)). AddAuthorizer(serviceAcctAddr). SetReferenceBlockID(examples.GetReferenceBlockId(flowClient)) diff --git a/examples/storage_usage/main.go b/examples/storage_usage/main.go index 435ad5ab4..e1420c59b 100644 --- a/examples/storage_usage/main.go +++ b/examples/storage_usage/main.go @@ -46,14 +46,14 @@ func StorageUsageDemo() { // A contract that defines a resource with a string so its easier to demonstrate adding resources of different sizes contract := ` - pub contract StorageDemo { - pub resource StorageTestResource { - pub let data: String + access(all) contract StorageDemo { + access(all) resource StorageTestResource { + access(all) let data: String init(data: String) { self.data = data } } - pub fun createStorageTestResource(_ data: String): @StorageTestResource { + access(all) fun createStorageTestResource(_ data: String): @StorageTestResource { return <- create StorageTestResource(data: data) } } @@ -135,9 +135,9 @@ func sendSaveLargeResourceTransaction( transaction { prepare(acct: auth(SaveValue) &Account) { - let storageUsed = acct.storageUsed - - // create resource and save it on the account + let storageUsed = acct.storage.used + + // create resource and save it on the account let bigResource <- StorageDemo.createStorageTestResource("%s") acct.storage.save(<-bigResource, to: /storage/StorageDemo) @@ -146,7 +146,7 @@ func sendSaveLargeResourceTransaction( if (storageUsed == storageUsedAfter) { panic("storage used will change") } - + if (storageUsedAfter > acct.storage.capacity) { // this is where we could deposit more flow to acct to increase its storaga capacity if we wanted to log("Storage used is over capacity. This transaction will fail if storage limits are on on this chain.") diff --git a/examples/stream_events/main.go b/examples/stream_events/main.go index dad8d76fb..037cf441e 100644 --- a/examples/stream_events/main.go +++ b/examples/stream_events/main.go @@ -34,7 +34,7 @@ func main() { func demo() { ctx := context.Background() - flowClient, err := grpc.NewClient("access.testnet.nodes.onflow.org:9000") + flowClient, err := grpc.NewClient(grpc.TestnetHost) examples.Handle(err) header, err := flowClient.GetLatestBlockHeader(ctx, true) diff --git a/examples/stream_execution_data/main.go b/examples/stream_execution_data/main.go index 56d874773..09e5b180e 100644 --- a/examples/stream_execution_data/main.go +++ b/examples/stream_execution_data/main.go @@ -34,7 +34,7 @@ func main() { func demo() { ctx := context.Background() - flowClient, err := grpc.NewClient("access-003.devnet46.nodes.onflow.org:9000") + flowClient, err := grpc.NewClient(grpc.TestnetHost) examples.Handle(err) header, err := flowClient.GetLatestBlockHeader(ctx, true) diff --git a/examples/transaction_signing/multi_party/main.go b/examples/transaction_signing/multi_party/main.go index 6da910554..b1f7b3f58 100644 --- a/examples/transaction_signing/multi_party/main.go +++ b/examples/transaction_signing/multi_party/main.go @@ -68,8 +68,8 @@ func MultiPartySingleSignatureDemo() { tx := flow.NewTransaction(). SetScript([]byte(` - transaction { - prepare(signer: AuthAccount) { log(signer.address) } + transaction { + prepare(signer: auth(Storage) &Account) { log(signer.address) } } `)). SetComputeLimit(100). diff --git a/examples/transaction_signing/multi_party_multisig/main.go b/examples/transaction_signing/multi_party_multisig/main.go index cd48bcd65..6149799a4 100644 --- a/examples/transaction_signing/multi_party_multisig/main.go +++ b/examples/transaction_signing/multi_party_multisig/main.go @@ -88,8 +88,8 @@ func MultiPartyMultiSignatureDemo() { tx := flow.NewTransaction(). SetScript([]byte(` - transaction { - prepare(signer: AuthAccount) { log(signer.address) } + transaction { + prepare(signer: auth(Storage) &Account) { log(signer.address) } } `)). SetComputeLimit(100). diff --git a/examples/transaction_signing/multi_party_two_authorizers/main.go b/examples/transaction_signing/multi_party_two_authorizers/main.go index 7c1a38d4f..22f4a99fd 100644 --- a/examples/transaction_signing/multi_party_two_authorizers/main.go +++ b/examples/transaction_signing/multi_party_two_authorizers/main.go @@ -67,9 +67,9 @@ func MultiPartySingleSignatureDemo() { referenceBlockID := examples.GetReferenceBlockId(flowClient) tx := flow.NewTransaction(). SetScript([]byte(` - transaction { - prepare(signer1: AuthAccount, signer2: AuthAccount) { - log(signer1.address) + transaction { + prepare(signer1: auth(Storage) &Account, signer2: auth(Storage) &Account) { + log(signer1.address) log(signer2.address) } }`)). diff --git a/examples/transaction_signing/single_party/main.go b/examples/transaction_signing/single_party/main.go index f1c130faf..117bb91e8 100644 --- a/examples/transaction_signing/single_party/main.go +++ b/examples/transaction_signing/single_party/main.go @@ -55,8 +55,8 @@ func SinglePartySingleSignatureDemo() { referenceBlockID := examples.GetReferenceBlockId(flowClient) tx := flow.NewTransaction(). SetScript([]byte(` - transaction { - prepare(signer: AuthAccount) { log(signer.address) } + transaction { + prepare(signer: auth(Storage) &Account) { log(signer.address) } } `)). SetComputeLimit(100). diff --git a/examples/transaction_signing/single_party_multisig/main.go b/examples/transaction_signing/single_party_multisig/main.go index 4701bc77b..e70f33126 100644 --- a/examples/transaction_signing/single_party_multisig/main.go +++ b/examples/transaction_signing/single_party_multisig/main.go @@ -65,8 +65,8 @@ func SinglePartyMultiSignatureDemo() { referenceBlockID := examples.GetReferenceBlockId(flowClient) tx := flow.NewTransaction(). SetScript([]byte(` - transaction { - prepare(signer: AuthAccount) { log(signer.address) } + transaction { + prepare(signer: auth(Storage) &Account) { log(signer.address) } } `)). SetComputeLimit(100). diff --git a/examples/verify_events/main.go b/examples/verify_events/main.go index 5421df68e..89c116820 100644 --- a/examples/verify_events/main.go +++ b/examples/verify_events/main.go @@ -40,7 +40,7 @@ func main() { // For users, its possible to get all the events for chunk, calculate and compare the resulting hash func VerifyEventsDemo() { ctx := context.Background() - flowClient, err := http.NewClient(http.EmulatorHost) + flowClient, err := http.NewClient(http.TestnetHost) examples.Handle(err) latestBlockHeader, err := flowClient.GetLatestBlockHeader(ctx, true) diff --git a/examples/verify_signature/user_signature/main.go b/examples/verify_signature/user_signature/main.go index 83eee76fc..a719ae979 100644 --- a/examples/verify_signature/user_signature/main.go +++ b/examples/verify_signature/user_signature/main.go @@ -40,13 +40,14 @@ func main() { var script = []byte(` import Crypto -pub fun main( +access(all) fun main( rawPublicKeys: [String], weights: [UFix64], signatures: [String], toAddress: Address, fromAddress: Address, amount: UFix64, + domainSeparationTag: String, ): Bool { let keyList = Crypto.KeyList() @@ -84,6 +85,7 @@ pub fun main( return keyList.verify( signatureSet: signatureSet, signedData: message, + domainSeparationTag: domainSeparationTag, ) } `) @@ -145,6 +147,8 @@ func UserSignatureDemo() { cadence.String(hex.EncodeToString(signatureBob)), }) + domainSeparationTag := cadence.String(flow.UserDomainTag[:]) + // call the script to verify the signatures on chain value, err := flowClient.ExecuteScriptAtLatestBlock( ctx, @@ -156,6 +160,7 @@ func UserSignatureDemo() { toAddress, fromAddress, amount, + domainSeparationTag, }, ) examples.Handle(err) diff --git a/examples/verify_signature/user_signature_validate_all/main.go b/examples/verify_signature/user_signature_validate_all/main.go index 26185df36..8dd49b9ea 100644 --- a/examples/verify_signature/user_signature_validate_all/main.go +++ b/examples/verify_signature/user_signature_validate_all/main.go @@ -39,14 +39,15 @@ func main() { var script = []byte(` import Crypto -pub fun main( +access(all) fun main( address: Address, signatures: [String], keyIndexes: [Int], message: String, + domainSeparationTag: String, ): Bool { let keyList = Crypto.KeyList() - + let account = getAccount(address) let keys = account.keys @@ -69,9 +70,9 @@ pub fun main( return false } } - + let signatureSet: [Crypto.KeyListSignature] = [] - + var i = 0 for signature in signatures { signatureSet.append( @@ -82,10 +83,11 @@ pub fun main( ) i = i + 1 } - + return keyList.verify( signatureSet: signatureSet, signedData: message.utf8, + domainSeparationTag: domainSeparationTag, ) } `) @@ -136,6 +138,8 @@ func UserSignatureValidateAll() { cadence.NewInt(0), }) + domainSeparationTag := flow.UserDomainTag[:] + // call the script to verify the signatures on chain value, err := flowClient.ExecuteScriptAtLatestBlock( ctx, @@ -145,6 +149,7 @@ func UserSignatureValidateAll() { signatures, signatureIndexes, cadence.String(message), + cadence.String(domainSeparationTag), }, ) examples.Handle(err) diff --git a/examples/verify_signature/user_signature_validate_any/main.go b/examples/verify_signature/user_signature_validate_any/main.go index c0fe2a788..68a22acf2 100644 --- a/examples/verify_signature/user_signature_validate_any/main.go +++ b/examples/verify_signature/user_signature_validate_any/main.go @@ -39,13 +39,14 @@ func main() { var script = []byte(` import Crypto -pub fun main( +access(all) fun main( address: Address, signature: String, - message: String + message: String, + domainSeparationTag: String ): Bool { let keyList = Crypto.KeyList() - + let account = getAccount(address) let keys = account.keys @@ -67,7 +68,7 @@ pub fun main( if pk.verify( signature: signatureBytes, signedData: messageBytes, - domainSeparationTag: "FLOW-V0.0-user", + domainSeparationTag: domainSeparationTag, hashAlgorithm: key.hashAlgorithm ) { // this key is good @@ -115,6 +116,8 @@ func UserSignatureValidateAny() { signatureAlice, err := flow.SignUserMessage(signerAlice, message) examples.Handle(err) + domainSeparationTag := flow.UserDomainTag[:] + // call the script to verify the signature on chain value, err := flowClient.ExecuteScriptAtLatestBlock( ctx, @@ -123,6 +126,7 @@ func UserSignatureValidateAny() { cadence.BytesToAddress(account.Address.Bytes()), cadence.String(hex.EncodeToString(signatureAlice)), cadence.String(message), + cadence.String(domainSeparationTag), }, ) examples.Handle(err) diff --git a/go.mod b/go.mod index 9f4d32511..c1bce6bb4 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/aws/aws-sdk-go-v2 v1.27.0 github.com/aws/aws-sdk-go-v2/config v1.27.15 github.com/aws/aws-sdk-go-v2/service/kms v1.31.0 - github.com/onflow/cadence v1.2.1 + github.com/onflow/cadence v1.2.2 github.com/onflow/crypto v0.25.1 github.com/onflow/flow/protobuf/go/flow v0.4.7 github.com/onflow/go-ethereum v1.13.4 @@ -75,17 +75,18 @@ require ( go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect - golang.org/x/crypto v0.26.0 // indirect + golang.org/x/crypto v0.28.0 // indirect golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect + google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect diff --git a/go.sum b/go.sum index 839da6edf..d13e17be9 100644 --- a/go.sum +++ b/go.sum @@ -84,6 +84,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -92,6 +94,7 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= @@ -128,8 +131,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/onflow/atree v0.8.0 h1:qg5c6J1gVDNObughpEeWm8oxqhPGdEyGrda121GM4u0= github.com/onflow/atree v0.8.0/go.mod h1:yccR+LR7xc1Jdic0mrjocbHvUD7lnVvg8/Ct1AA5zBo= -github.com/onflow/cadence v1.2.1 h1:hmSsgX3rTsp2E5qTSl1JXINt8qepdRrHTwDSYqN5Nxs= -github.com/onflow/cadence v1.2.1/go.mod h1:fJxxOAp1wnWDfOHT8GOc1ypsU0RR5E3z51AhG8Yf5jg= +github.com/onflow/cadence v1.2.2 h1:LwigF/2lPiXlwX5rFn71KeMpmW5Iu/f/JtsPLLULBCc= +github.com/onflow/cadence v1.2.2/go.mod h1:PYX1xLejqswtDsQzN93x/VpfSKNyjUk6hrkc/mpv7xs= github.com/onflow/crypto v0.25.1 h1:0txy2PKPMM873JbpxQNbJmuOJtD56bfs48RQfm0ts5A= github.com/onflow/crypto v0.25.1/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI= github.com/onflow/flow/protobuf/go/flow v0.4.7 h1:iP6DFx4wZ3ETORsyeqzHu7neFT3d1CXF6wdK+AOOjmc= @@ -168,6 +171,7 @@ github.com/turbolent/prettier v0.0.0-20220320183459-661cc755135d h1:5JInRQbk5UBX github.com/turbolent/prettier v0.0.0-20220320183459-661cc755135d/go.mod h1:Nlx5Y115XQvNcIdIy7dZXaNSUpzwBSge4/Ivk93/Yog= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= @@ -194,8 +198,9 @@ go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= @@ -205,6 +210,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -214,30 +220,41 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -245,9 +262,12 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= @@ -258,6 +278,8 @@ google.golang.org/api v0.162.0 h1:Vhs54HkaEpkMBdgGdOT2P6F0csGG/vxDS0hWHJzmmps= google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= @@ -283,6 +305,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=