@@ -17,13 +17,12 @@ import (
17
17
"github.com/ethereum/go-ethereum/ethclient"
18
18
"github.com/ethereum/go-ethereum/rpc"
19
19
"github.com/golang-jwt/jwt/v5"
20
+ "github.com/rs/zerolog"
20
21
21
22
"github.com/evstack/ev-node/core/execution"
22
23
)
23
24
24
25
var (
25
- // ErrNilPayloadStatus indicates that PayloadID returned by EVM was nil
26
- ErrNilPayloadStatus = errors .New ("nil payload status" )
27
26
// ErrInvalidPayloadStatus indicates that EVM returned status != VALID
28
27
ErrInvalidPayloadStatus = errors .New ("invalid payload status" )
29
28
)
@@ -45,6 +44,8 @@ type EngineClient struct {
45
44
currentHeadBlockHash common.Hash // Store last non-finalized HeadBlockHash
46
45
currentSafeBlockHash common.Hash // Store last non-finalized SafeBlockHash
47
46
currentFinalizedBlockHash common.Hash // Store last finalized block hash
47
+
48
+ logger zerolog.Logger
48
49
}
49
50
50
51
// NewEngineExecutionClient creates a new instance of EngineAPIExecutionClient
@@ -89,9 +90,15 @@ func NewEngineExecutionClient(
89
90
currentHeadBlockHash : genesisHash ,
90
91
currentSafeBlockHash : genesisHash ,
91
92
currentFinalizedBlockHash : genesisHash ,
93
+ logger : zerolog .Nop (),
92
94
}, nil
93
95
}
94
96
97
+ // SetLogger allows callers to attach a structured logger.
98
+ func (c * EngineClient ) SetLogger (l zerolog.Logger ) {
99
+ c .logger = l
100
+ }
101
+
95
102
// InitChain initializes the blockchain with the given genesis parameters
96
103
func (c * EngineClient ) InitChain (ctx context.Context , genesisTime time.Time , initialHeight uint64 , chainID string ) ([]byte , uint64 , error ) {
97
104
if initialHeight != 1 {
@@ -166,9 +173,7 @@ func (c *EngineClient) ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight
166
173
}
167
174
168
175
// update forkchoice to get the next payload id
169
- var forkchoiceResult engine.ForkChoiceResponse
170
-
171
- // Create evolve-compatible payload attributes with flattened structure
176
+ // Create evolve-compatible payloadtimestamp.Unix()
172
177
evPayloadAttrs := map [string ]interface {}{
173
178
// Standard Ethereum payload attributes (flattened) - using camelCase as expected by JSON
174
179
"timestamp" : timestamp .Unix (),
@@ -182,16 +187,29 @@ func (c *EngineClient) ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight
182
187
"gasLimit" : prevGasLimit , // Use camelCase to match JSON conventions
183
188
}
184
189
185
- err = c .engineClient .CallContext (ctx , & forkchoiceResult , "engine_forkchoiceUpdatedV3" ,
186
- args ,
187
- evPayloadAttrs ,
188
- )
190
+ c .logger .Debug ().
191
+ Uint64 ("height" , blockHeight ).
192
+ Int ("tx_count" , len (txs )).
193
+ Msg ("engine_forkchoiceUpdatedV3" )
194
+
195
+ var forkchoiceResult engine.ForkChoiceResponse
196
+ err = c .engineClient .CallContext (ctx , & forkchoiceResult , "engine_forkchoiceUpdatedV3" , args , evPayloadAttrs )
189
197
if err != nil {
190
198
return nil , 0 , fmt .Errorf ("forkchoice update failed: %w" , err )
191
199
}
192
-
193
200
if forkchoiceResult .PayloadID == nil {
194
- return nil , 0 , ErrNilPayloadStatus
201
+ c .logger .Error ().
202
+ Str ("status" , string (forkchoiceResult .PayloadStatus .Status )).
203
+ Str ("latestValidHash" , forkchoiceResult .PayloadStatus .LatestValidHash .Hex ()).
204
+ Interface ("validationError" , forkchoiceResult .PayloadStatus .ValidationError ).
205
+ Interface ("forkchoiceState" , args ).
206
+ Interface ("payloadAttributes" , evPayloadAttrs ).
207
+ Uint64 ("blockHeight" , blockHeight ).
208
+ Msg ("returned nil PayloadID" )
209
+
210
+ return nil , 0 , fmt .Errorf ("returned nil PayloadID - (status: %s, latestValidHash: %s)" ,
211
+ forkchoiceResult .PayloadStatus .Status ,
212
+ forkchoiceResult .PayloadStatus .LatestValidHash .Hex ())
195
213
}
196
214
197
215
// get payload
@@ -214,6 +232,11 @@ func (c *EngineClient) ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight
214
232
}
215
233
216
234
if newPayloadResult .Status != engine .VALID {
235
+ c .logger .Warn ().
236
+ Str ("status" , string (newPayloadResult .Status )).
237
+ Str ("latestValidHash" , newPayloadResult .LatestValidHash .Hex ()).
238
+ Interface ("validationError" , newPayloadResult .ValidationError ).
239
+ Msg ("engine_newPayloadV4 returned non-VALID status" )
217
240
return nil , 0 , ErrInvalidPayloadStatus
218
241
}
219
242
@@ -246,15 +269,17 @@ func (c *EngineClient) setFinal(ctx context.Context, blockHash common.Hash, isFi
246
269
c .mu .Unlock ()
247
270
248
271
var forkchoiceResult engine.ForkChoiceResponse
249
- err := c .engineClient .CallContext (ctx , & forkchoiceResult , "engine_forkchoiceUpdatedV3" ,
250
- args ,
251
- nil ,
252
- )
272
+ err := c .engineClient .CallContext (ctx , & forkchoiceResult , "engine_forkchoiceUpdatedV3" , args , nil )
253
273
if err != nil {
254
274
return fmt .Errorf ("forkchoice update failed with error: %w" , err )
255
275
}
256
276
257
277
if forkchoiceResult .PayloadStatus .Status != engine .VALID {
278
+ c .logger .Warn ().
279
+ Str ("status" , string (forkchoiceResult .PayloadStatus .Status )).
280
+ Str ("latestValidHash" , forkchoiceResult .PayloadStatus .LatestValidHash .Hex ()).
281
+ Interface ("validationError" , forkchoiceResult .PayloadStatus .ValidationError ).
282
+ Msg ("forkchoiceUpdatedV3 returned non-VALID status" )
258
283
return ErrInvalidPayloadStatus
259
284
}
260
285
0 commit comments