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:
# 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:

View File

@ -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
@ -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
@ -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

View File

@ -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,
@ -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",
@ -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,
@ -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
@ -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
@ -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:

View File

@ -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
@ -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

View File

@ -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
@ -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],
@ -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]
@ -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(
@ -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
vendor/nim-web3 vendored

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