Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
tersec authored Jun 10, 2023
1 parent db48160 commit 9e14d90
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 30 deletions.
3 changes: 2 additions & 1 deletion beacon_chain/beacon_node_light_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ proc initLightClient*(

if not blckPayload.block_hash.isZero:
# engine_newPayloadV1
discard await node.elManager.newExecutionPayload(blckPayload)
discard await node.elManager.newExecutionPayload(
blck.message.body)

# Retain optimistic head for other `forkchoiceUpdated` callers.
# May temporarily block `forkchoiceUpdatedV1` calls, e.g., Geth:
Expand Down
25 changes: 20 additions & 5 deletions beacon_chain/el/el_manager.nim
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import

from std/times import getTime, inSeconds, initTime, `-`
from ../spec/engine_authentication import getSignedIatToken
from ../spec/state_transition_block import kzg_commitment_to_versioned_hash

export
el_conf, engine_api, deques, base, DepositTreeSnapshot
Expand Down Expand Up @@ -1064,10 +1065,11 @@ proc sendNewPayloadToSingleEL(connection: ELConnection,
return await rpcClient.engine_newPayloadV2(payload)

proc sendNewPayloadToSingleEL(connection: ELConnection,
payload: engine_api.ExecutionPayloadV3):
payload: engine_api.ExecutionPayloadV3,
versioned_hashes: seq[engine_api.VersionedHash]):
Future[PayloadStatusV1] {.async.} =
let rpcClient = await connection.connectedRpcClient()
return await rpcClient.engine_newPayloadV3(payload)
return await rpcClient.engine_newPayloadV3(payload, versioned_hashes)

type
StatusRelation = enum
Expand Down Expand Up @@ -1159,15 +1161,28 @@ proc processResponse[ELResponseType](
url2 = connections[idx].engineUrl.url,
status2 = status

proc sendNewPayload*(m: ELManager,
payload: engine_api.ExecutionPayloadV1 | engine_api.ExecutionPayloadV2 | engine_api.ExecutionPayloadV3):
proc sendNewPayload*(m: ELManager, blockBody: SomeForkyBeaconBlockBody):
Future[PayloadExecutionStatus] {.async.} =
let
earlyDeadline = sleepAsync(chronos.seconds 1)
startTime = Moment.now
deadline = sleepAsync(NEWPAYLOAD_TIMEOUT)
payload = blockBody.execution_payload.asEngineExecutionPayload
requests = m.elConnections.mapIt:
let req = sendNewPayloadToSingleEL(it, payload)
let req =
when payload is engine_api.ExecutionPayloadV3:
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.1/specs/deneb/beacon-chain.md#process_execution_payload
# Verify the execution payload is valid
# [Modified in Deneb] Pass `versioned_hashes` to Execution Engine
let versioned_hashes = mapIt(
blockBody.blob_kzg_commitments,
engine_api.VersionedHash(kzg_commitment_to_versioned_hash(it)))
sendNewPayloadToSingleEL(it, payload, versioned_hashes)
elif payload is engine_api.ExecutionPayloadV1 or
payload is engine_api.ExecutionPayloadV2:
sendNewPayloadToSingleEL(it, payload)
else:
static: doAssert false
trackEngineApiRequest(it, req, "newPayload", startTime, deadline)
req

Expand Down
18 changes: 12 additions & 6 deletions beacon_chain/gossip_processing/block_processor.nim
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ from web3/engine_api_types import
PayloadAttributesV1, PayloadAttributesV2, PayloadExecutionStatus,
PayloadStatusV1
from ../el/el_manager import
ELManager, asEngineExecutionPayload, forkchoiceUpdated, hasConnection,
hasProperlyConfiguredConnection, sendNewPayload
ELManager, forkchoiceUpdated, hasConnection, hasProperlyConfiguredConnection,
sendNewPayload

proc expectValidForkchoiceUpdated(
elManager: ELManager, headBlockPayloadAttributesType: typedesc,
Expand Down Expand Up @@ -304,9 +304,11 @@ from ../spec/datatypes/deneb import SignedBeaconBlock, asTrusted, shortLog

proc newExecutionPayload*(
elManager: ELManager,
executionPayload: ForkyExecutionPayload):
blockBody: SomeForkyBeaconBlockBody):
Future[Opt[PayloadExecutionStatus]] {.async.} =

template executionPayload: untyped = blockBody.execution_payload

if not elManager.hasProperlyConfiguredConnection:
if elManager.hasConnection:
info "No execution client connected; cannot process block payloads",
Expand All @@ -320,8 +322,7 @@ proc newExecutionPayload*(
executionPayload = shortLog(executionPayload)

try:
let payloadStatus = await elManager.sendNewPayload(
executionPayload.asEngineExecutionPayload)
let payloadStatus = await elManager.sendNewPayload(blockBody)

debug "newPayload: succeeded",
parentHash = executionPayload.parent_hash,
Expand All @@ -348,7 +349,7 @@ proc getExecutionValidity(

try:
let executionPayloadStatus = await elManager.newExecutionPayload(
blck.message.body.execution_payload)
blck.message.body)
if executionPayloadStatus.isNone:
return NewPayloadStatus.noResponse

Expand Down Expand Up @@ -442,6 +443,10 @@ proc storeBlock*(
# When the execution layer is not available to verify the payload, we do the
# required check on the CL side instead and proceed as if the EL was syncing

# TODO run https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#blob-kzg-commitments
# https://github.com/ethereum/execution-apis/blob/main/src/engine/experimental/blob-extension.md#specification
# "This validation MUST be instantly run in all cases even during active sync process."
#
# Client software MUST validate `blockHash` value as being equivalent to
# `Keccak256(RLP(ExecutionBlockHeader))`
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/paris.md#specification
Expand All @@ -462,6 +467,7 @@ proc storeBlock*(
# be re-added later
self.consensusManager.quarantine[].removeOrphan(signedBlock)

# TODO with v1.4.0, not sure this is still relevant
# Establish blob viability before calling addHeadBlock to avoid
# writing the block in case of blob error.
when typeof(signedBlock).toFork() >= ConsensusFork.Deneb:
Expand Down
4 changes: 2 additions & 2 deletions beacon_chain/nimbus_light_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ programMain:
template payload(): auto = blck.message.body.execution_payload

if elManager != nil and not payload.block_hash.isZero:
discard await elManager.newExecutionPayload(payload)
discard await elManager.newExecutionPayload(blck.message.body)
discard await elManager.forkchoiceUpdated(
headBlockHash = payload.block_hash,
safeBlockHash = payload.block_hash, # stub value
Expand All @@ -124,7 +124,7 @@ programMain:
template payload(): auto = blck.message.body.execution_payload

if elManager != nil and not payload.block_hash.isZero:
discard await elManager.newExecutionPayload(payload)
discard await elManager.newExecutionPayload(blck.message.body)
discard await elManager.forkchoiceUpdated(
headBlockHash = payload.block_hash,
safeBlockHash = payload.block_hash, # stub value
Expand Down
29 changes: 14 additions & 15 deletions beacon_chain/spec/state_transition_block.nim
Original file line number Diff line number Diff line change
Expand Up @@ -727,9 +727,9 @@ func tx_peek_blob_versioned_hashes(opaque_tx: Transaction):
ok res

# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.1/specs/deneb/beacon-chain.md#kzg_commitment_to_versioned_hash
func kzg_commitment_to_versioned_hash(
func kzg_commitment_to_versioned_hash*(
kzg_commitment: KzgCommitment): VersionedHash =
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#blob
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.1/specs/deneb/beacon-chain.md#blob
const VERSIONED_HASH_VERSION_KZG = 0x01'u8

var res: VersionedHash
Expand All @@ -752,20 +752,15 @@ func verify_kzg_commitments_against_transactions*(
#all_versioned_hashes.add tx_peek_blob_versioned_hashes(tx).valueOr:
# return false

all_versioned_hashes == mapIt(kzg_commitments, it.kzg_commitment_to_versioned_hash)
all_versioned_hashes == mapIt(
kzg_commitments, it.kzg_commitment_to_versioned_hash)

# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#blob-kzg-commitments
func process_blob_kzg_commitments(
state: var deneb.BeaconState,
body: deneb.BeaconBlockBody | deneb.TrustedBeaconBlockBody |
deneb.SigVerifiedBeaconBlockBody):
Result[void, cstring] =
if verify_kzg_commitments_against_transactions(
body.execution_payload.transactions.asSeq,
body.blob_kzg_commitments.asSeq):
return ok()
else:
return err("process_blob_kzg_commitments: verify_kzg_commitments_against_transactions failed")
deneb.SigVerifiedBeaconBlockBody): bool =
verify_kzg_commitments_against_transactions(
body.execution_payload.transactions.asSeq,
body.blob_kzg_commitments.asSeq)

# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/fork-choice.md#validate_blobs
proc validate_blobs*(expected_kzg_commitments: seq[KzgCommitment],
Expand Down Expand Up @@ -875,6 +870,9 @@ proc process_block*(
## block application fails (!)

? process_block_header(state, blck, flags, cache)

# Consensus specs v1.4.0 unconditionally assume is_execution_enabled is
# true, but intentionally keep such a check.
if is_execution_enabled(state, blck.body):
? process_withdrawals(
state, blck.body.execution_payload) # [New in Capella]
Expand Down Expand Up @@ -909,6 +907,9 @@ proc process_block*(
## block application fails (!)

? process_block_header(state, blck, flags, cache)

# Consensus specs v1.4.0 unconditionally assume is_execution_enabled is
# true, but intentionally keep such a check.
if is_execution_enabled(state, blck.body):
? process_withdrawals(state, blck.body.execution_payload)
? process_execution_payload(
Expand All @@ -926,6 +927,4 @@ proc process_block*(
? process_sync_aggregate(
state, blck.body.sync_aggregate, total_active_balance, cache)

? process_blob_kzg_commitments(state, blck.body) # [New in Deneb]

ok()
2 changes: 1 addition & 1 deletion vendor/nim-web3

0 comments on commit 9e14d90

Please sign in to comment.