Skip to content

Commit

Permalink
Merge pull request #681 from onflow/leo/add-get-full-collection-support
Browse files Browse the repository at this point in the history
Add get full collection support
  • Loading branch information
zhangchiqing authored May 28, 2024
2 parents 988cd96 + 88e82bc commit 1173975
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 11 deletions.
14 changes: 14 additions & 0 deletions adapters/access.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,20 @@ func (a *AccessAdapter) GetCollectionByID(_ context.Context, id flowgo.Identifie
return collection, nil
}

func (a *AccessAdapter) GetFullCollectionByID(_ context.Context, id flowgo.Identifier) (*flowgo.Collection, error) {
collection, err := a.emulator.GetFullCollectionByID(id)
if err != nil {
return nil, convertError(err, codes.Internal)
}

a.logger.Debug().
Str("colID", id.String()).
Msg("📚 GetFullCollectionByID called")

return collection, nil

}

func (a *AccessAdapter) GetTransaction(_ context.Context, id flowgo.Identifier) (*flowgo.TransactionBody, error) {
tx, err := a.emulator.GetTransaction(id)
if err != nil {
Expand Down
18 changes: 18 additions & 0 deletions emulator/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,24 @@ func (b *Blockchain) getCollectionByID(colID flowgo.Identifier) (*flowgo.LightCo
return &col, nil
}

func (b *Blockchain) GetFullCollectionByID(colID flowgo.Identifier) (*flowgo.Collection, error) {
b.mu.RLock()
defer b.mu.RUnlock()
return b.getFullCollectionByID(colID)
}

func (b *Blockchain) getFullCollectionByID(colID flowgo.Identifier) (*flowgo.Collection, error) {
col, err := b.storage.FullCollectionByID(context.Background(), colID)
if err != nil {
if errors.Is(err, storage.ErrNotFound) {
return nil, &types.CollectionNotFoundError{ID: colID}
}
return nil, err
}

return &col, nil
}

// GetTransaction gets an existing transaction by ID.
//
// The function first looks in the pending block, then the current emulator state.
Expand Down
1 change: 1 addition & 0 deletions emulator/emulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ type AccessProvider interface {
GetBlockByHeight(height uint64) (*flowgo.Block, error)

GetCollectionByID(colID flowgo.Identifier) (*flowgo.LightCollection, error)
GetFullCollectionByID(colID flowgo.Identifier) (*flowgo.Collection, error)

GetTransaction(txID flowgo.Identifier) (*flowgo.TransactionBody, error)
GetTransactionResult(txID flowgo.Identifier) (*access.TransactionResult, error)
Expand Down
15 changes: 15 additions & 0 deletions emulator/mocks/emulator.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions storage/memstore/memstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,32 @@ func (s *Store) CollectionByID(
return tx, nil
}

func (s *Store) FullCollectionByID(
_ context.Context,
collectionID flowgo.Identifier,
) (flowgo.Collection, error) {
s.mu.RLock()
defer s.mu.RUnlock()

light, ok := s.collections[collectionID]
if !ok {
return flowgo.Collection{}, storage.ErrNotFound
}

txs := make([]*flowgo.TransactionBody, len(light.Transactions))
for i, txID := range light.Transactions {
tx, ok := s.transactions[txID]
if !ok {
return flowgo.Collection{}, storage.ErrNotFound
}
txs[i] = &tx
}

return flowgo.Collection{
Transactions: txs,
}, nil
}

func (s *Store) TransactionByID(
_ context.Context,
transactionID flowgo.Identifier,
Expand Down
15 changes: 15 additions & 0 deletions storage/mocks/store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions storage/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ type Store interface {
// CollectionByID gets the collection (transaction IDs only) with the given ID.
CollectionByID(ctx context.Context, collectionID flowgo.Identifier) (flowgo.LightCollection, error)

// FullCollectionByID gets the full collection (including transaction bodies) with the given ID.
FullCollectionByID(ctx context.Context, collectionID flowgo.Identifier) (flowgo.Collection, error)

// TransactionByID gets the transaction with the given ID.
TransactionByID(ctx context.Context, transactionID flowgo.Identifier) (flowgo.TransactionBody, error)

Expand Down Expand Up @@ -327,6 +330,44 @@ func (s *DefaultStore) CollectionByID(
return
}

func (s *DefaultStore) FullCollectionByID(
ctx context.Context,
colID flowgo.Identifier,
) (
col flowgo.Collection,
err error,
) {
light := flowgo.LightCollection{}
encCol, err := s.DataGetter.GetBytes(
ctx,
s.KeyGenerator.Storage(CollectionStoreName),
s.KeyGenerator.Identifier(colID),
)
if err != nil {
return
}

err = decodeCollection(&light, encCol)
if err != nil {
return
}

txs := make([]*flowgo.TransactionBody, len(light.Transactions))
for i, txID := range light.Transactions {
tx, err := s.TransactionByID(ctx, txID)
if err != nil {
return col, err
}
txs[i] = &tx
}

col = flowgo.Collection{
Transactions: txs,
}

return
}

func (s *DefaultStore) InsertCollection(ctx context.Context, col flowgo.LightCollection) error {
encCol, err := encodeCollection(col)
if err != nil {
Expand Down
46 changes: 35 additions & 11 deletions storage/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,16 +133,8 @@ func TestCollections(t *testing.T) {
require.NoError(t, os.RemoveAll(dir))
}()

ids := test.IdentifierGenerator()

// collection with 3 transactions
col := flowgo.LightCollection{
Transactions: []flowgo.Identifier{
flowgo.Identifier(ids.New()),
flowgo.Identifier(ids.New()),
flowgo.Identifier(ids.New()),
},
}
col := unittest.FullCollectionFixture(3)

t.Run("should return error for not found", func(t *testing.T) {
_, err := store.CollectionByID(context.Background(), col.ID())
Expand All @@ -152,13 +144,13 @@ func TestCollections(t *testing.T) {
})

t.Run("should be able to insert collection", func(t *testing.T) {
err := store.InsertCollection(context.Background(), col)
err := store.InsertCollection(context.Background(), col.Light())
assert.NoError(t, err)

t.Run("should be able to get inserted collection", func(t *testing.T) {
storedCol, err := store.CollectionByID(context.Background(), col.ID())
require.NoError(t, err)
assert.Equal(t, col, storedCol)
assert.Equal(t, col.Light(), storedCol)
})
})
}
Expand Down Expand Up @@ -194,6 +186,38 @@ func TestTransactions(t *testing.T) {
})
}

func TestFullCollection(t *testing.T) {
t.Parallel()
store, dir := setupStore(t)
defer func() {
require.NoError(t, store.Close())
require.NoError(t, os.RemoveAll(dir))
}()

col := unittest.FullCollectionFixture(3)

t.Run("should be able to insert full collection", func(t *testing.T) {
_, err := store.CollectionByID(context.Background(), col.ID())
require.Error(t, storage.ErrNotFound, err)

_, err = store.FullCollectionByID(context.Background(), col.ID())
require.Error(t, storage.ErrNotFound, err)

err = store.InsertCollection(context.Background(), col.Light())
require.NoError(t, err)

for _, tx := range col.Transactions {
err = store.InsertTransaction(context.Background(), *tx)
require.NoError(t, err)
}

c, err := store.FullCollectionByID(context.Background(), col.ID())
require.NoError(t, err)
require.Equal(t, col, c)
})

}

func TestTransactionResults(t *testing.T) {

t.Parallel()
Expand Down
12 changes: 12 additions & 0 deletions utils/unittest/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,15 @@ func StorableTransactionResultFixture() types.StorableTransactionResult {
},
}
}

func FullCollectionFixture(n int) flowgo.Collection {
transactions := make([]*flowgo.TransactionBody, n)
for i := 0; i < n; i++ {
tx := TransactionFixture()
transactions[i] = &tx
}

return flowgo.Collection{
Transactions: transactions,
}
}

0 comments on commit 1173975

Please sign in to comment.