diff --git a/da/mock/mock.go b/da/mock/mock.go index 1c706f5588..0fad324215 100644 --- a/da/mock/mock.go +++ b/da/mock/mock.go @@ -1,6 +1,8 @@ package mock import ( + "encoding/binary" + "github.com/celestiaorg/optimint/da" "github.com/celestiaorg/optimint/log" "github.com/celestiaorg/optimint/store" @@ -11,19 +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 + 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 { +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 } @@ -46,8 +45,19 @@ func (m *MockDataAvailabilityLayerClient) SubmitBlock(block *types.Block) da.Res 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{ @@ -59,12 +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 { - _, 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 { - hash := m.BlockIndex[height] - return da.ResultRetrieveBlock{DAResult: da.DAResult{Code: da.StatusSuccess}, Block: m.Blocks[hash]} + hash, err := m.dalcKV.Get(getKey(height)) + if err != nil { + return da.ResultRetrieveBlock{DAResult: da.DAResult{Code: da.StatusError, Message: err.Error()}} + } + 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/da/mock/mock_test.go b/da/mock/mock_test.go index 79e1862c90..64a2101873 100644 --- a/da/mock/mock_test.go +++ b/da/mock/mock_test.go @@ -9,15 +9,17 @@ import ( "github.com/celestiaorg/optimint/da" "github.com/celestiaorg/optimint/log/test" + "github.com/celestiaorg/optimint/store" "github.com/celestiaorg/optimint/types" ) func TestLifecycle(t *testing.T) { var da da.DataAvailabilityLayerClient = &MockDataAvailabilityLayerClient{} + dalcKV := store.NewInMemoryKVStore() require := require.New(t) - err := da.Init([]byte{}, nil, &test.TestLogger{T: t}) + err := da.Init([]byte{}, dalcKV, &test.TestLogger{T: t}) require.NoError(err) err = da.Start() @@ -29,11 +31,12 @@ func TestLifecycle(t *testing.T) { func TestMockDALC(t *testing.T) { var dalc da.DataAvailabilityLayerClient = &MockDataAvailabilityLayerClient{} + dalcKV := store.NewInMemoryKVStore() require := require.New(t) assert := assert.New(t) - err := dalc.Init([]byte{}, nil, &test.TestLogger{T: t}) + err := dalc.Init([]byte{}, dalcKV, &test.TestLogger{T: t}) require.NoError(err) err = dalc.Start() @@ -69,10 +72,12 @@ func TestRetrieve(t *testing.T) { var dalc da.DataAvailabilityLayerClient = mock var retriever da.BlockRetriever = mock + dalcKV := store.NewInMemoryKVStore() + require := require.New(t) assert := assert.New(t) - err := dalc.Init([]byte{}, nil, &test.TestLogger{T: t}) + err := dalc.Init([]byte{}, dalcKV, &test.TestLogger{T: t}) require.NoError(err) err = dalc.Start() @@ -109,6 +114,13 @@ func getRandomBlock(height uint64, nTxs int) *types.Block { block.Data.IntermediateStateRoots.RawRootsList[i] = getRandomBytes(32) } + // TODO(https://github.com/celestiaorg/optimint/issues/143) + // This is a hack to get around equality checks on serialization round trips + if nTxs == 0 { + block.Data.Txs = nil + block.Data.IntermediateStateRoots.RawRootsList = nil + } + return block }