implement getBlindedBlock REST API (#5829)

This commit is contained in:
tersec 2024-01-31 03:18:55 +00:00 committed by GitHub
parent 45b4b46041
commit 87052eba4e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 546 additions and 5 deletions

View File

@ -74,6 +74,13 @@ OK: 7/7 Fail: 0/7 Skip: 0/7
+ basics OK
```
OK: 2/2 Fail: 0/2 Skip: 0/2
## Blinded block conversions
```diff
+ Bellatrix toSignedBlindedBlock OK
+ Capella toSignedBlindedBlock OK
+ Deneb toSignedBlindedBlock OK
```
OK: 3/3 Fail: 0/3 Skip: 0/3
## Block pool altair processing [Preset: mainnet]
```diff
+ Invalid signatures [Preset: mainnet] OK
@ -979,4 +986,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
OK: 9/9 Fail: 0/9 Skip: 0/9
---TOTAL---
OK: 664/669 Fail: 0/669 Skip: 5/669
OK: 667/672 Fail: 0/672 Skip: 5/672

View File

@ -14,7 +14,7 @@ import
../beacon_node,
../consensus_object_pools/[blockchain_dag, spec_cache, validator_change_pool],
../spec/[deposit_snapshots, eth2_merkleization, forks, network, validator],
../spec/datatypes/[phase0, altair, deneb],
../spec/mev/bellatrix_mev,
../validators/message_router_mev
export rest_utils
@ -1012,6 +1012,48 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.4.2#/Beacon/getBlindedBlock
# https://github.com/ethereum/beacon-APIs/blob/v2.4.2/apis/beacon/blocks/blinded_block.yaml
router.api2(MethodGet, "/eth/v1/beacon/blinded_blocks/{block_id}") do (
block_id: BlockIdent) -> RestApiResponse:
let
blockIdent = block_id.valueOr:
return RestApiResponse.jsonError(Http400, InvalidBlockIdValueError,
$error)
bid = node.getBlockId(blockIdent).valueOr:
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
contentType =
block:
let res = preferredContentType(jsonMediaType,
sszMediaType)
if res.isErr():
return RestApiResponse.jsonError(Http406, ContentNotAcceptableError)
res.get()
bdata = node.dag.getForkedBlock(bid).valueOr:
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
template respondSszOrJson(
signedMaybeBlindedBlck: auto, consensusFork: ConsensusFork): untyped =
if contentType == sszMediaType:
RestApiResponse.sszResponse(
signedMaybeBlindedBlck,
[("eth-consensus-version", consensusFork.toString())])
elif contentType == jsonMediaType:
RestApiResponse.jsonResponseBlock(
signedMaybeBlindedBlck,
consensusFork,
node.getBlockOptimistic(bdata),
node.dag.isFinalized(bid)
)
else:
RestApiResponse.jsonError(Http500, InvalidAcceptError)
withBlck(bdata.asSigned()):
when consensusFork <= ConsensusFork.Altair:
respondSszOrJson(forkyBlck, consensusFork)
else:
respondSszOrJson(toSignedBlindedBeaconBlock(forkyBlck), consensusFork)
# https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlindedBlock
# https://github.com/ethereum/beacon-APIs/blob/v2.4.0/apis/beacon/blocks/blinded_blocks.yaml
router.api(MethodPost, "/eth/v1/beacon/blinded_blocks") do (

View File

@ -204,6 +204,7 @@ RestJson.useDefaultSerializationFor(
bellatrix.ExecutionPayload,
bellatrix.ExecutionPayloadHeader,
bellatrix.SignedBeaconBlock,
bellatrix_mev.BlindedBeaconBlockBody,
bellatrix_mev.BlindedBeaconBlock,
bellatrix_mev.SignedBlindedBeaconBlock,
capella.BeaconBlock,
@ -561,6 +562,33 @@ proc jsonResponse*(t: typedesc[RestApiResponse], data: auto): RestApiResponse =
default
RestApiResponse.response(res, Http200, "application/json")
proc jsonResponseBlock*(t: typedesc[RestApiResponse],
data: ForkySignedBlindedBeaconBlock,
consensusFork: ConsensusFork,
execOpt: Opt[bool],
finalized: bool): RestApiResponse =
let
headers = [("eth-consensus-version", consensusFork.toString())]
res =
block:
var default: seq[byte]
try:
var stream = memoryOutput()
var writer = JsonWriter[RestJson].init(stream)
writer.beginRecord()
writer.writeField("version", consensusFork.toString())
if execOpt.isSome():
writer.writeField("execution_optimistic", execOpt.get())
writer.writeField("finalized", finalized)
writer.writeField("data", data)
writer.endRecord()
stream.getOutput(seq[byte])
except SerializationError:
default
except IOError:
default
RestApiResponse.response(res, Http200, "application/json", headers = headers)
proc jsonResponseBlock*(t: typedesc[RestApiResponse],
data: ForkedSignedBeaconBlock,
execOpt: Opt[bool],

View File

@ -202,7 +202,9 @@ type
ForkySignedBlindedBeaconBlock* =
phase0.SignedBeaconBlock |
altair.SignedBeaconBlock |
capella_mev.SignedBlindedBeaconBlock
bellatrix_mev.SignedBlindedBeaconBlock |
capella_mev.SignedBlindedBeaconBlock |
deneb_mev.SignedBlindedBeaconBlock
ForkedSignedBlindedBeaconBlock* = object
case kind*: ConsensusFork
@ -318,7 +320,8 @@ template kind*(
bellatrix.TrustedBeaconBlockBody |
bellatrix.SigVerifiedSignedBeaconBlock |
bellatrix.MsgTrustedSignedBeaconBlock |
bellatrix.TrustedSignedBeaconBlock]): ConsensusFork =
bellatrix.TrustedSignedBeaconBlock] |
bellatrix_mev.SignedBlindedBeaconBlock): ConsensusFork =
ConsensusFork.Bellatrix
template kind*(

View File

@ -7,11 +7,36 @@
{.push raises: [].}
from ../datatypes/base import Eth1Data
import ".."/datatypes/altair
from ".."/datatypes/bellatrix import ExecutionPayloadHeader
from ".."/eth2_merkleization import hash_tree_root
type
# https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/bellatrix/builder.md#blindedbeaconblockbody
BlindedBeaconBlockBody* = object
randao_reveal*: ValidatorSig
eth1_data*: Eth1Data
graffiti*: GraffitiBytes
proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
attester_slashings*: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attestations*: List[Attestation, Limit MAX_ATTESTATIONS]
deposits*: List[Deposit, Limit MAX_DEPOSITS]
voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
sync_aggregate*: SyncAggregate
execution_payload_header*: bellatrix.ExecutionPayloadHeader
# https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/bellatrix/builder.md#blindedbeaconblock
BlindedBeaconBlock* = object
slot*: Slot
proposer_index*: uint64
parent_root*: Eth2Digest
state_root*: Eth2Digest
body*: BlindedBeaconBlockBody
# https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/bellatrix/builder.md#signedblindedbeaconblock
SignedBlindedBeaconBlock* = object
message*: BlindedBeaconBlock
signature*: ValidatorSig
func shortLog*(v: BlindedBeaconBlock): auto =
(
@ -40,3 +65,40 @@ func shortLog*(v: SignedBlindedBeaconBlock): auto =
blck: shortLog(default(BlindedBeaconBlock)),
signature: ""
)
func toSignedBlindedBeaconBlock*(blck: bellatrix.SignedBeaconBlock):
SignedBlindedBeaconBlock =
SignedBlindedBeaconBlock(
message: BlindedBeaconBlock(
slot: blck.message.slot,
proposer_index: blck.message.proposer_index,
parent_root: blck.message.parent_root,
state_root: blck.message.state_root,
body: BlindedBeaconBlockBody(
randao_reveal: blck.message.body.randao_reveal,
eth1_data: blck.message.body.eth1_data,
graffiti: blck.message.body.graffiti,
proposer_slashings: blck.message.body.proposer_slashings,
attester_slashings: blck.message.body.attester_slashings,
attestations: blck.message.body.attestations,
deposits: blck.message.body.deposits,
voluntary_exits: blck.message.body.voluntary_exits,
sync_aggregate: blck.message.body.sync_aggregate,
execution_payload_header: ExecutionPayloadHeader(
parent_hash: blck.message.body.execution_payload.parent_hash,
fee_recipient: blck.message.body.execution_payload.fee_recipient,
state_root: blck.message.body.execution_payload.state_root,
receipts_root: blck.message.body.execution_payload.receipts_root,
logs_bloom: blck.message.body.execution_payload.logs_bloom,
prev_randao: blck.message.body.execution_payload.prev_randao,
block_number: blck.message.body.execution_payload.block_number,
gas_limit: blck.message.body.execution_payload.gas_limit,
gas_used: blck.message.body.execution_payload.gas_used,
timestamp: blck.message.body.execution_payload.timestamp,
extra_data: blck.message.body.execution_payload.extra_data,
base_fee_per_gas:
blck.message.body.execution_payload.base_fee_per_gas,
block_hash: blck.message.body.execution_payload.block_hash,
transactions_root:
hash_tree_root(blck.message.body.execution_payload.transactions)))),
signature: blck.signature)

View File

@ -11,6 +11,7 @@ import ".."/datatypes/[altair, capella]
from stew/byteutils import to0xHex
from ../datatypes/bellatrix import ExecutionAddress
from ../eth2_merkleization import hash_tree_root
type
# https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/bellatrix/builder.md#validatorregistrationv1
@ -116,3 +117,43 @@ func shortLog*(v: SignedBlindedBeaconBlock): auto =
blck: shortLog(v.message),
signature: shortLog(v.signature)
)
func toSignedBlindedBeaconBlock*(blck: capella.SignedBeaconBlock):
SignedBlindedBeaconBlock =
SignedBlindedBeaconBlock(
message: BlindedBeaconBlock(
slot: blck.message.slot,
proposer_index: blck.message.proposer_index,
parent_root: blck.message.parent_root,
state_root: blck.message.state_root,
body: BlindedBeaconBlockBody(
randao_reveal: blck.message.body.randao_reveal,
eth1_data: blck.message.body.eth1_data,
graffiti: blck.message.body.graffiti,
proposer_slashings: blck.message.body.proposer_slashings,
attester_slashings: blck.message.body.attester_slashings,
attestations: blck.message.body.attestations,
deposits: blck.message.body.deposits,
voluntary_exits: blck.message.body.voluntary_exits,
sync_aggregate: blck.message.body.sync_aggregate,
execution_payload_header: ExecutionPayloadHeader(
parent_hash: blck.message.body.execution_payload.parent_hash,
fee_recipient: blck.message.body.execution_payload.fee_recipient,
state_root: blck.message.body.execution_payload.state_root,
receipts_root: blck.message.body.execution_payload.receipts_root,
logs_bloom: blck.message.body.execution_payload.logs_bloom,
prev_randao: blck.message.body.execution_payload.prev_randao,
block_number: blck.message.body.execution_payload.block_number,
gas_limit: blck.message.body.execution_payload.gas_limit,
gas_used: blck.message.body.execution_payload.gas_used,
timestamp: blck.message.body.execution_payload.timestamp,
extra_data: blck.message.body.execution_payload.extra_data,
base_fee_per_gas:
blck.message.body.execution_payload.base_fee_per_gas,
block_hash: blck.message.body.execution_payload.block_hash,
transactions_root:
hash_tree_root(blck.message.body.execution_payload.transactions),
withdrawals_root:
hash_tree_root(blck.message.body.execution_payload.withdrawals)),
bls_to_execution_changes: blck.message.body.bls_to_execution_changes)),
signature: blck.signature)

View File

@ -11,6 +11,7 @@ import ".."/datatypes/[altair, deneb]
from stew/byteutils import to0xHex
from ".."/datatypes/capella import SignedBLSToExecutionChange
from ".."/eth2_merkleization import hash_tree_root
type
# https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/deneb/builder.md#builderbid
@ -103,3 +104,44 @@ func shortLog*(v: SignedBlindedBeaconBlock): auto =
blck: shortLog(v.message),
signature: shortLog(v.signature)
)
func toSignedBlindedBeaconBlock*(blck: deneb.SignedBeaconBlock):
SignedBlindedBeaconBlock =
SignedBlindedBeaconBlock(
message: BlindedBeaconBlock(
slot: blck.message.slot,
proposer_index: blck.message.proposer_index,
parent_root: blck.message.parent_root,
state_root: blck.message.state_root,
body: BlindedBeaconBlockBody(
randao_reveal: blck.message.body.randao_reveal,
eth1_data: blck.message.body.eth1_data,
graffiti: blck.message.body.graffiti,
proposer_slashings: blck.message.body.proposer_slashings,
attester_slashings: blck.message.body.attester_slashings,
attestations: blck.message.body.attestations,
deposits: blck.message.body.deposits,
voluntary_exits: blck.message.body.voluntary_exits,
sync_aggregate: blck.message.body.sync_aggregate,
execution_payload_header: ExecutionPayloadHeader(
parent_hash: blck.message.body.execution_payload.parent_hash,
fee_recipient: blck.message.body.execution_payload.fee_recipient,
state_root: blck.message.body.execution_payload.state_root,
receipts_root: blck.message.body.execution_payload.receipts_root,
logs_bloom: blck.message.body.execution_payload.logs_bloom,
prev_randao: blck.message.body.execution_payload.prev_randao,
block_number: blck.message.body.execution_payload.block_number,
gas_limit: blck.message.body.execution_payload.gas_limit,
gas_used: blck.message.body.execution_payload.gas_used,
timestamp: blck.message.body.execution_payload.timestamp,
extra_data: blck.message.body.execution_payload.extra_data,
base_fee_per_gas:
blck.message.body.execution_payload.base_fee_per_gas,
block_hash: blck.message.body.execution_payload.block_hash,
transactions_root:
hash_tree_root(blck.message.body.execution_payload.transactions),
withdrawals_root:
hash_tree_root(blck.message.body.execution_payload.withdrawals)),
bls_to_execution_changes: blck.message.body.bls_to_execution_changes,
blob_kzg_commitments: blck.message.body.blob_kzg_commitments)),
signature: blck.signature)

View File

@ -3369,6 +3369,190 @@
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/head",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [
{"key": "Content-Type", "value": "application/json", "operator": "equals"},
{"key": "Eth-Consensus-Version", "value": ["phase0", "altair", "bellatrix"], "operator": "oneof"}
],
"body": [{"operator": "jstructcmpns", "value": {"version": "", "data": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body": {"randao_reveal": "", "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "graffiti": "", "proposer_slashings": [{"signed_header_1": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}, "signed_header_2": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}}], "attester_slashings": [{"attestation_1": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}, "attestation_2": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}}], "attestations": [{"aggregation_bits": "", "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}], "deposits": [{"proof": [""], "data": {"pubkey": "", "withdrawal_credentials": "", "amount": "", "signature": ""}}], "voluntary_exits": [{"message": {"epoch": "", "validator_index": ""}, "signature": ""}]}}, "signature": ""}}}]
}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/genesis",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [
{"key": "Content-Type", "value": "application/json", "operator": "equals"},
{"key": "Eth-Consensus-Version", "value": ["phase0", "altair", "bellatrix"], "operator": "oneof"}
],
"body": [{"operator": "jstructcmpns", "value": {"version": "", "data": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body": {"randao_reveal": "", "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "graffiti": "", "proposer_slashings": [{"signed_header_1": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}, "signed_header_2": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}}], "attester_slashings": [{"attestation_1": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}, "attestation_2": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}}], "attestations": [{"aggregation_bits": "", "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}], "deposits": [{"proof": [""], "data": {"pubkey": "", "withdrawal_credentials": "", "amount": "", "signature": ""}}], "voluntary_exits": [{"message": {"epoch": "", "validator_index": ""}, "signature": ""}]}}, "signature": ""}}}]
}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/finalized",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [
{"key": "Content-Type", "value": "application/json", "operator": "equals"},
{"key": "Eth-Consensus-Version", "value": ["phase0", "altair", "bellatrix"], "operator": "oneof"}
],
"body": [{"operator": "jstructcmpns", "value": {"version": "", "data": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body": {"randao_reveal": "", "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "graffiti": "", "proposer_slashings": [{"signed_header_1": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}, "signed_header_2": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}}], "attester_slashings": [{"attestation_1": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}, "attestation_2": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}}], "attestations": [{"aggregation_bits": "", "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}], "deposits": [{"proof": [""], "data": {"pubkey": "", "withdrawal_credentials": "", "amount": "", "signature": ""}}], "voluntary_exits": [{"message": {"epoch": "", "validator_index": ""}, "signature": ""}]}}, "signature": ""}}}]
}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/0",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "200"},
"headers": [
{"key": "Content-Type", "value": "application/json", "operator": "equals"},
{"key": "Eth-Consensus-Version", "value": ["phase0", "altair", "bellatrix"], "operator": "oneof"}
],
"body": [{"operator": "jstructcmpns", "value": {"version": "", "data": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body": {"randao_reveal": "", "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "graffiti": "", "proposer_slashings": [{"signed_header_1": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}, "signed_header_2": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}}], "attester_slashings": [{"attestation_1": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}, "attestation_2": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}}], "attestations": [{"aggregation_bits": "", "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}], "deposits": [{"proof": [""], "data": {"pubkey": "", "withdrawal_credentials": "", "amount": "", "signature": ""}}], "voluntary_exits": [{"message": {"epoch": "", "validator_index": ""}, "signature": ""}]}}, "signature": ""}}}]
}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/18446744073709551615",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "404"},
"headers": [
{"key": "Content-Type", "value": "application/json", "operator": "equals"},
{"key": "Eth-Consensus-Version", "operator": "notexists"}
],
"body": [{"operator": "jstructcmpns", "value": {"code": 404, "message": ""}}]
}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/18446744073709551616",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "400"},
"headers": [
{"key": "Content-Type", "value": "application/json", "operator": "equals"},
{"key": "Eth-Consensus-Version", "operator": "notexists"}
],
"body": [{"operator": "jstructcmpns", "value": {"code": 400, "message": ""}}]
}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/0x0000000000000000000000000000000000000000000000000000000000000000",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "404"},
"headers": [
{"key": "Content-Type", "value": "application/json", "operator": "equals"},
{"key": "Eth-Consensus-Version", "operator": "notexists"}
],
"body": [{"operator": "jstructcmpns", "value": {"code": 404, "message": ""}}]
}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/18446744073709551616",
"headers": {"Accept": "application/json"}
},
"response": {
"status": {"operator": "equals", "value": "400"},
"headers": [
{"key": "Content-Type", "value": "application/json", "operator": "equals"},
{"key": "Eth-Consensus-Version", "operator": "notexists"}
],
"body": [{"operator": "jstructcmpns", "value": {"code": 400, "message": ""}}]
}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/heat",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/geneziz",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/finalised",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/foobar",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/0x",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/0x0",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/0x00",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "beacon_blindedblocks_blockid"],
"request": {
"url": "/eth/v1/beacon/blinded_blocks/0x000000000000000000000000000000000000000000000000000000000000000000",
"headers": {"Accept": "application/json"}
},
"response": {"status": {"operator": "equals", "value": "400"}}
},
{
"topics": ["beacon", "beacon_block_blinded_blocks"],
"request": {

View File

@ -44,6 +44,7 @@ import # Unit test
./test_statediff,
./test_sync_committee_pool,
./test_sync_manager,
./test_toblindedblock,
./test_validator_change_pool,
./test_validator_pool,
./test_zero_signature,

View File

@ -0,0 +1,131 @@
# beacon_chain
# Copyright (c) 2024 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.used.}
import
# Beacon chain internals
../beacon_chain/spec/helpers,
../beacon_chain/spec/datatypes/[bellatrix, capella],
../beacon_chain/spec/mev/[bellatrix_mev, capella_mev, deneb_mev],
# Test utilities
unittest2
template do_check() =
check:
hash_tree_root(b.message) == hash_tree_root(
b.toSignedBlindedBeaconBlock.message)
b.signature == b.toSignedBlindedBeaconBlock.signature
const
nondefaultEth1Data = Eth1Data(
deposit_root: Eth2Digest.fromHex(
"0x55aaf2ee893f67db190d617070bd10d1583b00194fbcfda03d89baa24626f5bb"),
deposit_count: 1,
block_hash: Eth2Digest.fromHex(
"0xe617d58db390a10741ab7d3de0ba9460b5df5e0772e9721fe33c0422a63b2677"))
let nondefaultValidatorSig = ValidatorSig.fromHex(
"0xac08ca70066c6ea0525aa54dd867f82b86945818cb9305aae30f3bee13275dcf13d6d0680a47e889482ff2bb9a9f3cdb0588746f9e30c04645eda6d01bbd0ce6326ceb695294cb338ebace5b130c5b8f2e4f8efa63d63d5bb255c21a39da9c12")[]
template bellatrix_steps() =
b.message.slot = 1.Slot
do_check
b.message.proposer_index = 1
do_check
b.message.state_root = Eth2Digest.fromHex(
"0xb277ed302ade6685d0f0765fd0659c4b448656ab697409f2935cd9ab7189e48e")
do_check
b.message.parent_root = Eth2Digest.fromHex(
"0x2f6eaa73ec39aeb864884a2371f3e4a8abc29d277074459e46c987418f5df430")
do_check
b.message.body.randao_reveal = nondefaultValidatorSig
do_check
b.message.body.eth1_data = nondefaultEth1Data
do_check
distinctBase(b.message.body.graffiti)[0] = 1
do_check
check: b.message.body.proposer_slashings.add(default(ProposerSlashing))
do_check
check: b.message.body.attester_slashings.add(default(AttesterSlashing))
do_check
check: b.message.body.attestations.add(
Attestation(aggregation_bits: CommitteeValidatorsBits.init(1)))
do_check
check: b.message.body.deposits.add(default(Deposit))
do_check
check: b.message.body.voluntary_exits.add(default(SignedVoluntaryExit))
do_check
b.message.body.sync_aggregate.sync_committee_signature =
nondefaultValidatorSig
do_check
b.message.body.execution_payload.parent_hash = Eth2Digest.fromHex(
"0x941bdf6ccf731a7ede6bac0c9533ecee5e3dc5081ea59d57c3fd8c624eeca85d")
do_check
b.message.body.execution_payload.fee_recipient =
ExecutionAddress.fromHex("0x1234567812345678123456781234567812345678")
do_check
b.message.body.execution_payload.state_root = Eth2Digest.fromHex(
"0x9e7d9bca96a9d0af9013ad6abb8708988beef02d58c16ba1a90075960b99c2ff")
do_check
b.message.body.execution_payload.receipts_root = Eth2Digest.fromHex(
"0x0e66a5007cf7bb16f4398adbbd01b34067a80faaef41a0a6be324c5fdb93a6df")
do_check
b.message.body.execution_payload.logs_bloom.data[0] = 2
do_check
b.message.body.execution_payload.prev_randao = Eth2Digest.fromHex(
"0x8aa830156370e6a5ec7679d7e5ee712dd87f24fef76a1954a03c1df8c68bc0fd")
do_check
b.message.body.execution_payload.block_number = 3
do_check
b.message.body.execution_payload.gas_limit = 4
do_check
b.message.body.execution_payload.gas_used = 5
do_check
b.message.body.execution_payload.timestamp = 6
do_check
check: b.message.body.execution_payload.extra_data.add 0'u8
do_check
b.message.body.execution_payload.base_fee_per_gas = 7.u256
do_check
b.message.body.execution_payload.block_hash = Eth2Digest.fromHex(
"0x4b1aed517ac48bfbf6ab19846923d5256897fbc934c20ca5b8c486bfe71c6ef1")
do_check
check: b.message.body.execution_payload.transactions.add default(Transaction)
do_check
template capella_steps() =
check: b.message.body.bls_to_execution_changes.add(
default(SignedBLSToExecutionChange))
do_check
check: b.message.body.execution_payload.withdrawals.add(default(
Withdrawal))
do_check
template deneb_steps() =
check: b.message.body.blob_kzg_commitments.add(default(KzgCommitment))
do_check
suite "Blinded block conversions":
test "Bellatrix toSignedBlindedBlock":
var b = default(bellatrix.SignedBeaconBlock)
do_check
bellatrix_steps
test "Capella toSignedBlindedBlock":
var b = default(capella.SignedBeaconBlock)
do_check
bellatrix_steps
capella_steps
test "Deneb toSignedBlindedBlock":
var b = default(deneb.SignedBeaconBlock)
do_check
bellatrix_steps
capella_steps
deneb_steps