Skip to content

Commit 654817b

Browse files
committed
reorg handling
1 parent 6e83a48 commit 654817b

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed

nrpc/nrpc.nim

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import
2222
beacon_chain/el/el_manager,
2323
beacon_chain/el/engine_api_conversions,
2424
beacon_chain/spec/[forks, state_transition_block],
25+
beacon_chain/spec/datatypes/bellatrix,
2526
beacon_chain/spec/eth2_apis/[rest_types, rest_beacon_calls],
2627
beacon_chain/networking/network_metadata,
2728
eth/async_utils
@@ -45,7 +46,6 @@ template getCLBlockFromBeaconChain(
4546
var blck: ForkedSignedBeaconBlock
4647
if clBlock.isSome():
4748
let blck = clBlock.get()[]
48-
4949
(blck, true)
5050
else:
5151
(blck, false)
@@ -279,6 +279,12 @@ proc syncToEngineApi(conf: NRpcConf) {.async.} =
279279
info "newPayload Request sent",
280280
blockNumber = int(payload.blockNumber), response = payloadResponse.status
281281

282+
if payloadResponse.status != PayloadExecutionStatus.accepted:
283+
error "Payload not accepted",
284+
blockNumber = int(payload.blockNumber),
285+
status = payloadResponse.status
286+
quit(QuitFailure)
287+
282288
# Load the head hash from the execution payload, for forkchoice
283289
headHash = forkyBlck.message.body.execution_payload.block_hash
284290

@@ -303,9 +309,43 @@ proc syncToEngineApi(conf: NRpcConf) {.async.} =
303309
# Update the current block number from EL rest api
304310
# Shows that the fcu call has succeeded
305311
currentBlockNumber = elBlockNumber()
312+
let oldHeadBlockNumber = headBlck.header.number
306313
(headBlck, _) =
307314
client.getELBlockFromBeaconChain(BlockIdent.init(BlockIdentType.Head), clConfig)
308315

316+
# Check for reorg
317+
# No need to check for reorg if the EL head is behind the finalized block
318+
if currentBlockNumber > finalizedBlck.header.number and oldHeadBlockNumber > headBlck.header.number:
319+
warn "Head moved backwards : Possible reorg detected",
320+
oldHead = oldHeadBlockNumber,
321+
newHead = headBlck.header.number
322+
323+
let (headClBlck, isAvailable) = client.getCLBlockFromBeaconChain(
324+
BlockIdent.init(BlockIdentType.Head), clConfig
325+
)
326+
327+
# move back the importedSlot to the finalized block
328+
if isAvailable:
329+
withBlck(headClBlck.asTrusted()):
330+
when consensusFork >= ConsensusFork.Bellatrix:
331+
importedSlot = forkyBlck.message.slot.uint64 + 1
332+
currentBlockNumber = forkyBlck.message.body.execution_payload.block_number
333+
334+
# Load this head to the `headBlck`
335+
if not getEthBlock(forkyBlck.message, headBlck):
336+
error "Failed to get EL block from CL head"
337+
quit(QuitFailure)
338+
339+
(finalizedBlck, _) = client.getELBlockFromBeaconChain(
340+
BlockIdent.init(BlockIdentType.Finalized), clConfig
341+
)
342+
finalizedHash = finalizedBlck.header.blockHash.asEth2Digest
343+
sendFCU(headClBlck)
344+
else:
345+
error "Failed to get CL head"
346+
quit(QuitFailure)
347+
348+
309349
# fcU call for the last remaining payloads
310350
sendFCU(curBlck)
311351

0 commit comments

Comments
 (0)