4
4
"context"
5
5
"errors"
6
6
"fmt"
7
+ "math/big"
7
8
8
9
"github.com/ethereum/go-ethereum/beacon/engine"
9
10
"github.com/ethereum/go-ethereum/common"
@@ -31,35 +32,47 @@ func createPayloadAndSetHead(
31
32
"l1Origin" , meta .L1Origin ,
32
33
)
33
34
34
- payload , err := createExecutionPayloads (
35
- ctx ,
36
- rpc ,
37
- meta .createExecutionPayloadsMetaData ,
38
- anchorTx ,
39
- )
40
- if err != nil {
41
- return nil , fmt .Errorf ("failed to create execution payloads: %w" , err )
42
- }
43
-
44
- var (
45
- lastVerifiedBlockHash common.Hash
46
- )
35
+ var lastVerifiedBlockHash common.Hash
47
36
lastVerifiedTS , err := rpc .GetLastVerifiedTransitionPacaya (ctx )
48
37
if err != nil {
49
38
lastVerifiedBlockInfo , err := rpc .GetLastVerifiedBlockOntake (ctx )
50
39
if err != nil {
51
40
return nil , fmt .Errorf ("failed to fetch last verified block: %w" , err )
52
41
}
53
42
54
- if payload . Number > lastVerifiedBlockInfo .BlockId {
43
+ if meta . BlockID . Uint64 () > lastVerifiedBlockInfo .BlockId {
55
44
lastVerifiedBlockHash = lastVerifiedBlockInfo .BlockHash
56
45
}
57
46
} else {
58
- if payload . Number > lastVerifiedTS .BlockId {
47
+ if meta . BlockID . Uint64 () > lastVerifiedTS .BlockId {
59
48
lastVerifiedBlockHash = lastVerifiedTS .Ts .BlockHash
60
49
}
61
50
}
62
51
52
+ payload , err := createExecutionPayloads (
53
+ ctx ,
54
+ rpc ,
55
+ meta .createExecutionPayloadsMetaData ,
56
+ anchorTx ,
57
+ lastVerifiedBlockHash ,
58
+ )
59
+ if err != nil {
60
+ return nil , fmt .Errorf ("failed to create execution payloads: %w" , err )
61
+ }
62
+
63
+ // If the Pacaya block is preconfirmed, we don't need to insert it again.
64
+ if meta .BlockID .Cmp (new (big.Int ).SetUint64 (rpc .PacayaClients .ForkHeight )) >= 0 {
65
+ preconfirmed , err := isBlockPreconfirmed (ctx , rpc , payload )
66
+ if err != nil {
67
+ log .Debug ("Failed to check if the block is preconfirmed" , "error" , err )
68
+ } else {
69
+ if preconfirmed {
70
+ log .Info ("The block is preconfirmed" , "blockID" , meta .BlockID , "hash" , payload .BlockHash )
71
+ return payload , nil
72
+ }
73
+ }
74
+ }
75
+
63
76
fc := & engine.ForkchoiceStateV1 {
64
77
HeadBlockHash : payload .BlockHash ,
65
78
SafeBlockHash : lastVerifiedBlockHash ,
@@ -85,6 +98,7 @@ func createExecutionPayloads(
85
98
rpc * rpc.Client ,
86
99
meta * createExecutionPayloadsMetaData ,
87
100
anchorTx * types.Transaction ,
101
+ lastVerfiiedBlockHash common.Hash ,
88
102
) (payloadData * engine.ExecutableData , err error ) {
89
103
// Insert a TaikoL2.anchor / TaikoL2.anchorV2 transaction at transactions list head
90
104
txListBytes , err := rlp .EncodeToBytes (append ([]* types.Transaction {anchorTx }, meta .Txs ... ))
@@ -93,7 +107,11 @@ func createExecutionPayloads(
93
107
return nil , err
94
108
}
95
109
96
- fc := & engine.ForkchoiceStateV1 {HeadBlockHash : meta .ParentHash }
110
+ fc := & engine.ForkchoiceStateV1 {
111
+ HeadBlockHash : meta .ParentHash ,
112
+ SafeBlockHash : lastVerfiiedBlockHash ,
113
+ FinalizedBlockHash : lastVerfiiedBlockHash ,
114
+ }
97
115
attributes := & engine.PayloadAttributes {
98
116
Timestamp : meta .Timestamp ,
99
117
Random : meta .Difficulty ,
@@ -168,3 +186,17 @@ func createExecutionPayloads(
168
186
169
187
return payload , nil
170
188
}
189
+
190
+ // isBlockPreconfirmed checks if the block is preconfirmed.
191
+ func isBlockPreconfirmed (ctx context.Context , rpc * rpc.Client , payload * engine.ExecutableData ) (bool , error ) {
192
+ header , err := rpc .L2 .HeaderByNumber (ctx , new (big.Int ).SetUint64 (payload .Number ))
193
+ if err != nil {
194
+ return false , fmt .Errorf ("failed to get header by number %d: %w" , payload .Number , err )
195
+ }
196
+
197
+ if header == nil {
198
+ return false , fmt .Errorf ("header not found for block number %d" , payload .Number )
199
+ }
200
+
201
+ return header .Hash () == payload .BlockHash , nil
202
+ }
0 commit comments