diff --git a/block/components.go b/block/components.go index bd29f92440..0b7996623f 100644 --- a/block/components.go +++ b/block/components.go @@ -35,17 +35,6 @@ type Components struct { errorCh chan error } -// GetLastState returns the current blockchain state -func (bc *Components) GetLastState() types.State { - if bc.Executor != nil { - return bc.Executor.GetLastState() - } - if bc.Syncer != nil { - return bc.Syncer.GetLastState() - } - return types.State{} -} - // Start starts all components and monitors for critical errors. // It is blocking and returns when the context is cancelled or an error occurs func (bc *Components) Start(ctx context.Context) error { diff --git a/block/components_test.go b/block/components_test.go index c288f5322c..e8ae8a2a12 100644 --- a/block/components_test.go +++ b/block/components_test.go @@ -52,18 +52,6 @@ func TestBlockComponents_ExecutionClientFailure_StopsNode(t *testing.T) { assert.Contains(t, err.Error(), "execution client connection lost") } -func TestBlockComponents_GetLastState(t *testing.T) { - // Test that GetLastState works correctly for different component types - - t.Run("Empty state", func(t *testing.T) { - // When neither is present, return empty state - bc := &Components{} - - result := bc.GetLastState() - assert.Equal(t, uint64(0), result.LastBlockHeight) - }) -} - func TestBlockComponents_StartStop_Lifecycle(t *testing.T) { // Simple lifecycle test without creating full components bc := &Components{ diff --git a/block/internal/executing/executor.go b/block/internal/executing/executor.go index 263d590815..f376a0cb0d 100644 --- a/block/internal/executing/executor.go +++ b/block/internal/executing/executor.go @@ -151,14 +151,6 @@ func (e *Executor) Stop() error { return nil } -// GetLastState returns the current state. -func (e *Executor) GetLastState() types.State { - state := e.getLastState() - state.AppHash = bytes.Clone(state.AppHash) - - return state -} - // getLastState returns the current state. // getLastState should never directly mutate. func (e *Executor) getLastState() types.State { diff --git a/block/internal/syncing/syncer.go b/block/internal/syncing/syncer.go index 08e177cd6f..909433eedc 100644 --- a/block/internal/syncing/syncer.go +++ b/block/internal/syncing/syncer.go @@ -226,18 +226,14 @@ func (s *Syncer) Stop() error { return nil } -// GetLastState returns the current state -func (s *Syncer) GetLastState() types.State { +// getLastState returns the current state +func (s *Syncer) getLastState() types.State { state := s.lastState.Load() if state == nil { return types.State{} } - stateCopy := *state - stateCopy.AppHash = bytes.Clone(state.AppHash) - stateCopy.LastHeaderHash = bytes.Clone(state.LastHeaderHash) - - return stateCopy + return *state } // SetLastState updates the current state @@ -532,7 +528,7 @@ func (s *Syncer) processHeightEvent(event *common.DAHeightEvent) { case errors.Is(err, errInvalidState): s.sendCriticalError(fmt.Errorf("invalid state detected (block-height %d, state-height %d) "+ "- block references do not match local state. Manual intervention required: %w", event.Header.Height(), - s.GetLastState().LastBlockHeight, err)) + s.getLastState().LastBlockHeight, err)) default: s.cache.SetPendingEvent(height, event) } @@ -577,7 +573,7 @@ func (s *Syncer) trySyncNextBlock(event *common.DAHeightEvent) error { header := event.Header data := event.Data nextHeight := event.Header.Height() - currentState := s.GetLastState() + currentState := s.getLastState() headerHash := header.Hash().String() s.logger.Info().Uint64("height", nextHeight).Msg("syncing block") diff --git a/block/internal/syncing/syncer_forced_inclusion_test.go b/block/internal/syncing/syncer_forced_inclusion_test.go index 77909fc2f0..0467ecc692 100644 --- a/block/internal/syncing/syncer_forced_inclusion_test.go +++ b/block/internal/syncing/syncer_forced_inclusion_test.go @@ -418,7 +418,7 @@ func TestVerifyForcedInclusionTxs_AllTransactionsIncluded(t *testing.T) { data := makeData(gen.ChainID, 1, 1) data.Txs[0] = types.Tx(dataBin) - currentState := s.GetLastState() + currentState := s.getLastState() currentState.DAHeight = 0 // Verify - should pass since all forced txs are included @@ -504,7 +504,7 @@ func TestVerifyForcedInclusionTxs_MissingTransactions(t *testing.T) { data.Txs[0] = types.Tx([]byte("regular_tx_1")) data.Txs[1] = types.Tx([]byte("regular_tx_2")) - currentState := s.GetLastState() + currentState := s.getLastState() currentState.DAHeight = 0 // Verify - should pass since forced tx blob may be legitimately deferred within the epoch @@ -620,7 +620,7 @@ func TestVerifyForcedInclusionTxs_PartiallyIncluded(t *testing.T) { data.Txs[1] = types.Tx([]byte("regular_tx")) // dataBin2 is missing - currentState := s.GetLastState() + currentState := s.getLastState() currentState.DAHeight = 0 // Verify - should pass since dataBin2 may be legitimately deferred within the epoch @@ -727,7 +727,7 @@ func TestVerifyForcedInclusionTxs_NoForcedTransactions(t *testing.T) { // Create block data data := makeData(gen.ChainID, 1, 2) - currentState := s.GetLastState() + currentState := s.getLastState() currentState.DAHeight = 0 // Verify - should pass since no forced txs to verify @@ -792,7 +792,7 @@ func TestVerifyForcedInclusionTxs_NamespaceNotConfigured(t *testing.T) { // Create block data data := makeData(gen.ChainID, 1, 2) - currentState := s.GetLastState() + currentState := s.getLastState() currentState.DAHeight = 0 // Verify - should pass since namespace not configured @@ -894,7 +894,7 @@ func TestVerifyForcedInclusionTxs_DeferralWithinEpoch(t *testing.T) { data1.Txs[0] = types.Tx(dataBin1) data1.Txs[1] = types.Tx([]byte("regular_tx_1")) - currentState := s.GetLastState() + currentState := s.getLastState() currentState.DAHeight = 104 // Verify - should pass since dataBin2 can be deferred within epoch @@ -1036,7 +1036,7 @@ func TestVerifyForcedInclusionTxs_MaliciousAfterEpochEnd(t *testing.T) { data1 := makeData(gen.ChainID, 1, 1) data1.Txs[0] = types.Tx([]byte("regular_tx_1")) - currentState := s.GetLastState() + currentState := s.getLastState() currentState.DAHeight = 102 // Verify - should pass, tx can be deferred within epoch @@ -1135,7 +1135,7 @@ func TestVerifyForcedInclusionTxs_SmoothingExceedsEpoch(t *testing.T) { data1.Txs[0] = types.Tx(dataBin1) data1.Txs[1] = types.Tx(dataBin2) - currentState := s.GetLastState() + currentState := s.getLastState() currentState.DAHeight = 102 // At epoch end err = s.verifyForcedInclusionTxs(currentState, data1) diff --git a/block/internal/syncing/syncer_test.go b/block/internal/syncing/syncer_test.go index 5c16da4435..65ce4d7e8a 100644 --- a/block/internal/syncing/syncer_test.go +++ b/block/internal/syncing/syncer_test.go @@ -134,19 +134,19 @@ func TestSyncer_validateBlock_DataHashMismatch(t *testing.T) { data := makeData(gen.ChainID, 1, 2) // non-empty _, header := makeSignedHeaderBytes(t, gen.ChainID, 1, addr, pub, signer, nil, data, nil) - err = s.validateBlock(s.GetLastState(), data, header) + err = s.validateBlock(s.getLastState(), data, header) require.NoError(t, err) // Create header and data with mismatched hash data = makeData(gen.ChainID, 1, 2) // non-empty _, header = makeSignedHeaderBytes(t, gen.ChainID, 1, addr, pub, signer, nil, nil, nil) - err = s.validateBlock(s.GetLastState(), data, header) + err = s.validateBlock(s.getLastState(), data, header) require.Error(t, err) // Create header and empty data data = makeData(gen.ChainID, 1, 0) // empty _, header = makeSignedHeaderBytes(t, gen.ChainID, 2, addr, pub, signer, nil, nil, nil) - err = s.validateBlock(s.GetLastState(), data, header) + err = s.validateBlock(s.getLastState(), data, header) require.Error(t, err) } @@ -185,7 +185,7 @@ func TestProcessHeightEvent_SyncsAndUpdatesState(t *testing.T) { // set a context for internal loops that expect it s.ctx = context.Background() // Create signed header & data for height 1 - lastState := s.GetLastState() + lastState := s.getLastState() data := makeData(gen.ChainID, 1, 0) _, hdr := makeSignedHeaderBytes(t, gen.ChainID, 1, addr, pub, signer, lastState.AppHash, data, nil) @@ -238,7 +238,7 @@ func TestSequentialBlockSync(t *testing.T) { s.ctx = context.Background() // Sync two consecutive blocks via processHeightEvent so ExecuteTxs is called and state stored - st0 := s.GetLastState() + st0 := s.getLastState() data1 := makeData(gen.ChainID, 1, 1) // non-empty _, hdr1 := makeSignedHeaderBytes(t, gen.ChainID, 1, addr, pub, signer, st0.AppHash, data1, st0.LastHeaderHash) // Expect ExecuteTxs call for height 1 @@ -629,7 +629,7 @@ func TestSyncer_InitializeState_CallsReplayer(t *testing.T) { require.NoError(t, err) // Verify state was initialized correctly - state := syncer.GetLastState() + state := syncer.getLastState() assert.Equal(t, storeHeight, state.LastBlockHeight) assert.Equal(t, gen.ChainID, state.ChainID) diff --git a/node/single_sequencer_integration_test.go b/node/single_sequencer_integration_test.go index 22b2fd4506..98dca09c71 100644 --- a/node/single_sequencer_integration_test.go +++ b/node/single_sequencer_integration_test.go @@ -219,7 +219,8 @@ func (s *FullNodeTestSuite) TestGenesisInitialization() { require := require.New(s.T()) // Verify genesis state - state := s.node.blockComponents.GetLastState() + state, err := s.node.Store.GetState(s.ctx) + require.NoError(err) require.Equal(s.node.genesis.InitialHeight, state.InitialHeight) require.Equal(s.node.genesis.ChainID, state.ChainID) }