tersec 2023-06-10 05:39:10 +00:00 committed by GitHub
parent db48160ab3
commit 9e14d904ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 30 deletions

View File

@ -51,7 +51,8 @@ proc initLightClient*(
if not blckPayload.block_hash.isZero: if not blckPayload.block_hash.isZero:
# engine_newPayloadV1 # engine_newPayloadV1
discard await node.elManager.newExecutionPayload(blckPayload) discard await node.elManager.newExecutionPayload(
blck.message.body)
# Retain optimistic head for other `forkchoiceUpdated` callers. # Retain optimistic head for other `forkchoiceUpdated` callers.
# May temporarily block `forkchoiceUpdatedV1` calls, e.g., Geth: # May temporarily block `forkchoiceUpdatedV1` calls, e.g., Geth:

View File

@ -25,6 +25,7 @@ import
from std/times import getTime, inSeconds, initTime, `-` from std/times import getTime, inSeconds, initTime, `-`
from ../spec/engine_authentication import getSignedIatToken from ../spec/engine_authentication import getSignedIatToken
from ../spec/state_transition_block import kzg_commitment_to_versioned_hash
export export
el_conf, engine_api, deques, base, DepositTreeSnapshot el_conf, engine_api, deques, base, DepositTreeSnapshot
@ -1064,10 +1065,11 @@ proc sendNewPayloadToSingleEL(connection: ELConnection,
return await rpcClient.engine_newPayloadV2(payload) return await rpcClient.engine_newPayloadV2(payload)
proc sendNewPayloadToSingleEL(connection: ELConnection, proc sendNewPayloadToSingleEL(connection: ELConnection,
payload: engine_api.ExecutionPayloadV3): payload: engine_api.ExecutionPayloadV3,
versioned_hashes: seq[engine_api.VersionedHash]):
Future[PayloadStatusV1] {.async.} = Future[PayloadStatusV1] {.async.} =
let rpcClient = await connection.connectedRpcClient() let rpcClient = await connection.connectedRpcClient()
return await rpcClient.engine_newPayloadV3(payload) return await rpcClient.engine_newPayloadV3(payload, versioned_hashes)
type type
StatusRelation = enum StatusRelation = enum
@ -1159,15 +1161,28 @@ proc processResponse[ELResponseType](
url2 = connections[idx].engineUrl.url, url2 = connections[idx].engineUrl.url,
status2 = status status2 = status
proc sendNewPayload*(m: ELManager, proc sendNewPayload*(m: ELManager, blockBody: SomeForkyBeaconBlockBody):
payload: engine_api.ExecutionPayloadV1 | engine_api.ExecutionPayloadV2 | engine_api.ExecutionPayloadV3):
Future[PayloadExecutionStatus] {.async.} = Future[PayloadExecutionStatus] {.async.} =
let let
earlyDeadline = sleepAsync(chronos.seconds 1) earlyDeadline = sleepAsync(chronos.seconds 1)
startTime = Moment.now startTime = Moment.now
deadline = sleepAsync(NEWPAYLOAD_TIMEOUT) deadline = sleepAsync(NEWPAYLOAD_TIMEOUT)
payload = blockBody.execution_payload.asEngineExecutionPayload
requests = m.elConnections.mapIt: 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) trackEngineApiRequest(it, req, "newPayload", startTime, deadline)
req req

View File

@ -245,8 +245,8 @@ from web3/engine_api_types import
PayloadAttributesV1, PayloadAttributesV2, PayloadExecutionStatus, PayloadAttributesV1, PayloadAttributesV2, PayloadExecutionStatus,
PayloadStatusV1 PayloadStatusV1
from ../el/el_manager import from ../el/el_manager import
ELManager, asEngineExecutionPayload, forkchoiceUpdated, hasConnection, ELManager, forkchoiceUpdated, hasConnection, hasProperlyConfiguredConnection,
hasProperlyConfiguredConnection, sendNewPayload sendNewPayload
proc expectValidForkchoiceUpdated( proc expectValidForkchoiceUpdated(
elManager: ELManager, headBlockPayloadAttributesType: typedesc, elManager: ELManager, headBlockPayloadAttributesType: typedesc,
@ -304,9 +304,11 @@ from ../spec/datatypes/deneb import SignedBeaconBlock, asTrusted, shortLog
proc newExecutionPayload*( proc newExecutionPayload*(
elManager: ELManager, elManager: ELManager,
executionPayload: ForkyExecutionPayload): blockBody: SomeForkyBeaconBlockBody):
Future[Opt[PayloadExecutionStatus]] {.async.} = Future[Opt[PayloadExecutionStatus]] {.async.} =
template executionPayload: untyped = blockBody.execution_payload
if not elManager.hasProperlyConfiguredConnection: if not elManager.hasProperlyConfiguredConnection:
if elManager.hasConnection: if elManager.hasConnection:
info "No execution client connected; cannot process block payloads", info "No execution client connected; cannot process block payloads",
@ -320,8 +322,7 @@ proc newExecutionPayload*(
executionPayload = shortLog(executionPayload) executionPayload = shortLog(executionPayload)
try: try:
let payloadStatus = await elManager.sendNewPayload( let payloadStatus = await elManager.sendNewPayload(blockBody)
executionPayload.asEngineExecutionPayload)
debug "newPayload: succeeded", debug "newPayload: succeeded",
parentHash = executionPayload.parent_hash, parentHash = executionPayload.parent_hash,
@ -348,7 +349,7 @@ proc getExecutionValidity(
try: try:
let executionPayloadStatus = await elManager.newExecutionPayload( let executionPayloadStatus = await elManager.newExecutionPayload(
blck.message.body.execution_payload) blck.message.body)
if executionPayloadStatus.isNone: if executionPayloadStatus.isNone:
return NewPayloadStatus.noResponse return NewPayloadStatus.noResponse
@ -442,6 +443,10 @@ proc storeBlock*(
# When the execution layer is not available to verify the payload, we do the # 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 # 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 # Client software MUST validate `blockHash` value as being equivalent to
# `Keccak256(RLP(ExecutionBlockHeader))` # `Keccak256(RLP(ExecutionBlockHeader))`
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/paris.md#specification # https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.3/src/engine/paris.md#specification
@ -462,6 +467,7 @@ proc storeBlock*(
# be re-added later # be re-added later
self.consensusManager.quarantine[].removeOrphan(signedBlock) self.consensusManager.quarantine[].removeOrphan(signedBlock)
# TODO with v1.4.0, not sure this is still relevant
# Establish blob viability before calling addHeadBlock to avoid # Establish blob viability before calling addHeadBlock to avoid
# writing the block in case of blob error. # writing the block in case of blob error.
when typeof(signedBlock).toFork() >= ConsensusFork.Deneb: when typeof(signedBlock).toFork() >= ConsensusFork.Deneb:

View File

@ -113,7 +113,7 @@ programMain:
template payload(): auto = blck.message.body.execution_payload template payload(): auto = blck.message.body.execution_payload
if elManager != nil and not payload.block_hash.isZero: 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( discard await elManager.forkchoiceUpdated(
headBlockHash = payload.block_hash, headBlockHash = payload.block_hash,
safeBlockHash = payload.block_hash, # stub value safeBlockHash = payload.block_hash, # stub value
@ -124,7 +124,7 @@ programMain:
template payload(): auto = blck.message.body.execution_payload template payload(): auto = blck.message.body.execution_payload
if elManager != nil and not payload.block_hash.isZero: 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( discard await elManager.forkchoiceUpdated(
headBlockHash = payload.block_hash, headBlockHash = payload.block_hash,
safeBlockHash = payload.block_hash, # stub value safeBlockHash = payload.block_hash, # stub value

View File

@ -727,9 +727,9 @@ func tx_peek_blob_versioned_hashes(opaque_tx: Transaction):
ok res ok res
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.1/specs/deneb/beacon-chain.md#kzg_commitment_to_versioned_hash # 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 = 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 const VERSIONED_HASH_VERSION_KZG = 0x01'u8
var res: VersionedHash var res: VersionedHash
@ -752,20 +752,15 @@ func verify_kzg_commitments_against_transactions*(
#all_versioned_hashes.add tx_peek_blob_versioned_hashes(tx).valueOr: #all_versioned_hashes.add tx_peek_blob_versioned_hashes(tx).valueOr:
# return false # 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( func process_blob_kzg_commitments(
state: var deneb.BeaconState,
body: deneb.BeaconBlockBody | deneb.TrustedBeaconBlockBody | body: deneb.BeaconBlockBody | deneb.TrustedBeaconBlockBody |
deneb.SigVerifiedBeaconBlockBody): deneb.SigVerifiedBeaconBlockBody): bool =
Result[void, cstring] = verify_kzg_commitments_against_transactions(
if verify_kzg_commitments_against_transactions(
body.execution_payload.transactions.asSeq, body.execution_payload.transactions.asSeq,
body.blob_kzg_commitments.asSeq): body.blob_kzg_commitments.asSeq)
return ok()
else:
return err("process_blob_kzg_commitments: verify_kzg_commitments_against_transactions failed")
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/fork-choice.md#validate_blobs # 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], proc validate_blobs*(expected_kzg_commitments: seq[KzgCommitment],
@ -875,6 +870,9 @@ proc process_block*(
## block application fails (!) ## block application fails (!)
? process_block_header(state, blck, flags, cache) ? 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): if is_execution_enabled(state, blck.body):
? process_withdrawals( ? process_withdrawals(
state, blck.body.execution_payload) # [New in Capella] state, blck.body.execution_payload) # [New in Capella]
@ -909,6 +907,9 @@ proc process_block*(
## block application fails (!) ## block application fails (!)
? process_block_header(state, blck, flags, cache) ? 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): if is_execution_enabled(state, blck.body):
? process_withdrawals(state, blck.body.execution_payload) ? process_withdrawals(state, blck.body.execution_payload)
? process_execution_payload( ? process_execution_payload(
@ -926,6 +927,4 @@ proc process_block*(
? process_sync_aggregate( ? process_sync_aggregate(
state, blck.body.sync_aggregate, total_active_balance, cache) state, blck.body.sync_aggregate, total_active_balance, cache)
? process_blob_kzg_commitments(state, blck.body) # [New in Deneb]
ok() ok()

2
vendor/nim-web3 vendored

@ -1 +1 @@
Subproject commit 18e37f7e0110f4400d1a19a9b925e4ac6e349e5f Subproject commit ebd1d8913b938f1050ada408b9ceaecb2c39e666