99 "math/big"
1010 "net/http"
1111 "strings"
12+ "sync"
1213 "time"
1314
1415 "github.com/ethereum/go-ethereum/beacon/engine"
@@ -40,9 +41,14 @@ type EngineClient struct {
4041 genesisHash common.Hash // Hash of the genesis block
4142 initialHeight uint64
4243 feeRecipient common.Address // Address to receive transaction fees
44+
45+ lastHeadBlockHash common.Hash // Store last non-finalized HeadBlockHash
46+ lastSafeBlockHash common.Hash // Store last non-finalized SafeBlockHash
47+ lastFinalizedBlockHash common.Hash // Store last finalized block hash
48+ mu sync.Mutex // Mutex to protect concurrent access to mutable state
4349}
4450
45- // NewPureEngineExecutionClient creates a new instance of EngineAPIExecutionClient
51+ // NewEngineExecutionClient creates a new instance of EngineClient
4652func NewEngineExecutionClient (
4753 ethURL ,
4854 engineURL string ,
@@ -86,6 +92,8 @@ func NewEngineExecutionClient(
8692
8793// InitChain initializes the blockchain with the given genesis parameters
8894func (c * EngineClient ) InitChain (ctx context.Context , genesisTime time.Time , initialHeight uint64 , chainID string ) ([]byte , uint64 , error ) {
95+ c .mu .Lock ()
96+ defer c .mu .Unlock ()
8997 if initialHeight != 1 {
9098 return nil , 0 , fmt .Errorf ("initialHeight must be 1, got %d" , initialHeight )
9199 }
@@ -116,6 +124,8 @@ func (c *EngineClient) InitChain(ctx context.Context, genesisTime time.Time, ini
116124
117125// GetTxs retrieves transactions from the current execution payload
118126func (c * EngineClient ) GetTxs (ctx context.Context ) ([][]byte , error ) {
127+ c .mu .Lock ()
128+ defer c .mu .Unlock ()
119129 var result struct {
120130 Pending map [string ]map [string ]* types.Transaction `json:"pending"`
121131 Queued map [string ]map [string ]* types.Transaction `json:"queued"`
@@ -153,6 +163,8 @@ func (c *EngineClient) GetTxs(ctx context.Context) ([][]byte, error) {
153163
154164// ExecuteTxs executes the given transactions at the specified block height and timestamp
155165func (c * EngineClient ) ExecuteTxs (ctx context.Context , txs [][]byte , blockHeight uint64 , timestamp time.Time , prevStateRoot []byte ) (updatedStateRoot []byte , maxBytes uint64 , err error ) {
166+ c .mu .Lock ()
167+ defer c .mu .Unlock ()
156168 // convert rollkit tx to eth tx
157169 ethTxs := make ([]* types.Transaction , len (txs ))
158170 for i , tx := range txs {
@@ -264,12 +276,26 @@ func (c *EngineClient) ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight
264276}
265277
266278func (c * EngineClient ) setFinal (ctx context.Context , blockHash common.Hash , isFinal bool ) error {
267- args := engine.ForkchoiceStateV1 {
268- HeadBlockHash : blockHash ,
269- SafeBlockHash : blockHash ,
270- }
279+ var args engine.ForkchoiceStateV1
280+
271281 if isFinal {
272- args .FinalizedBlockHash = blockHash
282+ // Use the last stored values for head and safe block hashes
283+ args = engine.ForkchoiceStateV1 {
284+ HeadBlockHash : c .lastHeadBlockHash ,
285+ SafeBlockHash : c .lastSafeBlockHash ,
286+ FinalizedBlockHash : blockHash ,
287+ }
288+ // Store the current blockHash as the latest finalized block hash
289+ c .lastFinalizedBlockHash = blockHash
290+ } else {
291+ // Store the current blockHash as the latest head and safe block hashes
292+ c .lastHeadBlockHash = blockHash
293+ c .lastSafeBlockHash = blockHash
294+ args = engine.ForkchoiceStateV1 {
295+ HeadBlockHash : blockHash ,
296+ SafeBlockHash : blockHash ,
297+ FinalizedBlockHash : c .lastFinalizedBlockHash ,
298+ }
273299 }
274300
275301 var forkchoiceResult engine.ForkChoiceResponse
@@ -290,6 +316,8 @@ func (c *EngineClient) setFinal(ctx context.Context, blockHash common.Hash, isFi
290316
291317// SetFinal marks the block at the given height as finalized
292318func (c * EngineClient ) SetFinal (ctx context.Context , blockHeight uint64 ) error {
319+ c .mu .Lock ()
320+ defer c .mu .Unlock ()
293321 blockHash , _ , _ , _ , err := c .getBlockInfo (ctx , blockHeight )
294322 if err != nil {
295323 return fmt .Errorf ("failed to get block info: %w" , err )
0 commit comments