From eea0a826478f926341e8e664d405a2056fde0aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zdyba=C5=82?= Date: Thu, 14 Oct 2021 10:48:48 +0200 Subject: [PATCH] Change mock implementation to use store.KVStore instead of maps * update `MockDataAvailabilityLayerClient` to use `KVStore` instead of maps * ensure that `KVStore` is passed to `Init` in the tests Resolves #134. --- da/mock/mock.go | 69 +++++++++++++++++++++++++--------------- node/integration_test.go | 11 ++++--- 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/da/mock/mock.go b/da/mock/mock.go index b4516d83ab2..0fad3242151 100644 --- a/da/mock/mock.go +++ b/da/mock/mock.go @@ -1,7 +1,7 @@ package mock import ( - "sync" + "encoding/binary" "github.com/celestiaorg/optimint/da" "github.com/celestiaorg/optimint/log" @@ -13,23 +13,16 @@ import ( // It does actually ensures DA - it stores data in-memory. type MockDataAvailabilityLayerClient struct { logger log.Logger - - Blocks map[[32]byte]*types.Block - BlockIndex map[uint64][32]byte - - mtx sync.Mutex + dalcKV store.KVStore } var _ da.DataAvailabilityLayerClient = &MockDataAvailabilityLayerClient{} var _ da.BlockRetriever = &MockDataAvailabilityLayerClient{} // Init is called once to allow DA client to read configuration and initialize resources. -func (m *MockDataAvailabilityLayerClient) Init(config []byte, kvStore store.KVStore, logger log.Logger) error { - m.mtx.Lock() - defer m.mtx.Unlock() +func (m *MockDataAvailabilityLayerClient) Init(config []byte, dalcKV store.KVStore, logger log.Logger) error { m.logger = logger - m.Blocks = make(map[[32]byte]*types.Block) - m.BlockIndex = make(map[uint64][32]byte) + m.dalcKV = dalcKV return nil } @@ -49,13 +42,22 @@ func (m *MockDataAvailabilityLayerClient) Stop() error { // This should create a transaction which (potentially) // triggers a state transition in the DA layer. func (m *MockDataAvailabilityLayerClient) SubmitBlock(block *types.Block) da.ResultSubmitBlock { - m.mtx.Lock() - defer m.mtx.Unlock() m.logger.Debug("Submitting block to DA layer!", "height", block.Header.Height) hash := block.Header.Hash() - m.Blocks[hash] = block - m.BlockIndex[block.Header.Height] = hash + blob, err := block.MarshalBinary() + if err != nil { + return da.ResultSubmitBlock{DAResult: da.DAResult{Code: da.StatusError, Message: err.Error()}} + } + + err = m.dalcKV.Set(getKey(block.Header.Height), hash[:]) + if err != nil { + return da.ResultSubmitBlock{DAResult: da.DAResult{Code: da.StatusError, Message: err.Error()}} + } + err = m.dalcKV.Set(hash[:], blob) + if err != nil { + return da.ResultSubmitBlock{DAResult: da.DAResult{Code: da.StatusError, Message: err.Error()}} + } return da.ResultSubmitBlock{ DAResult: da.DAResult{ @@ -67,19 +69,36 @@ func (m *MockDataAvailabilityLayerClient) SubmitBlock(block *types.Block) da.Res // CheckBlockAvailability queries DA layer to check data availability of block corresponding to given header. func (m *MockDataAvailabilityLayerClient) CheckBlockAvailability(header *types.Header) da.ResultCheckBlock { - m.mtx.Lock() - defer m.mtx.Unlock() - _, ok := m.Blocks[header.Hash()] - return da.ResultCheckBlock{DAResult: da.DAResult{Code: da.StatusSuccess}, DataAvailable: ok} + hash := header.Hash() + _, err := m.dalcKV.Get(hash[:]) + if err != nil { + return da.ResultCheckBlock{DAResult: da.DAResult{Code: da.StatusSuccess}, DataAvailable: false} + } + return da.ResultCheckBlock{DAResult: da.DAResult{Code: da.StatusSuccess}, DataAvailable: true} } // RetrieveBlock returns block at given height from data availability layer. func (m *MockDataAvailabilityLayerClient) RetrieveBlock(height uint64) da.ResultRetrieveBlock { - m.mtx.Lock() - defer m.mtx.Unlock() - hash, ok := m.BlockIndex[height] - if !ok { - return da.ResultRetrieveBlock{DAResult: da.DAResult{Code: da.StatusError}} + hash, err := m.dalcKV.Get(getKey(height)) + if err != nil { + return da.ResultRetrieveBlock{DAResult: da.DAResult{Code: da.StatusError, Message: err.Error()}} } - return da.ResultRetrieveBlock{DAResult: da.DAResult{Code: da.StatusSuccess}, Block: m.Blocks[hash]} + blob, err := m.dalcKV.Get(hash) + if err != nil { + return da.ResultRetrieveBlock{DAResult: da.DAResult{Code: da.StatusError, Message: err.Error()}} + } + + block := &types.Block{} + err = block.UnmarshalBinary(blob) + if err != nil { + return da.ResultRetrieveBlock{DAResult: da.DAResult{Code: da.StatusError, Message: err.Error()}} + } + + return da.ResultRetrieveBlock{DAResult: da.DAResult{Code: da.StatusSuccess}, Block: block} +} + +func getKey(height uint64) []byte { + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, height) + return b } diff --git a/node/integration_test.go b/node/integration_test.go index 905eb996fce..a41d986fcf3 100644 --- a/node/integration_test.go +++ b/node/integration_test.go @@ -3,15 +3,17 @@ package node import ( "context" "crypto/rand" - mockda "github.com/celestiaorg/optimint/da/mock" - "github.com/celestiaorg/optimint/p2p" - "github.com/stretchr/testify/assert" mrand "math/rand" "strconv" "strings" "testing" "time" + mockda "github.com/celestiaorg/optimint/da/mock" + "github.com/celestiaorg/optimint/p2p" + "github.com/celestiaorg/optimint/store" + "github.com/stretchr/testify/assert" + "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" "github.com/stretchr/testify/mock" @@ -154,7 +156,7 @@ func createNodes(num int, t *testing.T) ([]*Node, []*mocks.Application) { nodes := make([]*Node, num) apps := make([]*mocks.Application, num) dalc := &mockda.MockDataAvailabilityLayerClient{} - _ = dalc.Init(nil, nil, log.TestingLogger()) + _ = dalc.Init(nil, store.NewInMemoryKVStore(), log.TestingLogger()) _ = dalc.Start() nodes[0], apps[0] = createNode(0, true, dalc, keys, t) for i := 1; i < num; i++ { @@ -216,4 +218,3 @@ func createNode(n int, aggregator bool, dalc da.DataAvailabilityLayerClient, key return node, app } -