From 1ed31afd556f16a1a0ec1aa163ea6df0abe17f36 Mon Sep 17 00:00:00 2001 From: Illia Malachyn Date: Thu, 12 Sep 2024 15:12:17 +0300 Subject: [PATCH 1/4] Add GetFullCollectionById endpoint --- access/client.go | 2 +- access/grpc/client.go | 10 +- access/grpc/convert/convert.go | 38 +++- access/grpc/convert/convert_test.go | 6 +- access/grpc/grpc.go | 48 ++++- access/grpc/grpc_test.go | 42 ++++- access/grpc/mocks/RPCClient.go | 210 ++++++++++++++++++++++ access/http/client.go | 2 +- access/http/convert/convert.go | 4 +- access/http/http.go | 2 +- access/http/internal/unittest/fixtures.go | 2 +- access/mocks/Client.go | 8 +- collection.go | 25 ++- examples/get_collection/main.go | 2 +- examples/go.mod | 6 +- examples/go.sum | 3 + go.mod | 2 +- go.sum | 4 +- test/entities.go | 26 ++- 19 files changed, 404 insertions(+), 38 deletions(-) diff --git a/access/client.go b/access/client.go index fe0220675..880714cc5 100644 --- a/access/client.go +++ b/access/client.go @@ -62,7 +62,7 @@ type Client interface { GetBlockByHeight(ctx context.Context, height uint64) (*flow.Block, error) // GetCollection gets a collection by ID. - GetCollection(ctx context.Context, colID flow.Identifier) (*flow.Collection, error) + GetCollection(ctx context.Context, colID flow.Identifier) (*flow.LightCollection, error) // SendTransaction submits a transaction to the network. SendTransaction(ctx context.Context, tx flow.Transaction) error diff --git a/access/grpc/client.go b/access/grpc/client.go index d1c15d903..8db8ffa45 100644 --- a/access/grpc/client.go +++ b/access/grpc/client.go @@ -157,10 +157,18 @@ func (c *Client) GetBlockByHeight(ctx context.Context, height uint64) (*flow.Blo return c.grpc.GetBlockByHeight(ctx, height) } -func (c *Client) GetCollection(ctx context.Context, colID flow.Identifier) (*flow.Collection, error) { +func (c *Client) GetCollection(ctx context.Context, colID flow.Identifier) (*flow.LightCollection, error) { return c.grpc.GetCollection(ctx, colID) } +func (c *Client) GetCollectionByID(ctx context.Context, id flow.Identifier) (*flow.LightCollection, error) { + return c.grpc.GetLightCollectionByID(ctx, id) +} + +func (c *Client) GetFullCollectionByID(ctx context.Context, id flow.Identifier) (*flow.FullCollection, error) { + return c.grpc.GetFullCollectionByID(ctx, id) +} + func (c *Client) SendTransaction(ctx context.Context, tx flow.Transaction) error { return c.grpc.SendTransaction(ctx, tx) } diff --git a/access/grpc/convert/convert.go b/access/grpc/convert/convert.go index e52500a08..a9a693713 100644 --- a/access/grpc/convert/convert.go +++ b/access/grpc/convert/convert.go @@ -241,7 +241,7 @@ func MessageToCadenceValue(m []byte, options []jsoncdc.Option) (cadence.Value, e return v, nil } -func CollectionToMessage(c flow.Collection) *entities.Collection { +func LightCollectionToMessage(c flow.LightCollection) *entities.Collection { transactionIDMessages := make([][]byte, len(c.TransactionIDs)) for i, transactionID := range c.TransactionIDs { transactionIDMessages[i] = transactionID.Bytes() @@ -252,9 +252,24 @@ func CollectionToMessage(c flow.Collection) *entities.Collection { } } -func MessageToCollection(m *entities.Collection) (flow.Collection, error) { +func FullCollectionToTransactionsMessage(tx flow.FullCollection) ([]*entities.Transaction, error) { + var convertedTxs []*entities.Transaction + + for _, tx := range tx.Transactions { + convertedTx, err := TransactionToMessage(*tx) + if err != nil { + return nil, err + } + + convertedTxs = append(convertedTxs, convertedTx) + } + + return convertedTxs, nil +} + +func MessageToLightCollection(m *entities.Collection) (flow.LightCollection, error) { if m == nil { - return flow.Collection{}, ErrEmptyMessage + return flow.LightCollection{}, ErrEmptyMessage } transactionIDMessages := m.GetTransactionIds() @@ -264,11 +279,26 @@ func MessageToCollection(m *entities.Collection) (flow.Collection, error) { transactionIDs[i] = flow.HashToID(transactionIDMsg) } - return flow.Collection{ + return flow.LightCollection{ TransactionIDs: transactionIDs, }, nil } +func MessageToFullCollection(m []*entities.Transaction) (flow.FullCollection, error) { + var collection flow.FullCollection + + for _, tx := range m { + convertedTx, err := MessageToTransaction(tx) + if err != nil { + return flow.FullCollection{}, err + } + + collection.Transactions = append(collection.Transactions, &convertedTx) + } + + return collection, nil +} + func CollectionGuaranteeToMessage(g flow.CollectionGuarantee) *entities.CollectionGuarantee { return &entities.CollectionGuarantee{ CollectionId: g.CollectionID.Bytes(), diff --git a/access/grpc/convert/convert_test.go b/access/grpc/convert/convert_test.go index 480dc4f56..cbcb55f31 100644 --- a/access/grpc/convert/convert_test.go +++ b/access/grpc/convert/convert_test.go @@ -139,11 +139,11 @@ func TestConvert_CadenceValue(t *testing.T) { } func TestConvert_Collection(t *testing.T) { - colA := test.CollectionGenerator().New() + colA := test.LightCollectionGenerator().New() - msg := CollectionToMessage(*colA) + msg := LightCollectionToMessage(*colA) - colB, err := MessageToCollection(msg) + colB, err := MessageToLightCollection(msg) require.NoError(t, err) assert.Equal(t, *colA, colB) diff --git a/access/grpc/grpc.go b/access/grpc/grpc.go index 042f09c24..d5ed58e93 100644 --- a/access/grpc/grpc.go +++ b/access/grpc/grpc.go @@ -296,7 +296,7 @@ func (c *BaseClient) GetCollection( ctx context.Context, colID flow.Identifier, opts ...grpc.CallOption, -) (*flow.Collection, error) { +) (*flow.LightCollection, error) { req := &access.GetCollectionByIDRequest{ Id: colID.Bytes(), } @@ -306,7 +306,51 @@ func (c *BaseClient) GetCollection( return nil, newRPCError(err) } - result, err := convert.MessageToCollection(res.GetCollection()) + result, err := convert.MessageToLightCollection(res.GetCollection()) + if err != nil { + return nil, newMessageToEntityError(entityCollection, err) + } + + return &result, nil +} + +func (c *BaseClient) GetLightCollectionByID( + ctx context.Context, + id flow.Identifier, + opts ...grpc.CallOption, +) (*flow.LightCollection, error) { + req := &access.GetCollectionByIDRequest{ + Id: id.Bytes(), + } + + res, err := c.rpcClient.GetCollectionByID(ctx, req, opts...) + if err != nil { + return nil, newRPCError(err) + } + + result, err := convert.MessageToLightCollection(res.GetCollection()) + if err != nil { + return nil, newMessageToEntityError(entityCollection, err) + } + + return &result, nil +} + +func (c *BaseClient) GetFullCollectionByID( + ctx context.Context, + id flow.Identifier, + opts ...grpc.CallOption, +) (*flow.FullCollection, error) { + req := &access.GetFullCollectionByIDRequest{ + Id: id.Bytes(), + } + + res, err := c.rpcClient.GetFullCollectionByID(ctx, req, opts...) + if err != nil { + return nil, newRPCError(err) + } + + result, err := convert.MessageToFullCollection(res.GetTransactions()) if err != nil { return nil, newMessageToEntityError(entityCollection, err) } diff --git a/access/grpc/grpc_test.go b/access/grpc/grpc_test.go index d818f898e..b3d26e323 100644 --- a/access/grpc/grpc_test.go +++ b/access/grpc/grpc_test.go @@ -386,14 +386,14 @@ func TestClient_GetBlockByHeight(t *testing.T) { } func TestClient_GetCollection(t *testing.T) { - cols := test.CollectionGenerator() + cols := test.LightCollectionGenerator() ids := test.IdentifierGenerator() t.Run("Success", clientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockRPCClient, c *BaseClient) { colID := ids.New() expectedCol := cols.New() response := &access.CollectionResponse{ - Collection: convert.CollectionToMessage(*expectedCol), + Collection: convert.LightCollectionToMessage(*expectedCol), } rpc.On("GetCollectionByID", ctx, mock.Anything).Return(response, nil) @@ -417,6 +417,44 @@ func TestClient_GetCollection(t *testing.T) { })) } +func TestClient_GetFullCollectionById(t *testing.T) { + collections := test.FullCollectionGenerator() + ids := test.IdentifierGenerator() + + t.Run("Success", clientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockRPCClient, c *BaseClient) { + expectedCollection := collections.New() + txs, err := convert.FullCollectionToTransactionsMessage(*expectedCollection) + require.NoError(t, err) + + response := &access.FullCollectionResponse{ + Transactions: txs, + } + + rpc. + On("GetFullCollectionByID", ctx, mock.Anything). + Return(response, nil) + + id := ids.New() + actualCollection, err := c.GetFullCollectionByID(ctx, id) + require.NoError(t, err) + + require.Equal(t, expectedCollection, actualCollection) + + })) + + t.Run("Not found error", clientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockRPCClient, c *BaseClient) { + rpc. + On("GetFullCollectionByID", ctx, mock.Anything). + Return(nil, errNotFound) + + id := ids.New() + col, err := c.GetFullCollectionByID(ctx, id) + assert.Error(t, err) + assert.Equal(t, codes.NotFound, status.Code(err)) + assert.Nil(t, col) + })) +} + func TestClient_SendTransaction(t *testing.T) { transactions := test.TransactionGenerator() diff --git a/access/grpc/mocks/RPCClient.go b/access/grpc/mocks/RPCClient.go index 3d4698561..18de91845 100644 --- a/access/grpc/mocks/RPCClient.go +++ b/access/grpc/mocks/RPCClient.go @@ -197,6 +197,186 @@ func (_m *MockRPCClient) GetAccountAtLatestBlock(ctx context.Context, in *access return r0, r1 } +// GetAccountBalanceAtBlockHeight provides a mock function with given fields: ctx, in, opts +func (_m *MockRPCClient) GetAccountBalanceAtBlockHeight(ctx context.Context, in *access.GetAccountBalanceAtBlockHeightRequest, opts ...grpc.CallOption) (*access.AccountBalanceResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 *access.AccountBalanceResponse + if rf, ok := ret.Get(0).(func(context.Context, *access.GetAccountBalanceAtBlockHeightRequest, ...grpc.CallOption) *access.AccountBalanceResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*access.AccountBalanceResponse) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *access.GetAccountBalanceAtBlockHeightRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAccountBalanceAtLatestBlock provides a mock function with given fields: ctx, in, opts +func (_m *MockRPCClient) GetAccountBalanceAtLatestBlock(ctx context.Context, in *access.GetAccountBalanceAtLatestBlockRequest, opts ...grpc.CallOption) (*access.AccountBalanceResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 *access.AccountBalanceResponse + if rf, ok := ret.Get(0).(func(context.Context, *access.GetAccountBalanceAtLatestBlockRequest, ...grpc.CallOption) *access.AccountBalanceResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*access.AccountBalanceResponse) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *access.GetAccountBalanceAtLatestBlockRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAccountKeyAtBlockHeight provides a mock function with given fields: ctx, in, opts +func (_m *MockRPCClient) GetAccountKeyAtBlockHeight(ctx context.Context, in *access.GetAccountKeyAtBlockHeightRequest, opts ...grpc.CallOption) (*access.AccountKeyResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 *access.AccountKeyResponse + if rf, ok := ret.Get(0).(func(context.Context, *access.GetAccountKeyAtBlockHeightRequest, ...grpc.CallOption) *access.AccountKeyResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*access.AccountKeyResponse) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *access.GetAccountKeyAtBlockHeightRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAccountKeyAtLatestBlock provides a mock function with given fields: ctx, in, opts +func (_m *MockRPCClient) GetAccountKeyAtLatestBlock(ctx context.Context, in *access.GetAccountKeyAtLatestBlockRequest, opts ...grpc.CallOption) (*access.AccountKeyResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 *access.AccountKeyResponse + if rf, ok := ret.Get(0).(func(context.Context, *access.GetAccountKeyAtLatestBlockRequest, ...grpc.CallOption) *access.AccountKeyResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*access.AccountKeyResponse) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *access.GetAccountKeyAtLatestBlockRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAccountKeysAtBlockHeight provides a mock function with given fields: ctx, in, opts +func (_m *MockRPCClient) GetAccountKeysAtBlockHeight(ctx context.Context, in *access.GetAccountKeysAtBlockHeightRequest, opts ...grpc.CallOption) (*access.AccountKeysResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 *access.AccountKeysResponse + if rf, ok := ret.Get(0).(func(context.Context, *access.GetAccountKeysAtBlockHeightRequest, ...grpc.CallOption) *access.AccountKeysResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*access.AccountKeysResponse) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *access.GetAccountKeysAtBlockHeightRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAccountKeysAtLatestBlock provides a mock function with given fields: ctx, in, opts +func (_m *MockRPCClient) GetAccountKeysAtLatestBlock(ctx context.Context, in *access.GetAccountKeysAtLatestBlockRequest, opts ...grpc.CallOption) (*access.AccountKeysResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 *access.AccountKeysResponse + if rf, ok := ret.Get(0).(func(context.Context, *access.GetAccountKeysAtLatestBlockRequest, ...grpc.CallOption) *access.AccountKeysResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*access.AccountKeysResponse) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *access.GetAccountKeysAtLatestBlockRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetBlockByHeight provides a mock function with given fields: ctx, in, opts func (_m *MockRPCClient) GetBlockByHeight(ctx context.Context, in *access.GetBlockByHeightRequest, opts ...grpc.CallOption) (*access.BlockResponse, error) { _va := make([]interface{}, len(opts)) @@ -467,6 +647,36 @@ func (_m *MockRPCClient) GetExecutionResultForBlockID(ctx context.Context, in *a return r0, r1 } +// GetFullCollectionByID provides a mock function with given fields: ctx, in, opts +func (_m *MockRPCClient) GetFullCollectionByID(ctx context.Context, in *access.GetFullCollectionByIDRequest, opts ...grpc.CallOption) (*access.FullCollectionResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 *access.FullCollectionResponse + if rf, ok := ret.Get(0).(func(context.Context, *access.GetFullCollectionByIDRequest, ...grpc.CallOption) *access.FullCollectionResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*access.FullCollectionResponse) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *access.GetFullCollectionByIDRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetLatestBlock provides a mock function with given fields: ctx, in, opts func (_m *MockRPCClient) GetLatestBlock(ctx context.Context, in *access.GetLatestBlockRequest, opts ...grpc.CallOption) (*access.BlockResponse, error) { _va := make([]interface{}, len(opts)) diff --git a/access/http/client.go b/access/http/client.go index 4e25212bd..0a26008cd 100644 --- a/access/http/client.go +++ b/access/http/client.go @@ -152,7 +152,7 @@ func (c *Client) GetBlockByHeight(ctx context.Context, height uint64) (*flow.Blo return blocks[0], nil } -func (c *Client) GetCollection(ctx context.Context, ID flow.Identifier) (*flow.Collection, error) { +func (c *Client) GetCollection(ctx context.Context, ID flow.Identifier) (*flow.LightCollection, error) { return c.httpClient.GetCollection(ctx, ID) } diff --git a/access/http/convert/convert.go b/access/http/convert/convert.go index 2f36bf11f..4296537c5 100644 --- a/access/http/convert/convert.go +++ b/access/http/convert/convert.go @@ -172,12 +172,12 @@ func ToBlock(block *models.Block) (*flow.Block, error) { }, nil } -func ToCollection(collection *models.Collection) *flow.Collection { +func ToCollection(collection *models.Collection) *flow.LightCollection { IDs := make([]flow.Identifier, len(collection.Transactions)) for i, tx := range collection.Transactions { IDs[i] = flow.HexToID(tx.Id) } - return &flow.Collection{ + return &flow.LightCollection{ TransactionIDs: IDs, } } diff --git a/access/http/http.go b/access/http/http.go index 6815b3905..9f09e079a 100644 --- a/access/http/http.go +++ b/access/http/http.go @@ -251,7 +251,7 @@ func (c *BaseClient) GetCollection( ctx context.Context, ID flow.Identifier, opts ...queryOpts, -) (*flow.Collection, error) { +) (*flow.LightCollection, error) { collection, err := c.handler.getCollection(ctx, ID.String(), opts...) if err != nil { return nil, err diff --git a/access/http/internal/unittest/fixtures.go b/access/http/internal/unittest/fixtures.go index 81881c390..2c5695202 100644 --- a/access/http/internal/unittest/fixtures.go +++ b/access/http/internal/unittest/fixtures.go @@ -99,7 +99,7 @@ func BlockFlowFixture() models.Block { } func CollectionFlowFixture() models.Collection { - collection := test.CollectionGenerator().New() + collection := test.LightCollectionGenerator().New() return models.Collection{ Id: collection.ID().String(), diff --git a/access/mocks/Client.go b/access/mocks/Client.go index 7a39bb053..bb604c48a 100644 --- a/access/mocks/Client.go +++ b/access/mocks/Client.go @@ -263,15 +263,15 @@ func (_m *Client) GetBlockHeaderByID(ctx context.Context, blockID flow.Identifie } // GetCollection provides a mock function with given fields: ctx, colID -func (_m *Client) GetCollection(ctx context.Context, colID flow.Identifier) (*flow.Collection, error) { +func (_m *Client) GetCollection(ctx context.Context, colID flow.Identifier) (*flow.LightCollection, error) { ret := _m.Called(ctx, colID) - var r0 *flow.Collection - if rf, ok := ret.Get(0).(func(context.Context, flow.Identifier) *flow.Collection); ok { + var r0 *flow.LightCollection + if rf, ok := ret.Get(0).(func(context.Context, flow.Identifier) *flow.LightCollection); ok { r0 = rf(ctx, colID) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*flow.Collection) + r0 = ret.Get(0).(*flow.LightCollection) } } diff --git a/collection.go b/collection.go index bc4e02645..998a7cb07 100644 --- a/collection.go +++ b/collection.go @@ -18,18 +18,18 @@ package flow -// A Collection is a list of transactions bundled together for inclusion in a block. -type Collection struct { +// A LightCollection is a list of transactions bundled together for inclusion in a block. +type LightCollection struct { TransactionIDs []Identifier } // ID returns the canonical SHA3-256 hash of this collection. -func (c Collection) ID() Identifier { +func (c LightCollection) ID() Identifier { return HashToID(defaultEntityHasher.ComputeHash(c.Encode())) } // Encode returns the canonical RLP byte representation of this collection. -func (c Collection) Encode() []byte { +func (c LightCollection) Encode() []byte { transactionIDs := make([][]byte, len(c.TransactionIDs)) for i, id := range c.TransactionIDs { transactionIDs[i] = id.Bytes() @@ -47,3 +47,20 @@ func (c Collection) Encode() []byte { type CollectionGuarantee struct { CollectionID Identifier } + +type FullCollection struct { + Transactions []*Transaction +} + +// Light returns the light, reference-only version of the collection. +func (c FullCollection) Light() LightCollection { + lc := LightCollection{TransactionIDs: make([]Identifier, 0, len(c.Transactions))} + for _, tx := range c.Transactions { + lc.TransactionIDs = append(lc.TransactionIDs, tx.ID()) + } + return lc +} + +func (c FullCollection) ID() Identifier { + return c.Light().ID() +} diff --git a/examples/get_collection/main.go b/examples/get_collection/main.go index be7548fc6..83e9beb1b 100644 --- a/examples/get_collection/main.go +++ b/examples/get_collection/main.go @@ -42,7 +42,7 @@ func demo(exampleCollectionID flow.Identifier) { printCollection(collection, err) } -func printCollection(collection *flow.Collection, err error) { +func printCollection(collection *flow.LightCollection, err error) { examples.Handle(err) fmt.Printf("\nID: %s", collection.ID().String()) diff --git a/examples/go.mod b/examples/go.mod index b1c8aae8f..6fd2b9c50 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -7,7 +7,7 @@ toolchain go1.22.4 replace github.com/onflow/flow-go-sdk => ../ require ( - github.com/onflow/cadence v1.0.0-preview.38 + github.com/onflow/cadence v1.0.0-preview.52 github.com/onflow/flow-cli/flowkit v1.11.0 github.com/onflow/flow-go-sdk v0.41.17 github.com/spf13/afero v1.11.0 @@ -41,9 +41,9 @@ require ( github.com/logrusorgru/aurora/v4 v4.0.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/onflow/atree v0.7.0-rc.2 // indirect + github.com/onflow/atree v0.8.0-rc.6 // indirect github.com/onflow/crypto v0.25.1 // indirect - github.com/onflow/flow/protobuf/go/flow v0.4.3 // indirect + github.com/onflow/flow/protobuf/go/flow v0.4.7 // indirect github.com/onflow/sdks v0.6.0-preview.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/examples/go.sum b/examples/go.sum index cbdeadaee..1a3ba9dca 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -104,6 +104,7 @@ github.com/onflow/atree v0.6.0/go.mod h1:gBHU0M05qCbv9NN0kijLWMgC47gHVNBIp4KmsVF github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f/go.mod h1:xvP61FoOs95K7IYdIYRnNcYQGf4nbF/uuJ0tHf4DRuM= github.com/onflow/atree v0.6.1-0.20240429171449-cb486ceb1f9c/go.mod h1:xvP61FoOs95K7IYdIYRnNcYQGf4nbF/uuJ0tHf4DRuM= github.com/onflow/atree v0.7.0-rc.2/go.mod h1:xvP61FoOs95K7IYdIYRnNcYQGf4nbF/uuJ0tHf4DRuM= +github.com/onflow/atree v0.8.0-rc.6/go.mod h1:yccR+LR7xc1Jdic0mrjocbHvUD7lnVvg8/Ct1AA5zBo= github.com/onflow/cadence v0.42.7 h1:Qp9VYX901saO7wPwF/rwV4cMS+0mfWxnm9EqbYElYy4= github.com/onflow/cadence v0.42.7/go.mod h1:raU8va8QRyTa/eUbhej4mbyW2ETePfSaywoo36MddgE= github.com/onflow/cadence v1.0.0-M3/go.mod h1:odXGZZ/wGNA5mwT8bC9v8u8EXACHllB2ABSZK65TGL8= @@ -115,6 +116,7 @@ github.com/onflow/cadence v1.0.0-preview.31/go.mod h1:3LM1VgE9HkJ815whY/F0LYWULw github.com/onflow/cadence v1.0.0-preview.35/go.mod h1:jOwvPSSLTr9TvaKMs7KKiBYMmpdpNNAFxBsjMlrqVD0= github.com/onflow/cadence v1.0.0-preview.36/go.mod h1:jOwvPSSLTr9TvaKMs7KKiBYMmpdpNNAFxBsjMlrqVD0= github.com/onflow/cadence v1.0.0-preview.38/go.mod h1:jOwvPSSLTr9TvaKMs7KKiBYMmpdpNNAFxBsjMlrqVD0= +github.com/onflow/cadence v1.0.0-preview.52/go.mod h1:7wvvecnAZtYOspLOS3Lh+FuAmMeSrXhAWiycC3kQ1UU= github.com/onflow/crypto v0.25.0 h1:BeWbLsh3ZD13Ej+Uky6kg1PL1ZIVBDVX+2MVBNwqddg= github.com/onflow/crypto v0.25.0/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI= github.com/onflow/crypto v0.25.1/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI= @@ -124,6 +126,7 @@ github.com/onflow/flow/protobuf/go/flow v0.3.2-0.20231124194313-106cc495def6 h1: github.com/onflow/flow/protobuf/go/flow v0.3.2-0.20231124194313-106cc495def6/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= github.com/onflow/flow/protobuf/go/flow v0.4.0/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= github.com/onflow/flow/protobuf/go/flow v0.4.3/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= +github.com/onflow/flow/protobuf/go/flow v0.4.7/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= github.com/onflow/sdks v0.5.0 h1:2HCRibwqDaQ1c9oUApnkZtEAhWiNY2GTpRD5+ftdkN8= github.com/onflow/sdks v0.5.0/go.mod h1:F0dj0EyHC55kknLkeD10js4mo14yTdMotnWMslPirrU= github.com/onflow/sdks v0.5.1-0.20230912225508-b35402f12bba/go.mod h1:F0dj0EyHC55kknLkeD10js4mo14yTdMotnWMslPirrU= diff --git a/go.mod b/go.mod index 7ab67be1c..91996ab06 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/kms v1.31.0 github.com/onflow/cadence v1.0.0-preview.52 github.com/onflow/crypto v0.25.1 - github.com/onflow/flow/protobuf/go/flow v0.4.3 + github.com/onflow/flow/protobuf/go/flow v0.4.7 github.com/onflow/go-ethereum v1.13.4 github.com/onflow/sdks v0.6.0-preview.1 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 089bf087a..0ea372414 100644 --- a/go.sum +++ b/go.sum @@ -137,8 +137,8 @@ github.com/onflow/cadence v1.0.0-preview.52 h1:hZ92e6lL2+PQa3C1i5jJh0zZYFdW89+X1 github.com/onflow/cadence v1.0.0-preview.52/go.mod h1:7wvvecnAZtYOspLOS3Lh+FuAmMeSrXhAWiycC3kQ1UU= 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.3 h1:gdY7Ftto8dtU+0wI+6ZgW4oE+z0DSDUMIDwVx8mqae8= -github.com/onflow/flow/protobuf/go/flow v0.4.3/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= +github.com/onflow/flow/protobuf/go/flow v0.4.7 h1:iP6DFx4wZ3ETORsyeqzHu7neFT3d1CXF6wdK+AOOjmc= +github.com/onflow/flow/protobuf/go/flow v0.4.7/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= github.com/onflow/go-ethereum v1.13.4 h1:iNO86fm8RbBbhZ87ZulblInqCdHnAQVY8okBrNsTevc= github.com/onflow/go-ethereum v1.13.4/go.mod h1:cE/gEUkAffhwbVmMJYz+t1dAfVNHNwZCgc3BWtZxBGY= github.com/onflow/sdks v0.6.0-preview.1 h1:mb/cUezuqWEP1gFZNAgUI4boBltudv4nlfxke1KBp9k= diff --git a/test/entities.go b/test/entities.go index 0f00be42b..bba6519b5 100644 --- a/test/entities.go +++ b/test/entities.go @@ -188,18 +188,18 @@ func (g *BlockHeaders) New() flow.BlockHeader { } } -type Collections struct { +type LightCollection struct { ids *Identifiers } -func CollectionGenerator() *Collections { - return &Collections{ +func LightCollectionGenerator() *LightCollection { + return &LightCollection{ ids: IdentifierGenerator(), } } -func (g *Collections) New() *flow.Collection { - return &flow.Collection{ +func (g *LightCollection) New() *flow.LightCollection { + return &flow.LightCollection{ TransactionIDs: []flow.Identifier{ g.ids.New(), g.ids.New(), @@ -207,6 +207,22 @@ func (g *Collections) New() *flow.Collection { } } +type FullCollection struct { + Transactions *Transactions +} + +func FullCollectionGenerator() *FullCollection { + return &FullCollection{ + Transactions: TransactionGenerator(), + } +} + +func (c *FullCollection) New() *flow.FullCollection { + return &flow.FullCollection{ + Transactions: []*flow.Transaction{c.Transactions.New(), c.Transactions.New()}, + } +} + type CollectionGuarantees struct { ids *Identifiers } From 291e452f3df0cc5463a4fbf84c917ee8827f768a Mon Sep 17 00:00:00 2001 From: Illia Malachyn Date: Thu, 12 Sep 2024 17:15:02 +0300 Subject: [PATCH 2/4] remove renaming of flow.Collection --- access/client.go | 2 +- access/grpc/client.go | 4 ++-- access/grpc/convert/convert.go | 8 ++++---- access/grpc/grpc.go | 4 ++-- access/http/client.go | 2 +- access/http/convert/convert.go | 4 ++-- access/http/http.go | 2 +- access/mocks/Client.go | 8 ++++---- collection.go | 12 ++++++------ examples/get_collection/main.go | 2 +- test/entities.go | 4 ++-- 11 files changed, 26 insertions(+), 26 deletions(-) diff --git a/access/client.go b/access/client.go index 880714cc5..fe0220675 100644 --- a/access/client.go +++ b/access/client.go @@ -62,7 +62,7 @@ type Client interface { GetBlockByHeight(ctx context.Context, height uint64) (*flow.Block, error) // GetCollection gets a collection by ID. - GetCollection(ctx context.Context, colID flow.Identifier) (*flow.LightCollection, error) + GetCollection(ctx context.Context, colID flow.Identifier) (*flow.Collection, error) // SendTransaction submits a transaction to the network. SendTransaction(ctx context.Context, tx flow.Transaction) error diff --git a/access/grpc/client.go b/access/grpc/client.go index 8db8ffa45..d97824b6a 100644 --- a/access/grpc/client.go +++ b/access/grpc/client.go @@ -157,11 +157,11 @@ func (c *Client) GetBlockByHeight(ctx context.Context, height uint64) (*flow.Blo return c.grpc.GetBlockByHeight(ctx, height) } -func (c *Client) GetCollection(ctx context.Context, colID flow.Identifier) (*flow.LightCollection, error) { +func (c *Client) GetCollection(ctx context.Context, colID flow.Identifier) (*flow.Collection, error) { return c.grpc.GetCollection(ctx, colID) } -func (c *Client) GetCollectionByID(ctx context.Context, id flow.Identifier) (*flow.LightCollection, error) { +func (c *Client) GetCollectionByID(ctx context.Context, id flow.Identifier) (*flow.Collection, error) { return c.grpc.GetLightCollectionByID(ctx, id) } diff --git a/access/grpc/convert/convert.go b/access/grpc/convert/convert.go index a9a693713..736ca6f8b 100644 --- a/access/grpc/convert/convert.go +++ b/access/grpc/convert/convert.go @@ -241,7 +241,7 @@ func MessageToCadenceValue(m []byte, options []jsoncdc.Option) (cadence.Value, e return v, nil } -func LightCollectionToMessage(c flow.LightCollection) *entities.Collection { +func LightCollectionToMessage(c flow.Collection) *entities.Collection { transactionIDMessages := make([][]byte, len(c.TransactionIDs)) for i, transactionID := range c.TransactionIDs { transactionIDMessages[i] = transactionID.Bytes() @@ -267,9 +267,9 @@ func FullCollectionToTransactionsMessage(tx flow.FullCollection) ([]*entities.Tr return convertedTxs, nil } -func MessageToLightCollection(m *entities.Collection) (flow.LightCollection, error) { +func MessageToLightCollection(m *entities.Collection) (flow.Collection, error) { if m == nil { - return flow.LightCollection{}, ErrEmptyMessage + return flow.Collection{}, ErrEmptyMessage } transactionIDMessages := m.GetTransactionIds() @@ -279,7 +279,7 @@ func MessageToLightCollection(m *entities.Collection) (flow.LightCollection, err transactionIDs[i] = flow.HashToID(transactionIDMsg) } - return flow.LightCollection{ + return flow.Collection{ TransactionIDs: transactionIDs, }, nil } diff --git a/access/grpc/grpc.go b/access/grpc/grpc.go index d5ed58e93..fbe4c5d61 100644 --- a/access/grpc/grpc.go +++ b/access/grpc/grpc.go @@ -296,7 +296,7 @@ func (c *BaseClient) GetCollection( ctx context.Context, colID flow.Identifier, opts ...grpc.CallOption, -) (*flow.LightCollection, error) { +) (*flow.Collection, error) { req := &access.GetCollectionByIDRequest{ Id: colID.Bytes(), } @@ -318,7 +318,7 @@ func (c *BaseClient) GetLightCollectionByID( ctx context.Context, id flow.Identifier, opts ...grpc.CallOption, -) (*flow.LightCollection, error) { +) (*flow.Collection, error) { req := &access.GetCollectionByIDRequest{ Id: id.Bytes(), } diff --git a/access/http/client.go b/access/http/client.go index 0a26008cd..4e25212bd 100644 --- a/access/http/client.go +++ b/access/http/client.go @@ -152,7 +152,7 @@ func (c *Client) GetBlockByHeight(ctx context.Context, height uint64) (*flow.Blo return blocks[0], nil } -func (c *Client) GetCollection(ctx context.Context, ID flow.Identifier) (*flow.LightCollection, error) { +func (c *Client) GetCollection(ctx context.Context, ID flow.Identifier) (*flow.Collection, error) { return c.httpClient.GetCollection(ctx, ID) } diff --git a/access/http/convert/convert.go b/access/http/convert/convert.go index 4296537c5..2f36bf11f 100644 --- a/access/http/convert/convert.go +++ b/access/http/convert/convert.go @@ -172,12 +172,12 @@ func ToBlock(block *models.Block) (*flow.Block, error) { }, nil } -func ToCollection(collection *models.Collection) *flow.LightCollection { +func ToCollection(collection *models.Collection) *flow.Collection { IDs := make([]flow.Identifier, len(collection.Transactions)) for i, tx := range collection.Transactions { IDs[i] = flow.HexToID(tx.Id) } - return &flow.LightCollection{ + return &flow.Collection{ TransactionIDs: IDs, } } diff --git a/access/http/http.go b/access/http/http.go index 9f09e079a..6815b3905 100644 --- a/access/http/http.go +++ b/access/http/http.go @@ -251,7 +251,7 @@ func (c *BaseClient) GetCollection( ctx context.Context, ID flow.Identifier, opts ...queryOpts, -) (*flow.LightCollection, error) { +) (*flow.Collection, error) { collection, err := c.handler.getCollection(ctx, ID.String(), opts...) if err != nil { return nil, err diff --git a/access/mocks/Client.go b/access/mocks/Client.go index bb604c48a..7a39bb053 100644 --- a/access/mocks/Client.go +++ b/access/mocks/Client.go @@ -263,15 +263,15 @@ func (_m *Client) GetBlockHeaderByID(ctx context.Context, blockID flow.Identifie } // GetCollection provides a mock function with given fields: ctx, colID -func (_m *Client) GetCollection(ctx context.Context, colID flow.Identifier) (*flow.LightCollection, error) { +func (_m *Client) GetCollection(ctx context.Context, colID flow.Identifier) (*flow.Collection, error) { ret := _m.Called(ctx, colID) - var r0 *flow.LightCollection - if rf, ok := ret.Get(0).(func(context.Context, flow.Identifier) *flow.LightCollection); ok { + var r0 *flow.Collection + if rf, ok := ret.Get(0).(func(context.Context, flow.Identifier) *flow.Collection); ok { r0 = rf(ctx, colID) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*flow.LightCollection) + r0 = ret.Get(0).(*flow.Collection) } } diff --git a/collection.go b/collection.go index 998a7cb07..3de5fff16 100644 --- a/collection.go +++ b/collection.go @@ -18,18 +18,18 @@ package flow -// A LightCollection is a list of transactions bundled together for inclusion in a block. -type LightCollection struct { +// A Collection is a list of transactions bundled together for inclusion in a block. +type Collection struct { TransactionIDs []Identifier } // ID returns the canonical SHA3-256 hash of this collection. -func (c LightCollection) ID() Identifier { +func (c Collection) ID() Identifier { return HashToID(defaultEntityHasher.ComputeHash(c.Encode())) } // Encode returns the canonical RLP byte representation of this collection. -func (c LightCollection) Encode() []byte { +func (c Collection) Encode() []byte { transactionIDs := make([][]byte, len(c.TransactionIDs)) for i, id := range c.TransactionIDs { transactionIDs[i] = id.Bytes() @@ -53,8 +53,8 @@ type FullCollection struct { } // Light returns the light, reference-only version of the collection. -func (c FullCollection) Light() LightCollection { - lc := LightCollection{TransactionIDs: make([]Identifier, 0, len(c.Transactions))} +func (c FullCollection) Light() Collection { + lc := Collection{TransactionIDs: make([]Identifier, 0, len(c.Transactions))} for _, tx := range c.Transactions { lc.TransactionIDs = append(lc.TransactionIDs, tx.ID()) } diff --git a/examples/get_collection/main.go b/examples/get_collection/main.go index 83e9beb1b..be7548fc6 100644 --- a/examples/get_collection/main.go +++ b/examples/get_collection/main.go @@ -42,7 +42,7 @@ func demo(exampleCollectionID flow.Identifier) { printCollection(collection, err) } -func printCollection(collection *flow.LightCollection, err error) { +func printCollection(collection *flow.Collection, err error) { examples.Handle(err) fmt.Printf("\nID: %s", collection.ID().String()) diff --git a/test/entities.go b/test/entities.go index bba6519b5..689078d12 100644 --- a/test/entities.go +++ b/test/entities.go @@ -198,8 +198,8 @@ func LightCollectionGenerator() *LightCollection { } } -func (g *LightCollection) New() *flow.LightCollection { - return &flow.LightCollection{ +func (g *LightCollection) New() *flow.Collection { + return &flow.Collection{ TransactionIDs: []flow.Identifier{ g.ids.New(), g.ids.New(), From 83455775b8e238b33364300a8611668a7f6d4861 Mon Sep 17 00:00:00 2001 From: Illia Malachyn Date: Thu, 12 Sep 2024 17:17:52 +0300 Subject: [PATCH 3/4] revert renaming in convert functions --- access/grpc/convert/convert.go | 2 +- access/grpc/convert/convert_test.go | 2 +- access/grpc/grpc_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/access/grpc/convert/convert.go b/access/grpc/convert/convert.go index 736ca6f8b..2b29c98e8 100644 --- a/access/grpc/convert/convert.go +++ b/access/grpc/convert/convert.go @@ -241,7 +241,7 @@ func MessageToCadenceValue(m []byte, options []jsoncdc.Option) (cadence.Value, e return v, nil } -func LightCollectionToMessage(c flow.Collection) *entities.Collection { +func CollectionToMessage(c flow.Collection) *entities.Collection { transactionIDMessages := make([][]byte, len(c.TransactionIDs)) for i, transactionID := range c.TransactionIDs { transactionIDMessages[i] = transactionID.Bytes() diff --git a/access/grpc/convert/convert_test.go b/access/grpc/convert/convert_test.go index cbcb55f31..670fb8314 100644 --- a/access/grpc/convert/convert_test.go +++ b/access/grpc/convert/convert_test.go @@ -141,7 +141,7 @@ func TestConvert_CadenceValue(t *testing.T) { func TestConvert_Collection(t *testing.T) { colA := test.LightCollectionGenerator().New() - msg := LightCollectionToMessage(*colA) + msg := CollectionToMessage(*colA) colB, err := MessageToLightCollection(msg) require.NoError(t, err) diff --git a/access/grpc/grpc_test.go b/access/grpc/grpc_test.go index b3d26e323..4f7ab44c4 100644 --- a/access/grpc/grpc_test.go +++ b/access/grpc/grpc_test.go @@ -393,7 +393,7 @@ func TestClient_GetCollection(t *testing.T) { colID := ids.New() expectedCol := cols.New() response := &access.CollectionResponse{ - Collection: convert.LightCollectionToMessage(*expectedCol), + Collection: convert.CollectionToMessage(*expectedCol), } rpc.On("GetCollectionByID", ctx, mock.Anything).Return(response, nil) From 9a012c25b1fa452775d0983bf43be5a6ee2cb472 Mon Sep 17 00:00:00 2001 From: Illia Malachyn Date: Thu, 12 Sep 2024 17:18:54 +0300 Subject: [PATCH 4/4] rever renaming of convert MessageToCollection --- access/grpc/convert/convert.go | 2 +- access/grpc/convert/convert_test.go | 2 +- access/grpc/grpc.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/access/grpc/convert/convert.go b/access/grpc/convert/convert.go index 2b29c98e8..dcfd353af 100644 --- a/access/grpc/convert/convert.go +++ b/access/grpc/convert/convert.go @@ -267,7 +267,7 @@ func FullCollectionToTransactionsMessage(tx flow.FullCollection) ([]*entities.Tr return convertedTxs, nil } -func MessageToLightCollection(m *entities.Collection) (flow.Collection, error) { +func MessageToCollection(m *entities.Collection) (flow.Collection, error) { if m == nil { return flow.Collection{}, ErrEmptyMessage } diff --git a/access/grpc/convert/convert_test.go b/access/grpc/convert/convert_test.go index 670fb8314..2c255a301 100644 --- a/access/grpc/convert/convert_test.go +++ b/access/grpc/convert/convert_test.go @@ -143,7 +143,7 @@ func TestConvert_Collection(t *testing.T) { msg := CollectionToMessage(*colA) - colB, err := MessageToLightCollection(msg) + colB, err := MessageToCollection(msg) require.NoError(t, err) assert.Equal(t, *colA, colB) diff --git a/access/grpc/grpc.go b/access/grpc/grpc.go index fbe4c5d61..c352d7de7 100644 --- a/access/grpc/grpc.go +++ b/access/grpc/grpc.go @@ -306,7 +306,7 @@ func (c *BaseClient) GetCollection( return nil, newRPCError(err) } - result, err := convert.MessageToLightCollection(res.GetCollection()) + result, err := convert.MessageToCollection(res.GetCollection()) if err != nil { return nil, newMessageToEntityError(entityCollection, err) } @@ -328,7 +328,7 @@ func (c *BaseClient) GetLightCollectionByID( return nil, newRPCError(err) } - result, err := convert.MessageToLightCollection(res.GetCollection()) + result, err := convert.MessageToCollection(res.GetCollection()) if err != nil { return nil, newMessageToEntityError(entityCollection, err) }