7
7
"fmt"
8
8
"math/big"
9
9
10
+ "github.com/ethereum/go-ethereum"
10
11
"github.com/ethereum/go-ethereum/beacon/engine"
11
12
"github.com/ethereum/go-ethereum/common"
12
13
consensus "github.com/ethereum/go-ethereum/consensus/taiko"
@@ -54,6 +55,21 @@ func createPayloadAndSetHead(
54
55
meta .GasLimit += consensus .AnchorGasLimit
55
56
}
56
57
58
+ // Update execution payload id for the L1 origin.
59
+ var (
60
+ txListHash = crypto .Keccak256Hash (txListBytes )
61
+ args = & miner.BuildPayloadArgs {
62
+ Parent : meta .ParentHash ,
63
+ Timestamp : meta .Timestamp ,
64
+ FeeRecipient : meta .SuggestedFeeRecipient ,
65
+ Random : meta .Difficulty ,
66
+ Withdrawals : make ([]* types.Withdrawal , 0 ),
67
+ Version : engine .PayloadV2 ,
68
+ TxListHash : & txListHash ,
69
+ }
70
+ )
71
+ meta .L1Origin .BuildPayloadArgsID = args .Id ()
72
+
57
73
// Create a new execution payload and set the chain head.
58
74
return createExecutionPayloadsAndSetHead (ctx , rpc , meta .createExecutionPayloadsMetaData , txListBytes )
59
75
}
@@ -193,9 +209,9 @@ func createExecutionPayloads(
193
209
return payload , nil
194
210
}
195
211
196
- // isBatchPreconfirmed checks if all blocks in the given batch are preconfirmed ,
197
- // and returns the header of the last block in the batch if it is preconfirmed .
198
- func isBatchPreconfirmed (
212
+ // isKnownCanonicalBatch checks if all blocks in the given batch are in the canonical chain already. ,
213
+ // and returns the header of the last block in the batch if it is.
214
+ func isKnownCanonicalBatch (
199
215
ctx context.Context ,
200
216
rpc * rpc.Client ,
201
217
anchorConstructor * anchorTxConstructor.AnchorTxConstructor ,
@@ -235,7 +251,7 @@ func isBatchPreconfirmed(
235
251
return fmt .Errorf ("failed to RLP encode tx list: %w" , err )
236
252
}
237
253
238
- if headers [i ], err = isBlockPreconfirmed (
254
+ if headers [i ], err = isKnownCanonicalBlock (
239
255
ctx ,
240
256
rpc ,
241
257
& createPayloadAndSetHeadMetaData {
@@ -258,8 +274,8 @@ func isBatchPreconfirmed(
258
274
return headers [len (headers )- 1 ], g .Wait ()
259
275
}
260
276
261
- // isBlockPreconfirmed checks if the block is preconfirmed .
262
- func isBlockPreconfirmed (
277
+ // isKnownCanonicalBlock checks if the block is in canonical chain already .
278
+ func isKnownCanonicalBlock (
263
279
ctx context.Context ,
264
280
rpc * rpc.Client ,
265
281
meta * createPayloadAndSetHeadMetaData ,
@@ -280,81 +296,31 @@ func isBlockPreconfirmed(
280
296
txListHash = crypto .Keccak256Hash (txListBytes [:])
281
297
args = & miner.BuildPayloadArgs {
282
298
Parent : meta .Parent .Hash (),
283
- Timestamp : block . Time () ,
284
- FeeRecipient : block . Coinbase () ,
285
- Random : block . MixDigest () ,
299
+ Timestamp : meta . Timestamp ,
300
+ FeeRecipient : meta . SuggestedFeeRecipient ,
301
+ Random : meta . Difficulty ,
286
302
Withdrawals : make ([]* types.Withdrawal , 0 ),
287
303
Version : engine .PayloadV2 ,
288
304
TxListHash : & txListHash ,
289
305
}
290
306
id = args .Id ()
291
307
)
292
- executableData , err := rpc .L2Engine .GetPayload (ctx , & id )
293
- if err != nil {
294
- return nil , fmt .Errorf ("failed to get payload: %w" , err )
295
- }
296
-
297
- defer func () {
298
- if err != nil {
299
- log .Warn ("Invalid preconfirmed block" , "blockID" , blockID , "coinbase" , executableData .FeeRecipient , "reason" , err )
300
- }
301
- }()
302
-
303
- if executableData .BlockHash != block .Hash () {
304
- err = fmt .Errorf ("block hash mismatch: %s != %s" , executableData .BlockHash , block .Hash ())
305
- return nil , err
306
- }
307
- if block .ParentHash () != meta .ParentHash {
308
- err = fmt .Errorf ("parent hash mismatch: %s != %s" , block .ParentHash (), meta .ParentHash )
309
- return nil , err
310
- }
311
- if block .Transactions ().Len () == 0 {
312
- err = errors .New ("transactions list is empty" )
313
- return nil , err
314
- }
315
- if block .Transactions ()[0 ].Hash () != anchorTx .Hash () {
316
- err = fmt .Errorf ("anchor transaction mismatch: %s != %s" , block .Transactions ()[0 ].Hash (), anchorTx .Hash ())
317
- return nil , err
318
- }
319
- if block .UncleHash () != types .EmptyUncleHash {
320
- err = fmt .Errorf ("uncle hash mismatch: %s != %s" , block .UncleHash (), types .EmptyUncleHash )
321
- return nil , err
308
+ l1Origin , err := rpc .L2 .L1OriginByID (ctx , blockID )
309
+ if err != nil && ! errors .Is (err , ethereum .NotFound ) {
310
+ return nil , fmt .Errorf ("failed to get L1Origin by ID %d: %w" , blockID , err )
322
311
}
323
- if block .Coinbase () != meta .SuggestedFeeRecipient {
324
- err = fmt .Errorf ("coinbase mismatch: %s != %s" , block .Coinbase (), meta .SuggestedFeeRecipient )
325
- return nil , err
326
- }
327
- if block .Difficulty ().Cmp (common .Big0 ) != 0 {
328
- err = fmt .Errorf ("difficulty mismatch: %s != 0" , block .Difficulty ())
329
- return nil , err
312
+ // If L1Origin is not found, it means this block is synced from beacon sync.
313
+ if l1Origin == nil {
314
+ return nil , fmt .Errorf ("L1Origin not found by ID %d" , blockID )
330
315
}
331
- if block .MixDigest () != meta .Difficulty {
332
- err = fmt .Errorf ("mixDigest mismatch: %s != %s" , block .MixDigest (), meta .Difficulty )
333
- return nil , err
334
- }
335
- if block .Number ().Uint64 () != meta .BlockID .Uint64 () {
336
- err = fmt .Errorf ("block number mismatch: %d != %d" , block .Number (), meta .BlockID )
337
- return nil , err
338
- }
339
- if block .GasLimit () != meta .GasLimit + consensus .AnchorV3GasLimit {
340
- err = fmt .Errorf ("gas limit mismatch: %d != %d" , block .GasLimit (), meta .GasLimit + consensus .AnchorV3GasLimit )
341
- return nil , err
342
- }
343
- if block .Time () != meta .Timestamp {
344
- err = fmt .Errorf ("timestamp mismatch: %d != %d" , block .Time (), meta .Timestamp )
345
- return nil , err
346
- }
347
- if ! bytes .Equal (block .Extra (), meta .ExtraData ) {
348
- err = fmt .Errorf ("extra data mismatch: %s != %s" , block .Extra (), meta .ExtraData )
349
- return nil , err
350
- }
351
- if block .BaseFee ().Cmp (meta .BaseFee ) != 0 {
352
- err = fmt .Errorf ("base fee mismatch: %s != %s" , block .BaseFee (), meta .BaseFee )
353
- return nil , err
354
- }
355
- if block .Withdrawals ().Len () != 0 {
356
- err = fmt .Errorf ("withdrawals mismatch: %d != 0" , block .Withdrawals ().Len ())
357
- return nil , err
316
+ // If the payload ID matches, it means this block is already in the canonical chain.
317
+ if l1Origin .BuildPayloadArgsID != [8 ]byte {} && ! bytes .Equal (l1Origin .BuildPayloadArgsID [:], id [:]) {
318
+ return nil , fmt .Errorf (
319
+ "payload ID for block %d mismatch, l1Origin payload id: %s, current payload id %s" ,
320
+ blockID ,
321
+ engine .PayloadID (l1Origin .BuildPayloadArgsID ),
322
+ id ,
323
+ )
358
324
}
359
325
360
326
return block .Header (), nil
@@ -460,6 +426,7 @@ func assembleCreateExecutionPayloadMetaPacaya(
460
426
}, anchorTx , nil
461
427
}
462
428
429
+ // updateL1OriginForBatch updates the L1 origin for the given batch of blocks.
463
430
func updateL1OriginForBatch (
464
431
ctx context.Context ,
465
432
rpc * rpc.Client ,
@@ -489,9 +456,19 @@ func updateL1OriginForBatch(
489
456
L1BlockHeight : meta .GetRawBlockHeight (),
490
457
L1BlockHash : meta .GetRawBlockHash (),
491
458
}
459
+ // Fetch the original L1Origin to get the BuildPayloadArgsID.
460
+ originalL1Origin , err := rpc .L2 .L1OriginByID (ctx , blockID )
461
+ if err != nil && ! errors .Is (err , ethereum .NotFound ) {
462
+ return fmt .Errorf ("failed to get L1Origin by ID %d: %w" , blockID , err )
463
+ }
464
+ // If L1Origin is not found, it means this block is synced from beacon sync,
465
+ // and we also won't set the `BuildPayloadArgsID` value.
466
+ if originalL1Origin != nil {
467
+ l1Origin .BuildPayloadArgsID = originalL1Origin .BuildPayloadArgsID
468
+ }
492
469
493
470
if _ , err := rpc .L2Engine .UpdateL1Origin (ctx , l1Origin ); err != nil {
494
- return fmt .Errorf ("failed to update L1 origin : %w" , err )
471
+ return fmt .Errorf ("failed to update L1Origin : %w" , err )
495
472
}
496
473
497
474
// If this is the most recent block, update the HeadL1Origin.
0 commit comments