66 "errors"
77 "fmt"
88 "sync"
9+ "sync/atomic"
910 "time"
1011
1112 "github.com/ipfs/go-datastore"
@@ -50,8 +51,7 @@ type Executor struct {
5051 options common.BlockOptions
5152
5253 // State management
53- lastState types.State
54- lastStateMtx * sync.RWMutex
54+ lastState * atomic.Pointer [types.State ]
5555
5656 // Channels for coordination
5757 txNotifyCh chan struct {}
@@ -112,7 +112,7 @@ func NewExecutor(
112112 headerBroadcaster : headerBroadcaster ,
113113 dataBroadcaster : dataBroadcaster ,
114114 options : options ,
115- lastStateMtx : & sync. RWMutex {},
115+ lastState : & atomic. Pointer [types. State ] {},
116116 txNotifyCh : make (chan struct {}, 1 ),
117117 errorCh : errorCh ,
118118 logger : logger .With ().Str ("component" , "executor" ).Logger (),
@@ -150,18 +150,29 @@ func (e *Executor) Stop() error {
150150 return nil
151151}
152152
153- // GetLastState returns the current state
153+ // GetLastState returns the current state.
154154func (e * Executor ) GetLastState () types.State {
155- e .lastStateMtx .RLock ()
156- defer e .lastStateMtx .RUnlock ()
157- return e .lastState
155+ state := e .getLastState ()
156+ state .AppHash = bytes .Clone (state .AppHash )
157+ state .LastResultsHash = bytes .Clone (state .LastResultsHash )
158+
159+ return state
160+ }
161+
162+ // getLastState returns the current state.
163+ // getLastState should never directly mutate.
164+ func (e * Executor ) getLastState () types.State {
165+ state := e .lastState .Load ()
166+ if state == nil {
167+ return types.State {}
168+ }
169+
170+ return * state
158171}
159172
160- // SetLastState updates the current state
161- func (e * Executor ) SetLastState (state types.State ) {
162- e .lastStateMtx .Lock ()
163- defer e .lastStateMtx .Unlock ()
164- e .lastState = state
173+ // setLastState updates the current state
174+ func (e * Executor ) setLastState (state types.State ) {
175+ e .lastState .Store (& state )
165176}
166177
167178// NotifyNewTransactions signals that new transactions are available
@@ -198,7 +209,7 @@ func (e *Executor) initializeState() error {
198209 }
199210 }
200211
201- e .SetLastState (state )
212+ e .setLastState (state )
202213
203214 // Set store height
204215 if err := e .store .SetHeight (e .ctx , state .LastBlockHeight ); err != nil {
@@ -218,7 +229,7 @@ func (e *Executor) executionLoop() {
218229
219230 var delay time.Duration
220231 initialHeight := e .genesis .InitialHeight
221- currentState := e .GetLastState ()
232+ currentState := e .getLastState ()
222233
223234 if currentState .LastBlockHeight < initialHeight {
224235 delay = time .Until (e .genesis .StartTime .Add (e .config .Node .BlockTime .Duration ))
@@ -291,7 +302,7 @@ func (e *Executor) produceBlock() error {
291302 }
292303 }()
293304
294- currentState := e .GetLastState ()
305+ currentState := e .getLastState ()
295306 newHeight := currentState .LastBlockHeight + 1
296307
297308 e .logger .Debug ().Uint64 ("height" , newHeight ).Msg ("producing block" )
@@ -429,7 +440,7 @@ func (e *Executor) retrieveBatch(ctx context.Context) (*BatchData, error) {
429440
430441// createBlock creates a new block from the given batch
431442func (e * Executor ) createBlock (ctx context.Context , height uint64 , batchData * BatchData ) (* types.SignedHeader , * types.Data , error ) {
432- currentState := e .GetLastState ()
443+ currentState := e .getLastState ()
433444 headerTime := uint64 (e .genesis .StartTime .UnixNano ())
434445
435446 // Get last block info
@@ -518,7 +529,7 @@ func (e *Executor) createBlock(ctx context.Context, height uint64, batchData *Ba
518529
519530// applyBlock applies the block to get the new state
520531func (e * Executor ) applyBlock (ctx context.Context , header types.Header , data * types.Data ) (types.State , error ) {
521- currentState := e .GetLastState ()
532+ currentState := e .getLastState ()
522533
523534 // Prepare transactions
524535 rawTxs := make ([][]byte , len (data .Txs ))
@@ -601,7 +612,7 @@ func (e *Executor) updateState(ctx context.Context, newState types.State) error
601612 return err
602613 }
603614
604- e .SetLastState (newState )
615+ e .setLastState (newState )
605616 e .metrics .Height .Set (float64 (newState .LastBlockHeight ))
606617
607618 return nil
0 commit comments