diff --git a/block/block.go b/block/block.go index 7aa4cd424..1015c3fba 100644 --- a/block/block.go +++ b/block/block.go @@ -121,7 +121,7 @@ func (m *Manager) applyBlock(block *types.Block, commit *types.Commit, blockMeta select { case m.pruningC <- retainHeight: default: - m.logger.Error("pruning channel full. skipping pruning", "retainHeight", retainHeight) + m.logger.Debug("pruning channel full. skipping pruning", "retainHeight", retainHeight) } } diff --git a/block/manager.go b/block/manager.go index c7daaeee4..3744dc8eb 100644 --- a/block/manager.go +++ b/block/manager.go @@ -80,7 +80,7 @@ type Manager struct { pruningC chan int64 // indexer - indexerService *txindex.IndexerService + IndexerService *txindex.IndexerService // used to fetch blocks from DA. Sequencer will only fetch batches in case it requires to re-sync (in case of rollback). Full-node will fetch batches for syncing and validation. Retriever da.BatchRetriever @@ -160,7 +160,7 @@ func NewManager( Executor: exec, Sequencers: types.NewSequencerSet(), SLClient: settlementClient, - indexerService: indexerService, + IndexerService: indexerService, logger: logger.With("module", "block_manager"), blockCache: &Cache{ cache: make(map[uint64]types.CachedBlock), diff --git a/block/manager_test.go b/block/manager_test.go index 47e48e6d3..5316b8237 100644 --- a/block/manager_test.go +++ b/block/manager_test.go @@ -76,6 +76,7 @@ func TestInitialState(t *testing.T) { GossipSubCacheSize: 50, BootstrapRetryTime: 30 * time.Second, BlockSyncRequestIntervalTime: 30 * time.Second, + BlockSyncEnabled: true, }, privKey, "TestChain", emptyStore, pubsubServer, datastore.NewMapDatastore(), logger) assert.NoError(err) assert.NotNil(p2pClient) diff --git a/block/pruning.go b/block/pruning.go index 8781cc1ed..401492c25 100644 --- a/block/pruning.go +++ b/block/pruning.go @@ -2,38 +2,30 @@ package block import ( "context" - "fmt" ) -// PruneBlocks prune all block related data from dymint store up to (but not including) retainHeight. It returns the number of blocks pruned, used for testing. -func (m *Manager) PruneBlocks(retainHeight uint64) (uint64, error) { - // prune blocks from blocksync store - err := m.P2PClient.RemoveBlocks(context.Background(), m.State.BaseHeight, retainHeight) - if err != nil { - m.logger.Error("pruning blocksync store", "retain_height", retainHeight, "err", err) - } - - // prune blocks from indexer store - err = m.indexerService.Prune(m.State.BaseHeight, retainHeight) - if err != nil { - m.logger.Error("pruning indexer", "retain_height", retainHeight, "err", err) - } - - // prune blocks from dymint store - pruned, err := m.Store.PruneStore(m.State.BaseHeight, retainHeight, m.logger) - if err != nil { - return 0, fmt.Errorf("prune block store: %w", err) +// Prune function prune all block related data from dymint store and blocksync store up to (but not including) retainHeight. +func (m *Manager) Prune(retainHeight uint64) { + // logging pruning result + logResult := func(err error, source string, retainHeight uint64, pruned uint64) { + if err != nil { + m.logger.Error("pruning", "from", source, "retain height", retainHeight, "err", err) + } else { + m.logger.Debug("pruned", "from", source, "retain height", retainHeight, "pruned", pruned) + } } - m.State.BaseHeight = retainHeight - _, err = m.Store.SaveState(m.State, nil) - if err != nil { - return 0, fmt.Errorf("save state: %w", err) - } + // prune blocks from blocksync store + pruned, err := m.P2PClient.RemoveBlocks(context.Background(), retainHeight) + logResult(err, "blocksync", retainHeight, pruned) - m.logger.Info("pruned blocks", "pruned", pruned, "retain_height", retainHeight) + // prune indexed block and txs and associated events + pruned, err = m.IndexerService.Prune(retainHeight, m.Store) + logResult(err, "indexer", retainHeight, pruned) - return pruned, nil + // prune blocks from dymint store + pruned, err = m.Store.PruneStore(retainHeight, m.logger) + logResult(err, "dymint store", retainHeight, pruned) } func (m *Manager) PruningLoop(ctx context.Context) error { @@ -48,12 +40,7 @@ func (m *Manager) PruningLoop(ctx context.Context) error { } else { // do not delete anything that is not validated yet pruningHeight = min(m.SettlementValidator.NextValidationHeight(), uint64(retainHeight)) } - - _, err := m.PruneBlocks(pruningHeight) - if err != nil { - m.logger.Error("pruning blocks", "retainHeight", retainHeight, "err", err) - } - + m.Prune(pruningHeight) } } } diff --git a/block/pruning_test.go b/block/pruning_test.go index 64f80b084..3f2c742ff 100644 --- a/block/pruning_test.go +++ b/block/pruning_test.go @@ -65,9 +65,8 @@ func TestPruningRetainHeight(t *testing.T) { require.NoError(err) } validRetainHeight := manager.NextHeightToSubmit() // the max possible valid retain height - for i := validRetainHeight; i < manager.State.Height(); i++ { - expectedPruned := validRetainHeight - manager.State.BaseHeight - pruned, err := manager.PruneBlocks(i) + + validatePruning := func(i uint64, expectedPruned uint64, pruned uint64, err error) { if i <= validRetainHeight { require.NoError(err) assert.Equal(t, expectedPruned, pruned) @@ -75,5 +74,17 @@ func TestPruningRetainHeight(t *testing.T) { require.Error(gerrc.ErrInvalidArgument) } } + for i := validRetainHeight; i < manager.State.Height(); i++ { + + baseHeight := uint64(1) + expectedPruned := validRetainHeight - baseHeight + + pruned, err := manager.Store.PruneStore(validRetainHeight, log.NewNopLogger()) + validatePruning(i, expectedPruned, pruned, err) + + pruned, err = manager.P2PClient.RemoveBlocks(ctx, validRetainHeight) + validatePruning(i, expectedPruned, pruned, err) + + } } diff --git a/block/state.go b/block/state.go index 2f29e845d..e1e850825 100644 --- a/block/state.go +++ b/block/state.go @@ -61,7 +61,6 @@ func NewStateFromGenesis(genDoc *tmtypes.GenesisDoc) (*types.State, error) { ChainID: genDoc.ChainID, InitialHeight: uint64(genDoc.InitialHeight), - BaseHeight: uint64(genDoc.InitialHeight), ConsensusParams: *genDoc.ConsensusParams, } s.SetHeight(0) diff --git a/indexers/blockindexer/kv/kv.go b/indexers/blockindexer/kv/kv.go index 65164ec36..736bd7895 100644 --- a/indexers/blockindexer/kv/kv.go +++ b/indexers/blockindexer/kv/kv.go @@ -528,19 +528,12 @@ func (idx *BlockerIndexer) indexEvents(batch store.KVBatch, events []abci.Event, } func (idx *BlockerIndexer) Prune(from, to uint64, logger log.Logger) (uint64, error) { - if from <= 0 { - return 0, fmt.Errorf("from height must be greater than 0: %w", gerrc.ErrInvalidArgument) - } - - if to <= from { - return 0, fmt.Errorf("to height must be greater than from height: to: %d: from: %d: %w", to, from, gerrc.ErrInvalidArgument) - } - blocksPruned, err := idx.pruneBlocks(from, to, logger) - return blocksPruned, err + return idx.pruneBlocks(from, to, logger) } func (idx *BlockerIndexer) pruneBlocks(from, to uint64, logger log.Logger) (uint64, error) { pruned := uint64(0) + toFlush := uint64(0) batch := idx.store.NewBatch() defer batch.Discard() @@ -555,7 +548,7 @@ func (idx *BlockerIndexer) pruneBlocks(from, to uint64, logger log.Logger) (uint for h := int64(from); h < int64(to); h++ { ok, err := idx.Has(h) if err != nil { - logger.Debug("pruning block indexer checking height", "err", err) + logger.Debug("pruning block indexer checking height", "height", h, "err", err) continue } if !ok { @@ -563,27 +556,35 @@ func (idx *BlockerIndexer) pruneBlocks(from, to uint64, logger log.Logger) (uint } key, err := heightKey(h) if err != nil { - logger.Debug("pruning block indexer getting height key", "err", err) + logger.Debug("pruning block indexer getting height key", "height", h, "err", err) continue } if err := batch.Delete(key); err != nil { - logger.Debug("pruning block indexer deleting height key", "err", err) + logger.Debug("pruning block indexer deleting height key", "height", h, "err", err) continue } - if err := idx.pruneEvents(h, batch); err != nil { - logger.Debug("pruning block indexer events", "err", err) + + pruned++ + + prunedEvents, err := idx.pruneEvents(h, logger, batch) + if err != nil { + logger.Debug("pruning block indexer events", "height", h, "err", err) continue } - pruned++ + pruned += prunedEvents + + toFlush += pruned // flush every 1000 blocks to avoid batches becoming too large - if pruned%1000 == 0 && pruned > 0 { + if toFlush > 1000 { err := flush(batch, h) if err != nil { return 0, err } batch.Discard() batch = idx.store.NewBatch() + + toFlush = 0 } } @@ -595,27 +596,32 @@ func (idx *BlockerIndexer) pruneBlocks(from, to uint64, logger log.Logger) (uint return pruned, nil } -func (idx *BlockerIndexer) pruneEvents(height int64, batch store.KVBatch) error { +func (idx *BlockerIndexer) pruneEvents(height int64, logger log.Logger, batch store.KVBatch) (uint64, error) { + pruned := uint64(0) + eventKey, err := eventHeightKey(height) if err != nil { - return err + return pruned, err } keysList, err := idx.store.Get(eventKey) if err != nil { - return err + return pruned, err } eventKeys := &dymint.EventKeys{} err = eventKeys.Unmarshal(keysList) if err != nil { - return err + return pruned, err } for _, key := range eventKeys.Keys { err := batch.Delete(key) if err != nil { - return err + logger.Error("pruning block indexer iterate events", "height", height, "err", err) + continue } + pruned++ + } - return nil + return pruned, nil } func (idx *BlockerIndexer) addEventKeys(height int64, beginKeys *dymint.EventKeys, endKeys *dymint.EventKeys, batch store.KVBatch) error { diff --git a/indexers/blockindexer/kv/kv_test.go b/indexers/blockindexer/kv/kv_test.go index b7a8a17f6..ff017616e 100644 --- a/indexers/blockindexer/kv/kv_test.go +++ b/indexers/blockindexer/kv/kv_test.go @@ -154,12 +154,17 @@ func TestBlockIndexerPruning(t *testing.T) { indexer := blockidxkv.New(prefixStore) numBlocks := uint64(100) + numEvents := uint64(0) // index block data for i := uint64(1); i <= numBlocks; i++ { + beginBlock := getBeginBlock() + endBlock := getEndBlock() + numEvents += uint64(len(beginBlock.Events)) + numEvents += uint64(len(endBlock.Events)) indexer.Index(types.EventDataNewBlockHeader{ Header: types.Header{Height: int64(i)}, - ResultBeginBlock: getBeginBlock(), - ResultEndBlock: getEndBlock(), + ResultBeginBlock: beginBlock, + ResultEndBlock: endBlock, }) } @@ -173,7 +178,7 @@ func TestBlockIndexerPruning(t *testing.T) { // prune indexer for all heights pruned, err := indexer.Prune(1, numBlocks+1, log.NewNopLogger()) require.NoError(t, err) - require.Equal(t, numBlocks, pruned) + require.Equal(t, numBlocks+numEvents, pruned) // check the query returns empty results, err = indexer.Search(context.Background(), q) diff --git a/indexers/txindex/indexer.go b/indexers/txindex/indexer.go index 694b90d86..281c1dccc 100644 --- a/indexers/txindex/indexer.go +++ b/indexers/txindex/indexer.go @@ -32,13 +32,15 @@ type TxIndexer interface { // Batch groups together multiple Index operations to be performed at the same time. // NOTE: Batch is NOT thread-safe and must not be modified after starting its execution. type Batch struct { - Ops []*abci.TxResult + Height int64 + Ops []*abci.TxResult } // NewBatch creates a new Batch. -func NewBatch(n int64) *Batch { +func NewBatch(n int64, height int64) *Batch { return &Batch{ - Ops: make([]*abci.TxResult, n), + Height: height, + Ops: make([]*abci.TxResult, n), } } diff --git a/indexers/txindex/indexer_service.go b/indexers/txindex/indexer_service.go index 88a79b8ae..e5ec76696 100644 --- a/indexers/txindex/indexer_service.go +++ b/indexers/txindex/indexer_service.go @@ -2,8 +2,11 @@ package txindex import ( "context" + "errors" indexer "github.com/dymensionxyz/dymint/indexers/blockindexer" + "github.com/dymensionxyz/dymint/store" + "github.com/dymensionxyz/gerr-cosmos/gerrc" "github.com/tendermint/tendermint/libs/service" "github.com/tendermint/tendermint/types" ) @@ -59,7 +62,7 @@ func (is *IndexerService) OnStart() error { msg := <-blockHeadersSub.Out() eventDataHeader, _ := msg.Data().(types.EventDataNewBlockHeader) height := eventDataHeader.Header.Height - batch := NewBatch(eventDataHeader.NumTxs) + batch := NewBatch(eventDataHeader.NumTxs, height) for i := int64(0); i < eventDataHeader.NumTxs; i++ { msg2 := <-txsSub.Out() @@ -99,14 +102,33 @@ func (is *IndexerService) OnStop() { } // Prune removes tx and blocks indexed up to (but not including) a height. -func (is *IndexerService) Prune(from, to uint64) error { - _, err := is.blockIdxr.Prune(from, to, is.Logger) +func (is *IndexerService) Prune(to uint64, s store.Store) (uint64, error) { + // load indexer base height + indexerBaseHeight, err := s.LoadIndexerBaseHeight() + + if errors.Is(err, gerrc.ErrNotFound) { + is.Logger.Error("load indexer base height", "err", err) + } else if err != nil { + return 0, err + } + + // prune indexed blocks + blockPruned, err := is.blockIdxr.Prune(indexerBaseHeight, to, is.Logger) if err != nil { - return err + return blockPruned, err } - _, err = is.txIdxr.Prune(from, to, is.Logger) + + // prune indexes txs + txPruned, err := is.txIdxr.Prune(indexerBaseHeight, to, is.Logger) if err != nil { - return err + return txPruned, err } - return nil + + // store indexer base height + err = s.SaveIndexerBaseHeight(to) + if err != nil { + is.Logger.Error("saving indexer base height", "err", err) + } + + return blockPruned + txPruned, nil } diff --git a/indexers/txindex/indexer_service_test.go b/indexers/txindex/indexer_service_test.go index abd281605..9c08b3d63 100644 --- a/indexers/txindex/indexer_service_test.go +++ b/indexers/txindex/indexer_service_test.go @@ -48,19 +48,45 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) { NumTxs: int64(2), }) require.NoError(t, err) + txResult1 := &abci.TxResult{ Height: 1, Index: uint32(0), Tx: types.Tx("foo"), - Result: abci.ResponseDeliverTx{Code: 0}, + Result: abci.ResponseDeliverTx{ + Code: 0, + Events: []abci.Event{{Type: "test_event", + Attributes: []abci.EventAttribute{ + { + Key: []byte("foo"), + Value: []byte("100"), + Index: true, + }, + }, + }, + }, + }, } + err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult1}) require.NoError(t, err) txResult2 := &abci.TxResult{ Height: 1, Index: uint32(1), Tx: types.Tx("bar"), - Result: abci.ResponseDeliverTx{Code: 0}, + Result: abci.ResponseDeliverTx{ + Code: 0, + Events: []abci.Event{{Type: "test_event", + Attributes: []abci.EventAttribute{ + { + Key: []byte("foo"), + Value: []byte("100"), + Index: true, + }, + }, + }, + }, + }, } err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult2}) require.NoError(t, err) @@ -84,9 +110,10 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) { expectedBlocksPruned := uint64(1) require.Equal(t, expectedBlocksPruned, blocksPruned) - txPruned, err := txIndexer.Prune(1, 2, log.NewNopLogger()) + pruned, err := txIndexer.Prune(1, 2, log.NewNopLogger()) require.NoError(t, err) - expectedTxPruned := uint64(2) - require.Equal(t, expectedTxPruned, txPruned) + // 2 indexed tx + indexed 2 events = 4 pruned + expectedPruned := uint64(4) + require.Equal(t, expectedPruned, pruned) } diff --git a/indexers/txindex/kv/kv.go b/indexers/txindex/kv/kv.go index d9b54508f..1dd3cbf96 100644 --- a/indexers/txindex/kv/kv.go +++ b/indexers/txindex/kv/kv.go @@ -73,6 +73,7 @@ func (txi *TxIndex) AddBatch(b *txindex.Batch) error { storeBatch := txi.store.NewBatch() defer storeBatch.Discard() + var eventKeysBatch dmtypes.EventKeys for _, result := range b.Ops { hash := types.Tx(result.Tx).Hash() @@ -81,12 +82,7 @@ func (txi *TxIndex) AddBatch(b *txindex.Batch) error { if err != nil { return err } - - err = txi.addEventKeys(result.Height, &eventKeys, storeBatch) - if err != nil { - return err - } - + eventKeysBatch.Keys = append(eventKeysBatch.Keys, eventKeys.Keys...) // index by height (always) err = storeBatch.Set(keyForHeight(result), hash) if err != nil { @@ -104,6 +100,11 @@ func (txi *TxIndex) AddBatch(b *txindex.Batch) error { } } + err := txi.addEventKeys(b.Height, &eventKeysBatch, storeBatch) + if err != nil { + return err + } + return storeBatch.Commit() } @@ -570,15 +571,16 @@ LOOP: } func (txi *TxIndex) Prune(from, to uint64, logger log.Logger) (uint64, error) { - pruned, err := txi.pruneTxs(from, to) + pruned, err := txi.pruneTxsAndEvents(from, to, logger) if err != nil { return 0, err } return pruned, nil } -func (txi *TxIndex) pruneTxs(from, to uint64) (uint64, error) { +func (txi *TxIndex) pruneTxsAndEvents(from, to uint64, logger log.Logger) (uint64, error) { pruned := uint64(0) + toFlush := uint64(0) batch := txi.store.NewBatch() defer batch.Discard() @@ -592,30 +594,44 @@ func (txi *TxIndex) pruneTxs(from, to uint64) (uint64, error) { for h := from; h < to; h++ { + // first all events are pruned associated to the same height + prunedEvents, err := txi.pruneEvents(h, batch) + if err != nil { + logger.Error("pruning txs indexer events by height", "height", h, "error", err) + continue + } + pruned += prunedEvents + + // then all txs indexed are iterated by height it := txi.store.PrefixIterator(prefixForHeight(int64(h))) defer it.Discard() + // and deleted all indexed (by hash and by keyheight) for ; it.Valid(); it.Next() { if err := batch.Delete(it.Key()); err != nil { + logger.Error("pruning txs indexer event key", "height", h, "error", err) continue } + if err := batch.Delete(it.Value()); err != nil { - continue - } - if err := txi.pruneEvents(h, batch); err != nil { + logger.Error("pruning txs indexer event val", "height", h, "error", err) continue } pruned++ - // flush every 1000 txs to avoid batches becoming too large - if pruned%1000 == 0 && pruned > 0 { - err := flush(batch, int64(h)) - if err != nil { - return 0, err - } - batch.Discard() - batch = txi.store.NewBatch() + } + + toFlush += pruned + // flush every 1000 txs to avoid batches becoming too large + if toFlush > 1000 { + err := flush(batch, int64(h)) + if err != nil { + return 0, err } + batch.Discard() + batch = txi.store.NewBatch() + toFlush = 0 } + } err := flush(batch, int64(to)) @@ -626,27 +642,29 @@ func (txi *TxIndex) pruneTxs(from, to uint64) (uint64, error) { return pruned, nil } -func (txi *TxIndex) pruneEvents(height uint64, batch store.KVBatch) error { +func (txi *TxIndex) pruneEvents(height uint64, batch store.KVBatch) (uint64, error) { + pruned := uint64(0) eventKey, err := eventHeightKey(int64(height)) if err != nil { - return err + return pruned, err } keysList, err := txi.store.Get(eventKey) if err != nil { - return err + return pruned, err } eventKeys := &dymint.EventKeys{} err = eventKeys.Unmarshal(keysList) if err != nil { - return err + return pruned, err } for _, key := range eventKeys.Keys { err := batch.Delete(key) if err != nil { - return err + return pruned, err } + pruned++ } - return nil + return pruned, nil } func (txi *TxIndex) addEventKeys(height int64, eventKeys *dymint.EventKeys, batch store.KVBatch) error { @@ -686,10 +704,9 @@ func keyForEvent(key string, value []byte, result *abci.TxResult) []byte { } func keyForHeight(result *abci.TxResult) []byte { - return []byte(fmt.Sprintf("%s/%d/%d/%d", + return []byte(fmt.Sprintf("%s/%d/%d", tmtypes.TxHeightKey, result.Height, - result.Height, result.Index, )) } diff --git a/indexers/txindex/kv/kv_test.go b/indexers/txindex/kv/kv_test.go index 60caf7f54..abba1995d 100644 --- a/indexers/txindex/kv/kv_test.go +++ b/indexers/txindex/kv/kv_test.go @@ -36,7 +36,7 @@ func TestTxIndex(t *testing.T) { } hash := tx.Hash() - batch := txindex.NewBatch(1) + batch := txindex.NewBatch(1, txResult.Height) if err := batch.Add(txResult); err != nil { t.Error(err) } @@ -321,7 +321,7 @@ func TestTxIndexerPruning(t *testing.T) { numBlocks := uint64(100) txsWithEvents := 0 - + numEvents := uint64(0) // index tx event data for i := uint64(1); i <= numBlocks; i++ { events := getNEvents(rand.Intn(10)) @@ -331,6 +331,7 @@ func TestTxIndexerPruning(t *testing.T) { if len(events) > 0 { txsWithEvents++ } + numEvents += uint64(len(events)) } q := query.MustParse("account.number = 1") @@ -342,7 +343,7 @@ func TestTxIndexerPruning(t *testing.T) { // prune indexer for all heights pruned, err := indexer.Prune(1, numBlocks+1, log.NewNopLogger()) require.NoError(t, err) - require.Equal(t, uint64(numBlocks), pruned) + require.Equal(t, numBlocks+numEvents, pruned) // check the query returns empty results, err = indexer.Search(context.Background(), q) @@ -428,7 +429,7 @@ func benchmarkTxIndex(txsCount int64, b *testing.B) { require.NoError(b, err) indexer := NewTxIndex(store) - batch := txindex.NewBatch(txsCount) + batch := txindex.NewBatch(txsCount, int64(0)) txIndex := uint32(0) for i := int64(0); i < txsCount; i++ { tx := tmrand.Bytes(250) diff --git a/p2p/block_sync.go b/p2p/block_sync.go index e7bda4bf2..f8be1e2c0 100644 --- a/p2p/block_sync.go +++ b/p2p/block_sync.go @@ -113,5 +113,5 @@ func (blocksync *BlockSync) LoadBlock(ctx context.Context, cid cid.Cid) (BlockDa // RemoveBlock removes the block from the DAGservice. func (blocksync *BlockSync) DeleteBlock(ctx context.Context, cid cid.Cid) error { - return blocksync.dsrv.Remove(ctx, cid) + return blocksync.dsrv.DeleteBlock(ctx, cid) } diff --git a/p2p/block_sync_dag.go b/p2p/block_sync_dag.go index 18d78dca3..d9df4d440 100644 --- a/p2p/block_sync_dag.go +++ b/p2p/block_sync_dag.go @@ -112,6 +112,23 @@ func (bsDagService *BlockSyncDagService) LoadBlock(ctx context.Context, cid cid. return data, nil } +func (bsDagService *BlockSyncDagService) DeleteBlock(ctx context.Context, cid cid.Cid) error { + // first it gets the root node + root, err := bsDagService.Get(ctx, cid) + if err != nil { + return err + } + + // then it iterates all the cids to remove them from the block store + for _, l := range root.Links() { + err := bsDagService.Remove(ctx, l.Cid) + if err != nil { + return err + } + } + return nil +} + // dagReader is used to read the DAG (all the block chunks) from the root (IPLD) node func dagReader(root ipld.Node, ds ipld.DAGService) (io.Reader, error) { ctx := context.Background() diff --git a/p2p/client.go b/p2p/client.go index 640c50a29..e33986e92 100644 --- a/p2p/client.go +++ b/p2p/client.go @@ -205,6 +205,14 @@ func (c *Client) SaveBlock(ctx context.Context, height uint64, blockBytes []byte if !c.conf.BlockSyncEnabled { return nil } + _, err := c.store.LoadBlockSyncBaseHeight() + if err != nil { + err = c.store.SaveBlockSyncBaseHeight(height) + if err != nil { + return err + } + } + cid, err := c.blocksync.SaveBlock(ctx, blockBytes) if err != nil { return fmt.Errorf("blocksync add block: %w", err) @@ -221,13 +229,14 @@ func (c *Client) SaveBlock(ctx context.Context, height uint64, blockBytes []byte } // RemoveBlocks is used to prune blocks from the block sync datastore. -func (c *Client) RemoveBlocks(ctx context.Context, from, to uint64) error { - if from <= 0 { - return fmt.Errorf("from height must be greater than 0: %w", gerrc.ErrInvalidArgument) - } +func (c *Client) RemoveBlocks(ctx context.Context, to uint64) (uint64, error) { + prunedBlocks := uint64(0) - if to <= from { - return fmt.Errorf("to height must be greater than from height: to: %d: from: %d: %w", to, from, gerrc.ErrInvalidArgument) + from, err := c.store.LoadBlockSyncBaseHeight() + if errors.Is(err, gerrc.ErrNotFound) { + c.logger.Error("load blocksync base height", "err", err) + } else if err != nil { + return prunedBlocks, err } for h := from; h < to; h++ { @@ -242,9 +251,22 @@ func (c *Client) RemoveBlocks(ctx context.Context, from, to uint64) error { err = c.blocksync.DeleteBlock(ctx, cid) if err != nil { c.logger.Error("remove blocksync block", "height", h, "err", err) + continue } + err = c.store.RemoveBlockCid(h) + if err != nil { + c.logger.Error("remove cid from dymint store", "height", h, "cid", cid, "err", err) + continue + } + prunedBlocks++ } - return nil + + err = c.store.SaveBlockSyncBaseHeight(to) + if err != nil { + return prunedBlocks, err + } + + return prunedBlocks, nil } // AdvertiseBlockIdToDHT is used to advertise the identifier (cid) for a specific block height to the DHT, using a PutValue operation @@ -623,7 +645,11 @@ func (c *Client) advertiseBlockSyncCids(ctx context.Context) { if err != nil { return } - for h := state.BaseHeight; h <= state.Height(); h++ { + baseHeight, err := c.store.LoadBaseHeight() + if err != nil { + return + } + for h := baseHeight; h <= state.Height(); h++ { id, err := c.store.LoadBlockCid(h) if err != nil || id == cid.Undef { diff --git a/proto/types/dymint/state.proto b/proto/types/dymint/state.proto index 18c9e4b79..48f243594 100755 --- a/proto/types/dymint/state.proto +++ b/proto/types/dymint/state.proto @@ -40,7 +40,7 @@ message State { bytes app_hash = 15; uint64 last_store_height = 16 [(gogoproto.customname) = "LastStoreHeight"]; - uint64 base_height = 17; + reserved 17; RollappParams rollapp_params = 18 [(gogoproto.nullable) = false]; diff --git a/rpc/client/client.go b/rpc/client/client.go index 389aebebe..339e6b95a 100644 --- a/rpc/client/client.go +++ b/rpc/client/client.go @@ -26,6 +26,7 @@ import ( "github.com/dymensionxyz/dymint/node" "github.com/dymensionxyz/dymint/types" "github.com/dymensionxyz/dymint/version" + "github.com/dymensionxyz/gerr-cosmos/gerrc" ) const ( @@ -325,8 +326,15 @@ func (c *Client) GenesisChunked(context context.Context, id uint) (*ctypes.Resul func (c *Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) { const limit int64 = 20 - minHeight, maxHeight, err := filterMinMax( - int64(c.node.BlockManager.State.BaseHeight), + baseHeight, err := c.node.BlockManager.Store.LoadBaseHeight() + if err != nil && !errors.Is(err, gerrc.ErrNotFound) { + return nil, err + } + if errors.Is(err, gerrc.ErrNotFound) { + baseHeight = 1 + } + minHeight, maxHeight, err = filterMinMax( + int64(baseHeight), int64(c.node.GetBlockManagerHeight()), minHeight, maxHeight, diff --git a/store/pruning.go b/store/pruning.go index 93b2c3f11..e1cccc827 100644 --- a/store/pruning.go +++ b/store/pruning.go @@ -1,106 +1,73 @@ package store import ( + "errors" "fmt" - "github.com/dymensionxyz/gerr-cosmos/gerrc" - "github.com/dymensionxyz/dymint/types" + "github.com/dymensionxyz/gerr-cosmos/gerrc" ) -// PruneStore removes store items up to (but not including) a height. It returns number of blocks pruned. -func (s *DefaultStore) PruneStore(from, to uint64, logger types.Logger) (uint64, error) { - if from <= 0 { - return 0, fmt.Errorf("from height must be greater than 0: %w", gerrc.ErrInvalidArgument) - } - - if to <= from { - return 0, fmt.Errorf("to height must be greater than from height: to: %d: from: %d: %w", to, from, gerrc.ErrInvalidArgument) - } - - prunedBlocks, err := s.pruneBlocks(from, to, logger) - if err != nil { - logger.Error("pruning blocks", "from", from, "to", to, "blocks pruned", prunedBlocks, "err", err) - } - - prunedResponses, err := s.pruneResponses(from, to, logger) - if err != nil { - logger.Error("pruning responses", "from", from, "to", to, "responses pruned", prunedResponses, "err", err) - } - - prunedCids, err := s.pruneCids(from, to, logger) - if err != nil { - logger.Error("pruning block sync identifiers", "from", from, "to", to, "cids pruned", prunedCids, "err", err) +// PruneStore removes blocks up to (but not including) a height. It returns number of blocks pruned. +func (s *DefaultStore) PruneStore(to uint64, logger types.Logger) (uint64, error) { + pruned := uint64(0) + from, err := s.LoadBaseHeight() + if errors.Is(err, gerrc.ErrNotFound) { + logger.Error("load store base height", "err", err) + } else if err != nil { + return pruned, err } - - prunedDRS, err := s.pruneDRSVersion(from, to, logger) + pruned, err = s.pruneHeights(from, to, logger) if err != nil { - logger.Error("pruning drs version", "from", from, "to", to, "drs pruned", prunedDRS, "err", err) + return pruned, fmt.Errorf("pruning blocks. from: %d to: %d: err:%w", from, to, err) } - prunedProposers, err := s.pruneProposers(from, to, logger) + err = s.SaveBaseHeight(to) if err != nil { - logger.Error("pruning block sync identifiers", "from", from, "to", to, "proposers pruned", prunedProposers, "err", err) + logger.Error("saving base height", "error", err) } - - return prunedBlocks, nil + return pruned, nil } -// pruneBlocks prunes all store entries that are stored along blocks (blocks,commit and block hash) -func (s *DefaultStore) pruneBlocks(from, to uint64, logger types.Logger) (uint64, error) { +// pruneHeights prunes all store entries that are stored along blocks (blocks,commit,proposer, etc) +func (s *DefaultStore) pruneHeights(from, to uint64, logger types.Logger) (uint64, error) { pruneBlocks := func(batch KVBatch, height uint64) error { + + if err := batch.Delete(getResponsesKey(height)); err != nil { + logger.Error("delete responses", "error", err) + } + if err := batch.Delete(getDRSVersionKey(height)); err != nil { + logger.Error("delete drs", "error", err) + } + if err := batch.Delete(getProposerKey(height)); err != nil { + logger.Error("delete proposer", "error", err) + } + hash, err := s.loadHashFromIndex(height) if err != nil { return err } if err := batch.Delete(getBlockKey(hash)); err != nil { - return err + logger.Error("delete block", "error", err) } if err := batch.Delete(getCommitKey(hash)); err != nil { - return err + logger.Error("delete commit", "error", err) } + if err := batch.Delete(getIndexKey(height)); err != nil { - return err + logger.Error("delete hash index", "error", err) } - return nil - } - prunedBlocks, err := s.pruneHeights(from, to, pruneBlocks, logger) - return prunedBlocks, err -} - -// pruneResponses prunes block execution responses from store -func (s *DefaultStore) pruneResponses(from, to uint64, logger types.Logger) (uint64, error) { - pruneResponses := func(batch KVBatch, height uint64) error { - return batch.Delete(getResponsesKey(height)) - } - - prunedResponses, err := s.pruneHeights(from, to, pruneResponses, logger) - return prunedResponses, err -} - -// pruneCids prunes content identifiers from store -func (s *DefaultStore) pruneCids(from, to uint64, logger types.Logger) (uint64, error) { - pruneCids := func(batch KVBatch, height uint64) error { - return batch.Delete(getCidKey(height)) + return nil } - prunedCids, err := s.pruneHeights(from, to, pruneCids, logger) - return prunedCids, err -} -// pruneDRSVersion prunes drs version info from store -func (s *DefaultStore) pruneDRSVersion(from, to uint64, logger types.Logger) (uint64, error) { - pruneDRS := func(batch KVBatch, height uint64) error { - return batch.Delete(getDRSVersionKey(height)) - } - prunedSequencers, err := s.pruneHeights(from, to, pruneDRS, logger) - return prunedSequencers, err + pruned, err := s.prune(from, to, pruneBlocks, logger) + return pruned, err } -// pruneHeights is the common function for all pruning that iterates through all heights and prunes according to the pruning function set -func (s *DefaultStore) pruneHeights(from, to uint64, prune func(batch KVBatch, height uint64) error, logger types.Logger) (uint64, error) { +// prune is the function that iterates through all heights and prunes according to the pruning function set +func (s *DefaultStore) prune(from, to uint64, prune func(batch KVBatch, height uint64) error, logger types.Logger) (uint64, error) { pruned := uint64(0) - batch := s.db.NewBatch() defer batch.Discard() @@ -138,12 +105,3 @@ func (s *DefaultStore) pruneHeights(from, to uint64, prune func(batch KVBatch, h return pruned, nil } - -// pruneSequencers prunes proposer from store -func (s *DefaultStore) pruneProposers(from, to uint64, logger types.Logger) (uint64, error) { - pruneProposers := func(batch KVBatch, height uint64) error { - return batch.Delete(getProposerKey(height)) - } - prunedSequencers, err := s.pruneHeights(from, to, pruneProposers, logger) - return prunedSequencers, err -} diff --git a/store/pruning_test.go b/store/pruning_test.go index 9628dd5aa..e3b0bca79 100644 --- a/store/pruning_test.go +++ b/store/pruning_test.go @@ -19,11 +19,11 @@ func TestStorePruning(t *testing.T) { t.Parallel() cases := []struct { - name string - blocks []*types.Block - from uint64 - to uint64 - shouldError bool + name string + blocks []*types.Block + from uint64 + to uint64 + pruned uint64 }{ {"blocks with pruning", []*types.Block{ testutil.GetRandomBlock(1, 0), @@ -31,33 +31,33 @@ func TestStorePruning(t *testing.T) { testutil.GetRandomBlock(3, 0), testutil.GetRandomBlock(4, 0), testutil.GetRandomBlock(5, 0), - }, 3, 5, false}, + }, 3, 5, 2}, {"blocks out of order", []*types.Block{ testutil.GetRandomBlock(2, 0), testutil.GetRandomBlock(3, 0), testutil.GetRandomBlock(1, 0), testutil.GetRandomBlock(5, 0), - }, 3, 5, false}, + }, 3, 5, 1}, {"with a gap", []*types.Block{ testutil.GetRandomBlock(1, 0), testutil.GetRandomBlock(9, 0), testutil.GetRandomBlock(10, 0), - }, 3, 5, false}, + }, 3, 5, 0}, {"pruning height 0", []*types.Block{ testutil.GetRandomBlock(1, 0), testutil.GetRandomBlock(2, 0), testutil.GetRandomBlock(3, 0), - }, 0, 1, true}, + }, 0, 1, 0}, {"pruning same height", []*types.Block{ testutil.GetRandomBlock(1, 0), testutil.GetRandomBlock(2, 0), testutil.GetRandomBlock(3, 0), - }, 3, 3, true}, + }, 3, 3, 0}, {"to height exceeds actual block cnt", []*types.Block{ testutil.GetRandomBlock(1, 0), testutil.GetRandomBlock(2, 0), testutil.GetRandomBlock(3, 0), - }, 2, 5, false}, // it shouldn't error it should just no-op + }, 2, 5, 2}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { @@ -70,6 +70,7 @@ func TestStorePruning(t *testing.T) { savedCidHeights := make(map[uint64]bool) savedDRSHeights := make(map[uint64]bool) + bstore.SaveBaseHeight(c.from) for _, block := range c.blocks { _, err := bstore.SaveBlock(block, &types.Commit{Height: block.Header.Height}, nil) @@ -144,12 +145,8 @@ func TestStorePruning(t *testing.T) { assert.NoError(err) } - _, err := bstore.PruneStore(c.from, c.to, log.NewNopLogger()) - if c.shouldError { - assert.Error(err) - return - } - + pruned, err := bstore.PruneStore(c.to, log.NewNopLogger()) + assert.Equal(c.pruned, pruned) assert.NoError(err) // Validate only blocks in the range are pruned @@ -193,17 +190,6 @@ func TestStorePruning(t *testing.T) { } } - // Validate only block cids in the range are pruned - for k := range savedCidHeights { - if k >= c.from && k < c.to { // k < c.to is the exclusion test - _, err = bstore.LoadBlockCid(k) - assert.Error(err, "Block cid at height %d should be pruned", k) - } else { - _, err = bstore.LoadBlockCid(k) - assert.NoError(err) - } - } - // Validate only block drs in the range are pruned for k := range savedDRSHeights { if k >= c.from && k < c.to { // k < c.to is the exclusion test diff --git a/store/store.go b/store/store.go index 8c5ce4df4..4bc01db1b 100644 --- a/store/store.go +++ b/store/store.go @@ -14,16 +14,19 @@ import ( ) var ( - blockPrefix = [1]byte{1} - indexPrefix = [1]byte{2} - commitPrefix = [1]byte{3} - statePrefix = [1]byte{4} - responsesPrefix = [1]byte{5} - proposerPrefix = [1]byte{6} - cidPrefix = [1]byte{7} - sourcePrefix = [1]byte{8} - validatedHeightPrefix = [1]byte{9} - drsVersionPrefix = [1]byte{10} + blockPrefix = [1]byte{1} + indexPrefix = [1]byte{2} + commitPrefix = [1]byte{3} + statePrefix = [1]byte{4} + responsesPrefix = [1]byte{5} + proposerPrefix = [1]byte{6} + cidPrefix = [1]byte{7} + sourcePrefix = [1]byte{8} + validatedHeightPrefix = [1]byte{9} + baseHeightPrefix = [1]byte{10} + blocksyncBaseHeightPrefix = [1]byte{11} + indexerBaseHeightPrefix = [1]byte{12} + drsVersionPrefix = [1]byte{13} ) // DefaultStore is a default store implementation. @@ -317,6 +320,11 @@ func (s *DefaultStore) LoadValidationHeight() (uint64, error) { return binary.LittleEndian.Uint64(b), nil } +func (s *DefaultStore) RemoveBlockCid(height uint64) error { + err := s.db.Delete(getCidKey(height)) + return err +} + func (s *DefaultStore) LoadDRSVersion(height uint64) (uint32, error) { b, err := s.db.Get(getDRSVersionKey(height)) if err != nil { @@ -335,6 +343,48 @@ func (s *DefaultStore) SaveDRSVersion(height uint64, version uint32, batch KVBat return batch, err } +func (s *DefaultStore) LoadBaseHeight() (uint64, error) { + b, err := s.db.Get(getBaseHeightKey()) + if err != nil { + return 0, err + } + return binary.LittleEndian.Uint64(b), nil +} + +func (s *DefaultStore) SaveBaseHeight(height uint64) error { + b := make([]byte, 8) + binary.LittleEndian.PutUint64(b, height) + return s.db.Set(getBaseHeightKey(), b) +} + +func (s *DefaultStore) LoadBlockSyncBaseHeight() (uint64, error) { + b, err := s.db.Get(getBlockSyncBaseHeightKey()) + if err != nil { + return 0, err + } + return binary.LittleEndian.Uint64(b), nil +} + +func (s *DefaultStore) SaveBlockSyncBaseHeight(height uint64) error { + b := make([]byte, 8) + binary.LittleEndian.PutUint64(b, height) + return s.db.Set(getBlockSyncBaseHeightKey(), b) +} + +func (s *DefaultStore) LoadIndexerBaseHeight() (uint64, error) { + b, err := s.db.Get(getIndexerBaseHeightKey()) + if err != nil { + return 0, err + } + return binary.LittleEndian.Uint64(b), nil +} + +func (s *DefaultStore) SaveIndexerBaseHeight(height uint64) error { + b := make([]byte, 8) + binary.LittleEndian.PutUint64(b, height) + return s.db.Set(getIndexerBaseHeightKey(), b) +} + func getBlockKey(hash [32]byte) []byte { return append(blockPrefix[:], hash[:]...) } @@ -386,3 +436,15 @@ func getProposerKey(height uint64) []byte { binary.BigEndian.PutUint64(buf, height) return append(proposerPrefix[:], buf[:]...) } + +func getBaseHeightKey() []byte { + return baseHeightPrefix[:] +} + +func getBlockSyncBaseHeightKey() []byte { + return blocksyncBaseHeightPrefix[:] +} + +func getIndexerBaseHeightKey() []byte { + return indexerBaseHeightPrefix[:] +} diff --git a/store/storeIface.go b/store/storeIface.go index 8a2bf7166..5f49031be 100644 --- a/store/storeIface.go +++ b/store/storeIface.go @@ -72,7 +72,7 @@ type Store interface { LoadProposer(height uint64) (types.Sequencer, error) - PruneStore(from, to uint64, logger types.Logger) (uint64, error) + PruneStore(to uint64, logger types.Logger) (uint64, error) SaveBlockCid(height uint64, cid cid.Cid, batch KVBatch) (KVBatch, error) @@ -90,5 +90,19 @@ type Store interface { SaveDRSVersion(height uint64, version uint32, batch KVBatch) (KVBatch, error) + RemoveBlockCid(height uint64) error + + LoadBaseHeight() (uint64, error) + + SaveBaseHeight(height uint64) error + + LoadBlockSyncBaseHeight() (uint64, error) + + SaveBlockSyncBaseHeight(height uint64) error + + LoadIndexerBaseHeight() (uint64, error) + + SaveIndexerBaseHeight(height uint64) error + Close() error } diff --git a/test/loadtime/cmd/report/main.go b/test/loadtime/cmd/report/main.go index c981a65e4..6b132ae5d 100644 --- a/test/loadtime/cmd/report/main.go +++ b/test/loadtime/cmd/report/main.go @@ -52,7 +52,7 @@ func newBlockStore(kvstore store.KV, baseHeight uint64) *BlockStore { } return &BlockStore{ DefaultStore: store, - base: state.BaseHeight, + base: baseHeight, height: state.Height(), } } diff --git a/testutil/block.go b/testutil/block.go index 58d13eb97..0080bab7a 100644 --- a/testutil/block.go +++ b/testutil/block.go @@ -101,6 +101,7 @@ func GetManagerWithProposerKey(conf config.BlockManagerConfig, proposerKey crypt GossipSubCacheSize: 50, BootstrapRetryTime: 30 * time.Second, BlockSyncRequestIntervalTime: 30 * time.Second, + BlockSyncEnabled: true, }, p2pKey, "TestChain", managerStore, pubsubServer, datastore.NewMapDatastore(), logger) if err != nil { return nil, err diff --git a/testutil/types.go b/testutil/types.go index ecf540037..2b6d6e8ca 100644 --- a/testutil/types.go +++ b/testutil/types.go @@ -326,7 +326,6 @@ func GenerateStateWithSequencer(initialHeight int64, lastBlockHeight int64, pubk s := &types.State{ ChainID: "test-chain", InitialHeight: uint64(initialHeight), - BaseHeight: uint64(initialHeight), AppHash: [32]byte{}, LastResultsHash: GetEmptyLastResultsHash(), Version: tmstate.Version{ diff --git a/types/pb/dymint/state.pb.go b/types/pb/dymint/state.pb.go index 0e95298c2..16f5b2548 100644 --- a/types/pb/dymint/state.pb.go +++ b/types/pb/dymint/state.pb.go @@ -43,7 +43,6 @@ type State struct { LastResultsHash []byte `protobuf:"bytes,14,opt,name=last_results_hash,json=lastResultsHash,proto3" json:"last_results_hash,omitempty"` AppHash []byte `protobuf:"bytes,15,opt,name=app_hash,json=appHash,proto3" json:"app_hash,omitempty"` LastStoreHeight uint64 `protobuf:"varint,16,opt,name=last_store_height,json=lastStoreHeight,proto3" json:"last_store_height,omitempty"` - BaseHeight uint64 `protobuf:"varint,17,opt,name=base_height,json=baseHeight,proto3" json:"base_height,omitempty"` RollappParams RollappParams `protobuf:"bytes,18,opt,name=rollapp_params,json=rollappParams,proto3" json:"rollapp_params"` LastHeaderHash []byte `protobuf:"bytes,19,opt,name=last_header_hash,json=lastHeaderHash,proto3" json:"last_header_hash,omitempty"` // Proposer is a sequencer that acts as a proposer. Can be nil if no proposer is set. @@ -168,13 +167,6 @@ func (m *State) GetLastStoreHeight() uint64 { return 0 } -func (m *State) GetBaseHeight() uint64 { - if m != nil { - return m.BaseHeight - } - return 0 -} - func (m *State) GetRollappParams() RollappParams { if m != nil { return m.RollappParams @@ -259,51 +251,50 @@ func init() { func init() { proto.RegisterFile("types/dymint/state.proto", fileDescriptor_4b679420add07272) } var fileDescriptor_4b679420add07272 = []byte{ - // 695 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x94, 0xcf, 0x4e, 0xdb, 0x4a, - 0x14, 0xc6, 0xe3, 0x10, 0x88, 0x33, 0x21, 0x89, 0x31, 0x5c, 0xc9, 0x70, 0x25, 0x27, 0x70, 0x75, - 0xaf, 0xa2, 0x2b, 0xd5, 0x91, 0xca, 0x03, 0xb4, 0x32, 0x2c, 0x48, 0xc4, 0xa2, 0x9a, 0x54, 0x2c, - 0xba, 0xb1, 0xc6, 0xf6, 0xd4, 0xb6, 0xea, 0x78, 0xdc, 0x99, 0x09, 0x2a, 0x7d, 0x81, 0x6e, 0x79, - 0x2c, 0x96, 0x2c, 0xbb, 0xa2, 0x55, 0x78, 0x91, 0x6a, 0xfe, 0xd8, 0x24, 0x8a, 0x58, 0x25, 0xf3, - 0x9d, 0xdf, 0x7c, 0x73, 0xce, 0x9c, 0x33, 0x06, 0x0e, 0xbf, 0x2b, 0x31, 0x9b, 0xc4, 0x77, 0x8b, - 0xac, 0xe0, 0x13, 0xc6, 0x11, 0xc7, 0x5e, 0x49, 0x09, 0x27, 0xf6, 0x9e, 0xd2, 0x4e, 0x8e, 0x12, - 0x92, 0x10, 0x29, 0x4d, 0xc4, 0x3f, 0x15, 0x3d, 0x19, 0x26, 0x84, 0x24, 0x39, 0x9e, 0xc8, 0x55, - 0xb8, 0xfc, 0x3c, 0xe1, 0xd9, 0x02, 0x33, 0x8e, 0x16, 0xa5, 0x06, 0x4e, 0x95, 0x31, 0xc7, 0x45, - 0x8c, 0xa9, 0x34, 0x47, 0x61, 0x94, 0x4d, 0xa4, 0xaa, 0x91, 0xb3, 0x2d, 0x44, 0x0b, 0x6b, 0xcc, - 0x7f, 0xaf, 0x30, 0xb7, 0x28, 0xcf, 0x62, 0xc4, 0x09, 0xd5, 0xdc, 0x3f, 0xaf, 0x70, 0x25, 0xa2, - 0x68, 0xf1, 0xfa, 0x81, 0xb2, 0xe0, 0x8d, 0x03, 0x8f, 0x37, 0x2e, 0x44, 0xfd, 0xa8, 0xd0, 0xd9, - 0x8f, 0x36, 0xd8, 0x9d, 0x8b, 0x0d, 0xf6, 0x39, 0x68, 0xdf, 0x62, 0xca, 0x32, 0x52, 0x38, 0xc6, - 0xc8, 0x18, 0x77, 0xdf, 0x1e, 0x7b, 0x2f, 0xa6, 0x9e, 0xba, 0xc5, 0x1b, 0x05, 0xc0, 0x8a, 0xb4, - 0x8f, 0x81, 0x19, 0xa5, 0x28, 0x2b, 0x82, 0x2c, 0x76, 0x9a, 0x23, 0x63, 0xdc, 0x81, 0x6d, 0xb9, - 0x9e, 0xc6, 0xf6, 0xbf, 0xa0, 0x9f, 0x15, 0x19, 0xcf, 0x50, 0x1e, 0xa4, 0x38, 0x4b, 0x52, 0xee, - 0xec, 0x8c, 0x8c, 0xf1, 0x0e, 0xec, 0x69, 0xf5, 0x4a, 0x8a, 0xf6, 0xff, 0xe0, 0x20, 0x47, 0x8c, - 0x07, 0x61, 0x4e, 0xa2, 0x2f, 0x15, 0xd9, 0x92, 0xe4, 0x40, 0x04, 0x7c, 0xa1, 0x6b, 0x16, 0x82, - 0xde, 0x1a, 0x9b, 0xc5, 0xce, 0xee, 0x76, 0xa2, 0xaa, 0x6e, 0xb9, 0x6b, 0x7a, 0xe9, 0x1f, 0x3e, - 0x3c, 0x0d, 0x1b, 0xab, 0xa7, 0x61, 0xf7, 0xba, 0xb2, 0x9a, 0x5e, 0xc2, 0x6e, 0xed, 0x3b, 0x8d, - 0xed, 0x6b, 0x30, 0x58, 0xf3, 0x14, 0x1d, 0x77, 0xf6, 0xa4, 0xeb, 0x89, 0xa7, 0xc6, 0xc1, 0xab, - 0xc6, 0xc1, 0xfb, 0x58, 0x8d, 0x83, 0x6f, 0x0a, 0xdb, 0xfb, 0x5f, 0x43, 0x03, 0xf6, 0x6a, 0x2f, - 0x11, 0xb5, 0x7d, 0x00, 0xea, 0x2e, 0x32, 0xa7, 0x23, 0x8d, 0xdc, 0xed, 0xf4, 0x6e, 0x2a, 0x66, - 0x8e, 0xb9, 0xdf, 0x74, 0x0c, 0xb8, 0xb6, 0xcb, 0xbe, 0x00, 0xae, 0xcc, 0x48, 0xdd, 0x45, 0xf0, - 0x12, 0x09, 0xa2, 0x14, 0x15, 0x09, 0x8e, 0x9d, 0xae, 0xbc, 0x9e, 0xbf, 0x05, 0xa5, 0x6e, 0xa6, - 0xf6, 0x63, 0x17, 0x0a, 0xb1, 0x21, 0xb0, 0x22, 0x52, 0x30, 0x5c, 0xb0, 0x25, 0x0b, 0xd4, 0xc0, - 0x38, 0xfb, 0x32, 0x9d, 0xd3, 0xed, 0x74, 0x2e, 0x2a, 0xf2, 0x83, 0x04, 0xfd, 0x96, 0x28, 0x0f, - 0x0e, 0xa2, 0x4d, 0xb9, 0x6e, 0x15, 0xc5, 0x6c, 0x99, 0x73, 0x16, 0xa4, 0x88, 0xa5, 0x4e, 0x7f, - 0x64, 0x8c, 0xf7, 0x55, 0xab, 0xa0, 0xd2, 0xaf, 0x10, 0x4b, 0xc5, 0x60, 0xa0, 0xb2, 0x54, 0xc8, - 0x40, 0x22, 0x6d, 0x54, 0x96, 0x32, 0xf4, 0x4e, 0xdb, 0x30, 0x4e, 0x28, 0xae, 0x3a, 0x6e, 0x8d, - 0x8c, 0x71, 0xcb, 0x3f, 0x5c, 0x3d, 0x0d, 0x07, 0xa2, 0x55, 0x73, 0x11, 0x53, 0xb5, 0x29, 0xef, - 0x35, 0xc1, 0x1e, 0x82, 0x6e, 0x88, 0x58, 0xbd, 0xf5, 0x40, 0x6c, 0x85, 0x40, 0x48, 0x1a, 0xf0, - 0x41, 0x9f, 0x92, 0x3c, 0x17, 0x09, 0xe8, 0xd2, 0x6d, 0x59, 0xfa, 0x5f, 0x9e, 0x9e, 0x7d, 0xa8, - 0xa2, 0x1b, 0xe5, 0xf6, 0xe8, 0xba, 0x68, 0x8f, 0x81, 0xa5, 0xbb, 0x80, 0x62, 0x4c, 0x55, 0x21, - 0x87, 0xb2, 0x90, 0xbe, 0xba, 0x77, 0x21, 0xcb, 0x7a, 0xde, 0x00, 0xb3, 0xa4, 0xa4, 0x24, 0x0c, - 0x53, 0xe7, 0x48, 0x9e, 0x73, 0x50, 0x9d, 0x33, 0xc7, 0x5f, 0x97, 0xb8, 0x88, 0x30, 0x85, 0x35, - 0x32, 0x6b, 0x99, 0x6d, 0xcb, 0x9c, 0xb5, 0x4c, 0xd3, 0xea, 0xcc, 0x5a, 0x26, 0xb0, 0xba, 0xb3, - 0x96, 0xd9, 0xb3, 0xfa, 0x67, 0xef, 0x41, 0x6f, 0x23, 0x2d, 0xbb, 0x0f, 0x9a, 0x31, 0x92, 0x6f, - 0xb1, 0x03, 0x9b, 0x31, 0x12, 0x65, 0xc7, 0x94, 0x05, 0xd5, 0x23, 0x15, 0xcf, 0xad, 0x07, 0x41, - 0x4c, 0x99, 0x7e, 0x95, 0xfe, 0xd5, 0xc3, 0xca, 0x35, 0x1e, 0x57, 0xae, 0xf1, 0x7b, 0xe5, 0x1a, - 0xf7, 0xcf, 0x6e, 0xe3, 0xf1, 0xd9, 0x6d, 0xfc, 0x7c, 0x76, 0x1b, 0x9f, 0xbc, 0x24, 0xe3, 0xe9, - 0x32, 0xf4, 0x22, 0xb2, 0x10, 0xcf, 0x1f, 0x17, 0x82, 0xff, 0x76, 0xf7, 0xbd, 0xfa, 0x24, 0xe8, - 0xef, 0x4a, 0xa8, 0xd7, 0xe1, 0x9e, 0x9c, 0xf9, 0xf3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x24, - 0xb8, 0xfb, 0x6f, 0x4a, 0x05, 0x00, 0x00, + // 686 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x94, 0xd1, 0x4e, 0xdb, 0x3c, + 0x14, 0xc7, 0x9b, 0x12, 0xda, 0xd4, 0xa5, 0x6d, 0x30, 0x7c, 0x52, 0xe0, 0x93, 0xd2, 0xc2, 0xb4, + 0xa9, 0x9a, 0xb4, 0x54, 0x1a, 0x0f, 0xb0, 0x29, 0x70, 0x41, 0x2b, 0x2e, 0x26, 0x77, 0xe2, 0x62, + 0x37, 0x91, 0x9b, 0x78, 0x49, 0xb4, 0x34, 0xce, 0x6c, 0x17, 0x8d, 0x3d, 0x05, 0x8f, 0xc5, 0x25, + 0x97, 0xbb, 0x62, 0x53, 0xb9, 0xdd, 0x43, 0x4c, 0xb6, 0x93, 0xd2, 0xaa, 0xe2, 0x0a, 0xf2, 0x3f, + 0x3f, 0xff, 0x7d, 0xce, 0xf1, 0x39, 0x05, 0x8e, 0xb8, 0x2d, 0x08, 0x1f, 0x45, 0xb7, 0xf3, 0x34, + 0x17, 0x23, 0x2e, 0xb0, 0x20, 0x5e, 0xc1, 0xa8, 0xa0, 0xb0, 0xa1, 0xb5, 0xe3, 0xc3, 0x98, 0xc6, + 0x54, 0x49, 0x23, 0xf9, 0x9f, 0x8e, 0x1e, 0xf7, 0x63, 0x4a, 0xe3, 0x8c, 0x8c, 0xd4, 0xd7, 0x6c, + 0xf1, 0x75, 0x24, 0xd2, 0x39, 0xe1, 0x02, 0xcf, 0x8b, 0x12, 0x38, 0xd1, 0xc6, 0x82, 0xe4, 0x11, + 0x61, 0xca, 0x1c, 0xcf, 0xc2, 0x74, 0xa4, 0xd4, 0x12, 0x39, 0xdd, 0x42, 0x4a, 0x61, 0x8d, 0x79, + 0xf3, 0x02, 0x73, 0x83, 0xb3, 0x34, 0xc2, 0x82, 0xb2, 0x92, 0x7b, 0xf5, 0x02, 0x57, 0x60, 0x86, + 0xe7, 0x2f, 0x5f, 0xa8, 0x0a, 0xde, 0xb8, 0xf0, 0x68, 0xa3, 0x21, 0xfa, 0x8f, 0x0e, 0x9d, 0xfe, + 0x6d, 0x80, 0xdd, 0xa9, 0x3c, 0x00, 0xcf, 0x40, 0xf3, 0x86, 0x30, 0x9e, 0xd2, 0xdc, 0x31, 0x06, + 0xc6, 0xb0, 0xfd, 0xfe, 0xc8, 0x7b, 0x36, 0xf5, 0x74, 0x17, 0xaf, 0x35, 0x80, 0x2a, 0x12, 0x1e, + 0x01, 0x2b, 0x4c, 0x70, 0x9a, 0x07, 0x69, 0xe4, 0xd4, 0x07, 0xc6, 0xb0, 0x85, 0x9a, 0xea, 0x7b, + 0x1c, 0xc1, 0xd7, 0xa0, 0x9b, 0xe6, 0xa9, 0x48, 0x71, 0x16, 0x24, 0x24, 0x8d, 0x13, 0xe1, 0xec, + 0x0c, 0x8c, 0xe1, 0x0e, 0xea, 0x94, 0xea, 0xa5, 0x12, 0xe1, 0x5b, 0xb0, 0x9f, 0x61, 0x2e, 0x82, + 0x59, 0x46, 0xc3, 0x6f, 0x15, 0x69, 0x2a, 0xb2, 0x27, 0x03, 0xbe, 0xd4, 0x4b, 0x16, 0x81, 0xce, + 0x1a, 0x9b, 0x46, 0xce, 0xee, 0x76, 0xa2, 0xba, 0x6e, 0x75, 0x6a, 0x7c, 0xe1, 0x1f, 0xdc, 0x3f, + 0xf6, 0x6b, 0xcb, 0xc7, 0x7e, 0xfb, 0xaa, 0xb2, 0x1a, 0x5f, 0xa0, 0xf6, 0xca, 0x77, 0x1c, 0xc1, + 0x2b, 0xd0, 0x5b, 0xf3, 0x94, 0x2f, 0xee, 0x34, 0x94, 0xeb, 0xb1, 0xa7, 0xc7, 0xc1, 0xab, 0xc6, + 0xc1, 0xfb, 0x5c, 0x8d, 0x83, 0x6f, 0x49, 0xdb, 0xbb, 0xdf, 0x7d, 0x03, 0x75, 0x56, 0x5e, 0x32, + 0x0a, 0x7d, 0x00, 0x56, 0xaf, 0xc8, 0x9d, 0x96, 0x32, 0x72, 0xb7, 0xd3, 0xbb, 0xae, 0x98, 0x29, + 0x11, 0x7e, 0xdd, 0x31, 0xd0, 0xda, 0x29, 0x78, 0x0e, 0x5c, 0x95, 0x91, 0xee, 0x45, 0xf0, 0x1c, + 0x09, 0xc2, 0x04, 0xe7, 0x31, 0x89, 0x9c, 0xb6, 0x6a, 0xcf, 0xff, 0x92, 0xd2, 0x9d, 0x59, 0xf9, + 0xf1, 0x73, 0x8d, 0x40, 0x04, 0xec, 0x90, 0xe6, 0x9c, 0xe4, 0x7c, 0xc1, 0x03, 0x3d, 0x30, 0xce, + 0x9e, 0x4a, 0xe7, 0x64, 0x3b, 0x9d, 0xf3, 0x8a, 0xfc, 0xa4, 0x40, 0xdf, 0x94, 0xe5, 0xa1, 0x5e, + 0xb8, 0x29, 0xaf, 0x9e, 0x8a, 0x11, 0xbe, 0xc8, 0x04, 0x0f, 0x12, 0xcc, 0x13, 0xa7, 0x3b, 0x30, + 0x86, 0x7b, 0xfa, 0xa9, 0x90, 0xd6, 0x2f, 0x31, 0x4f, 0xe4, 0x60, 0xe0, 0xa2, 0xd0, 0x48, 0x4f, + 0x21, 0x4d, 0x5c, 0x14, 0x2a, 0xf4, 0xa1, 0xb4, 0xe1, 0x82, 0x32, 0x52, 0xbd, 0xb8, 0x3d, 0x30, + 0x86, 0xa6, 0x7f, 0xb0, 0x7c, 0xec, 0xf7, 0xe4, 0x53, 0x4d, 0x65, 0x4c, 0xd7, 0xa6, 0xbd, 0xd7, + 0x04, 0xe8, 0x83, 0x2e, 0xa3, 0x59, 0x26, 0xfd, 0xcb, 0xca, 0xa0, 0xaa, 0xec, 0x3f, 0xaf, 0x1c, + 0x6d, 0xa4, 0xa3, 0x1b, 0xd5, 0x74, 0xd8, 0xba, 0x08, 0x87, 0xc0, 0x2e, 0x9b, 0x8c, 0x23, 0xc2, + 0x74, 0x9e, 0x07, 0x2a, 0xcf, 0xae, 0x6e, 0xab, 0x94, 0x55, 0xba, 0xef, 0x80, 0x55, 0x30, 0x5a, + 0x50, 0x4e, 0x98, 0x73, 0xa8, 0xee, 0xd9, 0xaf, 0xee, 0x99, 0x92, 0xef, 0x0b, 0x92, 0x87, 0x84, + 0xa1, 0x15, 0x32, 0x31, 0xad, 0xa6, 0x6d, 0x4d, 0x4c, 0xcb, 0xb2, 0x5b, 0x13, 0xd3, 0x02, 0x76, + 0x7b, 0x62, 0x5a, 0x1d, 0xbb, 0x3b, 0x31, 0xad, 0x7d, 0x1b, 0x9e, 0x7e, 0x04, 0x9d, 0x8d, 0xe4, + 0x60, 0x17, 0xd4, 0x23, 0xac, 0x16, 0xae, 0x85, 0xea, 0x11, 0x86, 0x7d, 0xd0, 0x8e, 0x18, 0x0f, + 0xaa, 0x4d, 0x94, 0x3b, 0xd5, 0x41, 0x20, 0x62, 0xbc, 0x5c, 0x3d, 0xff, 0xf2, 0x7e, 0xe9, 0x1a, + 0x0f, 0x4b, 0xd7, 0xf8, 0xb3, 0x74, 0x8d, 0xbb, 0x27, 0xb7, 0xf6, 0xf0, 0xe4, 0xd6, 0x7e, 0x3d, + 0xb9, 0xb5, 0x2f, 0x5e, 0x9c, 0x8a, 0x64, 0x31, 0xf3, 0x42, 0x3a, 0x97, 0x3b, 0x4e, 0x72, 0xc9, + 0xff, 0xb8, 0xfd, 0x59, 0xed, 0x7d, 0xf9, 0xe3, 0x31, 0x2b, 0xbf, 0x67, 0x0d, 0x35, 0xd8, 0x67, + 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xf4, 0x93, 0x2f, 0x96, 0x2f, 0x05, 0x00, 0x00, } func (m *State) Marshal() (dAtA []byte, err error) { @@ -361,13 +352,6 @@ func (m *State) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x1 i-- dAtA[i] = 0x92 - if m.BaseHeight != 0 { - i = encodeVarintState(dAtA, i, uint64(m.BaseHeight)) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x88 - } if m.LastStoreHeight != 0 { i = encodeVarintState(dAtA, i, uint64(m.LastStoreHeight)) i-- @@ -556,9 +540,6 @@ func (m *State) Size() (n int) { if m.LastStoreHeight != 0 { n += 2 + sovState(uint64(m.LastStoreHeight)) } - if m.BaseHeight != 0 { - n += 2 + sovState(uint64(m.BaseHeight)) - } l = m.RollappParams.Size() n += 2 + l + sovState(uint64(l)) l = len(m.LastHeaderHash) @@ -970,25 +951,6 @@ func (m *State) Unmarshal(dAtA []byte) error { break } } - case 17: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BaseHeight", wireType) - } - m.BaseHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.BaseHeight |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } case 18: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field RollappParams", wireType) diff --git a/types/serialization.go b/types/serialization.go index 729fc3faf..e90fc5785 100644 --- a/types/serialization.go +++ b/types/serialization.go @@ -265,7 +265,6 @@ func (s *State) ToProto() (*pb.State, error) { ChainId: s.ChainID, InitialHeight: int64(s.InitialHeight), LastBlockHeight: int64(s.Height()), - BaseHeight: s.BaseHeight, ConsensusParams: s.ConsensusParams, LastResultsHash: s.LastResultsHash[:], LastHeaderHash: s.LastHeaderHash[:], @@ -281,7 +280,6 @@ func (s *State) FromProto(other *pb.State) error { s.ChainID = other.ChainId s.InitialHeight = uint64(other.InitialHeight) s.SetHeight(uint64(other.LastBlockHeight)) - s.BaseHeight = other.BaseHeight if other.Proposer != nil { proposer, err := SequencerFromProto(other.Proposer) diff --git a/types/state.go b/types/state.go index 6257b79fc..529cccaa0 100644 --- a/types/state.go +++ b/types/state.go @@ -25,9 +25,6 @@ type State struct { // LastBlockHeight=0 at genesis (ie. block(H=0) does not exist) LastBlockHeight atomic.Uint64 - // BaseHeight is the height of the first block we have in store after pruning. - BaseHeight uint64 - // Proposer is a sequencer that acts as a proposer. Can be nil if no proposer is set. Proposer atomic.Pointer[Sequencer]