From f0ecdb407d7bc97dfd5f807356e53faa247b3817 Mon Sep 17 00:00:00 2001 From: tersec Date: Mon, 16 Sep 2024 10:32:59 +0000 Subject: [PATCH] remove block fork guessing/inference from REST JSON decoding --- AllTests-mainnet.md | 32 +- .../eth2_apis/eth2_rest_serialization.nim | 754 +++++------------- tests/all_tests.nim | 1 - tests/test_rest_json_serialization.nim | 12 - 4 files changed, 204 insertions(+), 595 deletions(-) diff --git a/AllTests-mainnet.md b/AllTests-mainnet.md index d4135b9854..b582ff578b 100644 --- a/AllTests-mainnet.md +++ b/AllTests-mainnet.md @@ -762,33 +762,6 @@ OK: 8/8 Fail: 0/8 Skip: 0/8 + sepolia OK ``` OK: 2/2 Fail: 0/2 Skip: 0/2 -## Nimbus remote signer/signing test (verifying-web3signer) -```diff -+ Signing BeaconBlock (getBlockSignature(capella)) OK -+ Signing BeaconBlock (getBlockSignature(deneb)) OK -+ Waiting for signing node (/upcheck) test OK -``` -OK: 3/3 Fail: 0/3 Skip: 0/3 -## Nimbus remote signer/signing test (web3signer) -```diff -+ Connection timeout test OK -+ Public keys enumeration (/api/v1/eth2/publicKeys) test OK -+ Public keys reload (/reload) test OK -+ Signing BeaconBlock (getBlockSignature(capella)) OK -+ Signing BeaconBlock (getBlockSignature(deneb)) OK -+ Signing SC contribution and proof (getContributionAndProofSignature()) OK -+ Signing SC message (getSyncCommitteeMessage()) OK -+ Signing SC selection proof (getSyncCommitteeSelectionProof()) OK -+ Signing aggregate and proof (getAggregateAndProofSignature()) OK -+ Signing aggregation slot (getSlotSignature()) OK -+ Signing attestation (getAttestationSignature()) OK -+ Signing deposit message (getDepositMessageSignature()) OK -+ Signing randao reveal (getEpochSignature()) OK -+ Signing validator registration (getBuilderSignature()) OK -+ Signing voluntary exit (getValidatorExitSignature()) OK -+ Waiting for signing node (/upcheck) test OK -``` -OK: 16/16 Fail: 0/16 Skip: 0/16 ## Old database versions [Preset: mainnet] ```diff + pre-1.1.0 OK @@ -821,10 +794,9 @@ OK: 1/1 Fail: 0/1 Skip: 0/1 + DenebSignedBlockContents decoding OK + KzgCommitment OK + KzgProof OK -+ RestPublishedSignedBlockContents decoding OK + Validator pubkey hack OK ``` -OK: 6/6 Fail: 0/6 Skip: 0/6 +OK: 5/5 Fail: 0/5 Skip: 0/5 ## Remove keystore testing suite ```diff + Many remotes OK @@ -1125,4 +1097,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2 OK: 9/9 Fail: 0/9 Skip: 0/9 ---TOTAL--- -OK: 762/767 Fail: 0/767 Skip: 5/767 +OK: 742/747 Fail: 0/747 Skip: 5/747 diff --git a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim index b0e49bc468..6dd5001343 100644 --- a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim +++ b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim @@ -1576,532 +1576,6 @@ proc writeValue*[BlockType: Web3SignerForkedBeaconBlock]( writer.writeField("block_header", value.data) writer.endRecord() -## RestPublishedBeaconBlockBody -proc readValue*(reader: var JsonReader[RestJson], - value: var RestPublishedBeaconBlockBody) {. - raises: [IOError, SerializationError].} = - var - randao_reveal: Opt[ValidatorSig] - eth1_data: Opt[Eth1Data] - graffiti: Opt[GraffitiBytes] - proposer_slashings: - Opt[List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]] - attester_slashings: - Opt[List[phase0.AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]] - attestations: Opt[List[phase0.Attestation, Limit MAX_ATTESTATIONS]] - deposits: Opt[List[Deposit, Limit MAX_DEPOSITS]] - voluntary_exits: Opt[List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]] - sync_aggregate: Opt[SyncAggregate] - execution_payload: Opt[RestExecutionPayload] - bls_to_execution_changes: Opt[SignedBLSToExecutionChangeList] - blob_kzg_commitments: Opt[KzgCommitments] - - for fieldName in readObjectFields(reader): - case fieldName - of "randao_reveal": - if randao_reveal.isSome(): - reader.raiseUnexpectedField("Multiple `randao_reveal` fields found", - "RestPublishedBeaconBlockBody") - randao_reveal = Opt.some(reader.readValue(ValidatorSig)) - of "eth1_data": - if eth1_data.isSome(): - reader.raiseUnexpectedField("Multiple `eth1_data` fields found", - "RestPublishedBeaconBlockBody") - eth1_data = Opt.some(reader.readValue(Eth1Data)) - of "graffiti": - if graffiti.isSome(): - reader.raiseUnexpectedField("Multiple `graffiti` fields found", - "RestPublishedBeaconBlockBody") - graffiti = Opt.some(reader.readValue(GraffitiBytes)) - of "proposer_slashings": - if proposer_slashings.isSome(): - reader.raiseUnexpectedField( - "Multiple `proposer_slashings` fields found", - "RestPublishedBeaconBlockBody") - proposer_slashings = Opt.some( - reader.readValue(List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS])) - of "attester_slashings": - if attester_slashings.isSome(): - reader.raiseUnexpectedField( - "Multiple `attester_slashings` fields found", - "RestPublishedBeaconBlockBody") - attester_slashings = Opt.some( - reader.readValue( - List[phase0.AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS])) - of "attestations": - if attestations.isSome(): - reader.raiseUnexpectedField("Multiple `attestations` fields found", - "RestPublishedBeaconBlockBody") - attestations = Opt.some( - reader.readValue(List[phase0.Attestation, Limit MAX_ATTESTATIONS])) - of "deposits": - if deposits.isSome(): - reader.raiseUnexpectedField("Multiple `deposits` fields found", - "RestPublishedBeaconBlockBody") - deposits = Opt.some(reader.readValue(List[Deposit, Limit MAX_DEPOSITS])) - of "voluntary_exits": - if voluntary_exits.isSome(): - reader.raiseUnexpectedField("Multiple `voluntary_exits` fields found", - "RestPublishedBeaconBlockBody") - voluntary_exits = Opt.some( - reader.readValue(List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS])) - of "sync_aggregate": - if sync_aggregate.isSome(): - reader.raiseUnexpectedField("Multiple `sync_aggregate` fields found", - "RestPublishedBeaconBlockBody") - sync_aggregate = Opt.some(reader.readValue(SyncAggregate)) - of "execution_payload": - if execution_payload.isSome(): - reader.raiseUnexpectedField("Multiple `execution_payload` fields found", - "RestPublishedBeaconBlockBody") - execution_payload = Opt.some(reader.readValue(RestExecutionPayload)) - of "bls_to_execution_changes": - if bls_to_execution_changes.isSome(): - reader.raiseUnexpectedField("Multiple `bls_to_execution_changes` fields found", - "RestPublishedBeaconBlockBody") - bls_to_execution_changes = Opt.some( - reader.readValue(SignedBLSToExecutionChangeList)) - of "blob_kzg_commitments": - if blob_kzg_commitments.isSome(): - reader.raiseUnexpectedField("Multiple `blob_kzg_commitments` fields found", - "RestPublishedBeaconBlockBody") - blob_kzg_commitments = Opt.some(reader.readValue(KzgCommitments)) - else: - unrecognizedFieldWarning(fieldName, typeof(value).name) - - if randao_reveal.isNone(): - reader.raiseUnexpectedValue("Field `randao_reveal` is missing") - if eth1_data.isNone(): - reader.raiseUnexpectedValue("Field `eth1_data` is missing") - if graffiti.isNone(): - reader.raiseUnexpectedValue("Field `graffiti` is missing") - if proposer_slashings.isNone(): - reader.raiseUnexpectedValue("Field `proposer_slashings` is missing") - if attester_slashings.isNone(): - reader.raiseUnexpectedValue("Field `attester_slashings` is missing") - if attestations.isNone(): - reader.raiseUnexpectedValue("Field `attestations` is missing") - if deposits.isNone(): - reader.raiseUnexpectedValue("Field `deposits` is missing") - if voluntary_exits.isNone(): - reader.raiseUnexpectedValue("Field `voluntary_exits` is missing") - - let bodyKind = - if execution_payload.isSome() and - execution_payload.get().blob_gas_used.isSome() and - blob_kzg_commitments.isSome(): - ConsensusFork.Deneb - elif execution_payload.isSome() and - execution_payload.get().withdrawals.isSome() and - bls_to_execution_changes.isSome() and - sync_aggregate.isSome(): - ConsensusFork.Capella - elif execution_payload.isSome() and sync_aggregate.isSome(): - ConsensusFork.Bellatrix - elif execution_payload.isNone() and sync_aggregate.isSome(): - ConsensusFork.Altair - else: - ConsensusFork.Phase0 - - template ep_src: auto = execution_payload.get() - template copy_ep_bellatrix(ep_dst: auto) = - assign(ep_dst.parent_hash, ep_src.parent_hash) - assign(ep_dst.fee_recipient, ep_src.fee_recipient) - assign(ep_dst.state_root, ep_src.state_root) - assign(ep_dst.receipts_root, ep_src.receipts_root) - assign(ep_dst.logs_bloom, ep_src.logs_bloom) - assign(ep_dst.prev_randao, ep_src.prev_randao) - assign(ep_dst.block_number, ep_src.block_number) - assign(ep_dst.gas_limit, ep_src.gas_limit) - assign(ep_dst.gas_used, ep_src.gas_used) - assign(ep_dst.timestamp, ep_src.timestamp) - assign(ep_dst.extra_data, ep_src.extra_data) - assign(ep_dst.base_fee_per_gas, ep_src.base_fee_per_gas) - assign(ep_dst.block_hash, ep_src.block_hash) - assign(ep_dst.transactions, ep_src.transactions) - - case bodyKind - of ConsensusFork.Phase0: - value = RestPublishedBeaconBlockBody( - kind: ConsensusFork.Phase0, - phase0Body: phase0.BeaconBlockBody( - randao_reveal: randao_reveal.get(), - eth1_data: eth1_data.get(), - graffiti: graffiti.get(), - proposer_slashings: proposer_slashings.get(), - attester_slashings: attester_slashings.get(), - attestations: attestations.get(), - deposits: deposits.get(), - voluntary_exits: voluntary_exits.get() - ) - ) - of ConsensusFork.Altair: - value = RestPublishedBeaconBlockBody( - kind: ConsensusFork.Altair, - altairBody: altair.BeaconBlockBody( - randao_reveal: randao_reveal.get(), - eth1_data: eth1_data.get(), - graffiti: graffiti.get(), - proposer_slashings: proposer_slashings.get(), - attester_slashings: attester_slashings.get(), - attestations: attestations.get(), - deposits: deposits.get(), - voluntary_exits: voluntary_exits.get(), - sync_aggregate: sync_aggregate.get() - ) - ) - of ConsensusFork.Bellatrix: - value = RestPublishedBeaconBlockBody( - kind: ConsensusFork.Bellatrix, - bellatrixBody: bellatrix.BeaconBlockBody( - randao_reveal: randao_reveal.get(), - eth1_data: eth1_data.get(), - graffiti: graffiti.get(), - proposer_slashings: proposer_slashings.get(), - attester_slashings: attester_slashings.get(), - attestations: attestations.get(), - deposits: deposits.get(), - voluntary_exits: voluntary_exits.get(), - sync_aggregate: sync_aggregate.get(), - ) - ) - copy_ep_bellatrix(value.bellatrixBody.execution_payload) - of ConsensusFork.Capella: - value = RestPublishedBeaconBlockBody( - kind: ConsensusFork.Capella, - capellaBody: capella.BeaconBlockBody( - randao_reveal: randao_reveal.get(), - eth1_data: eth1_data.get(), - graffiti: graffiti.get(), - proposer_slashings: proposer_slashings.get(), - attester_slashings: attester_slashings.get(), - attestations: attestations.get(), - deposits: deposits.get(), - voluntary_exits: voluntary_exits.get(), - sync_aggregate: sync_aggregate.get(), - bls_to_execution_changes: bls_to_execution_changes.get() - ) - ) - copy_ep_bellatrix(value.capellaBody.execution_payload) - assign( - value.capellaBody.execution_payload.withdrawals, - ep_src.withdrawals.get()) - of ConsensusFork.Deneb: - value = RestPublishedBeaconBlockBody( - kind: ConsensusFork.Deneb, - denebBody: deneb.BeaconBlockBody( - randao_reveal: randao_reveal.get(), - eth1_data: eth1_data.get(), - graffiti: graffiti.get(), - proposer_slashings: proposer_slashings.get(), - attester_slashings: attester_slashings.get(), - attestations: attestations.get(), - deposits: deposits.get(), - voluntary_exits: voluntary_exits.get(), - sync_aggregate: sync_aggregate.get(), - bls_to_execution_changes: bls_to_execution_changes.get(), - blob_kzg_commitments: blob_kzg_commitments.get() - ) - ) - copy_ep_bellatrix(value.denebBody.execution_payload) - assign( - value.denebBody.execution_payload.withdrawals, - ep_src.withdrawals.get()) - assign( - value.denebBody.execution_payload.blob_gas_used, - ep_src.blob_gas_used.get()) - assign( - value.denebBody.execution_payload.excess_blob_gas, - ep_src.excess_blob_gas.get()) - of ConsensusFork.Electra: - value = RestPublishedBeaconBlockBody( - kind: ConsensusFork.Electra, - electraBody: electra.BeaconBlockBody( - randao_reveal: randao_reveal.get(), - eth1_data: eth1_data.get(), - graffiti: graffiti.get(), - proposer_slashings: proposer_slashings.get(), - #attester_slashings: attester_slashings.get(), - #attestations: attestations.get(), - deposits: deposits.get(), - voluntary_exits: voluntary_exits.get(), - sync_aggregate: sync_aggregate.get(), - bls_to_execution_changes: bls_to_execution_changes.get(), - blob_kzg_commitments: blob_kzg_commitments.get() - ) - ) - copy_ep_bellatrix(value.electraBody.execution_payload) - assign( - value.electraBody.execution_payload.withdrawals, - ep_src.withdrawals.get()) - assign( - value.electraBody.execution_payload.blob_gas_used, - ep_src.blob_gas_used.get()) - assign( - value.electraBody.execution_payload.excess_blob_gas, - ep_src.excess_blob_gas.get()) - - debugComment "electra support missing, including attslashing/atts" - -## RestPublishedBeaconBlock -proc readValue*(reader: var JsonReader[RestJson], - value: var RestPublishedBeaconBlock) {. - raises: [IOError, SerializationError].} = - var - slot: Opt[Slot] - proposer_index: Opt[uint64] - parent_root: Opt[Eth2Digest] - state_root: Opt[Eth2Digest] - blockBody: Opt[RestPublishedBeaconBlockBody] - - for fieldName in readObjectFields(reader): - case fieldName - of "slot": - if slot.isSome(): - reader.raiseUnexpectedField("Multiple `slot` fields found", - "RestPublishedBeaconBlock") - slot = Opt.some(reader.readValue(Slot)) - of "proposer_index": - if proposer_index.isSome(): - reader.raiseUnexpectedField("Multiple `proposer_index` fields found", - "RestPublishedBeaconBlock") - proposer_index = Opt.some(reader.readValue(uint64)) - of "parent_root": - if parent_root.isSome(): - reader.raiseUnexpectedField("Multiple `parent_root` fields found", - "RestPublishedBeaconBlock") - parent_root = Opt.some(reader.readValue(Eth2Digest)) - of "state_root": - if state_root.isSome(): - reader.raiseUnexpectedField("Multiple `state_root` fields found", - "RestPublishedBeaconBlock") - state_root = Opt.some(reader.readValue(Eth2Digest)) - of "body": - if blockBody.isSome(): - reader.raiseUnexpectedField("Multiple `body` fields found", - "RestPublishedBeaconBlock") - blockBody = Opt.some(reader.readValue(RestPublishedBeaconBlockBody)) - else: - unrecognizedFieldWarning(fieldName, typeof(value).name) - - if slot.isNone(): - reader.raiseUnexpectedValue("Field `slot` is missing") - if proposer_index.isNone(): - reader.raiseUnexpectedValue("Field `proposer_index` is missing") - if parent_root.isNone(): - reader.raiseUnexpectedValue("Field `parent_root` is missing") - if state_root.isNone(): - reader.raiseUnexpectedValue("Field `state_root` is missing") - if blockBody.isNone(): - reader.raiseUnexpectedValue("Field `body` is missing") - - let body = blockBody.get() - value = RestPublishedBeaconBlock( - case body.kind - of ConsensusFork.Phase0: - ForkedBeaconBlock.init( - phase0.BeaconBlock( - slot: slot.get(), - proposer_index: proposer_index.get(), - parent_root: parent_root.get(), - state_root: state_root.get(), - body: body.phase0Body - ) - ) - of ConsensusFork.Altair: - ForkedBeaconBlock.init( - altair.BeaconBlock( - slot: slot.get(), - proposer_index: proposer_index.get(), - parent_root: parent_root.get(), - state_root: state_root.get(), - body: body.altairBody - ) - ) - of ConsensusFork.Bellatrix: - ForkedBeaconBlock.init( - bellatrix.BeaconBlock( - slot: slot.get(), - proposer_index: proposer_index.get(), - parent_root: parent_root.get(), - state_root: state_root.get(), - body: body.bellatrixBody - ) - ) - of ConsensusFork.Capella: - ForkedBeaconBlock.init( - capella.BeaconBlock( - slot: slot.get(), - proposer_index: proposer_index.get(), - parent_root: parent_root.get(), - state_root: state_root.get(), - body: body.capellaBody - ) - ) - of ConsensusFork.Deneb: - ForkedBeaconBlock.init( - deneb.BeaconBlock( - slot: slot.get(), - proposer_index: proposer_index.get(), - parent_root: parent_root.get(), - state_root: state_root.get(), - body: body.denebBody - ) - ) - of ConsensusFork.Electra: - ForkedBeaconBlock.init( - electra.BeaconBlock( - slot: slot.get(), - proposer_index: proposer_index.get(), - parent_root: parent_root.get(), - state_root: state_root.get(), - body: body.electraBody - ) - ) - ) - -## RestPublishedSignedBeaconBlock -proc readValue*(reader: var JsonReader[RestJson], - value: var RestPublishedSignedBeaconBlock) {. - raises: [IOError, SerializationError].} = - var signature: Opt[ValidatorSig] - var message: Opt[RestPublishedBeaconBlock] - for fieldName in readObjectFields(reader): - case fieldName - of "message": - if message.isSome(): - reader.raiseUnexpectedField("Multiple `message` fields found", - "RestPublishedSignedBeaconBlock") - message = Opt.some(reader.readValue(RestPublishedBeaconBlock)) - of "signature": - if signature.isSome(): - reader.raiseUnexpectedField("Multiple `signature` fields found", - "RestPublishedSignedBeaconBlock") - signature = Opt.some(reader.readValue(ValidatorSig)) - else: - unrecognizedFieldWarning(fieldName, typeof(value).name) - - if signature.isNone(): - reader.raiseUnexpectedValue("Field `signature` is missing") - if message.isNone(): - reader.raiseUnexpectedValue("Field `message` is missing") - - let blck = ForkedBeaconBlock(message.get()) - value = RestPublishedSignedBeaconBlock ForkedSignedBeaconBlock.init( - blck, blck.hash_tree_root(), signature.get()) - -proc readValue*(reader: var JsonReader[RestJson], - value: var RestPublishedSignedBlockContents) {. - raises: [IOError, SerializationError].} = - var signature: Opt[ValidatorSig] - var message: Opt[RestPublishedBeaconBlock] - var signed_message: Opt[RestPublishedSignedBeaconBlock] - var signed_block_data: Opt[JsonString] - var kzg_proofs: Opt[deneb.KzgProofs] - var blobs: Opt[deneb.Blobs] - - # Pre-Deneb, there were always the same two top-level fields - # ('signature' and 'message'). For Deneb, there's a different set of - # a top-level fields: 'signed_block' 'kzg_proofs', `blobs`. The - # former is the same as the pre-Deneb object. - for fieldName in readObjectFields(reader): - case fieldName - of "message": - if message.isSome(): - reader.raiseUnexpectedField("Multiple `message` fields found", - "RestPublishedSignedBlockContents") - message = Opt.some(reader.readValue(RestPublishedBeaconBlock)) - of "signature": - if signature.isSome(): - reader.raiseUnexpectedField("Multiple `signature` fields found", - "RestPublishedSignedBlockContents") - signature = Opt.some(reader.readValue(ValidatorSig)) - of "signed_block": - if signed_block_data.isSome(): - reader.raiseUnexpectedField("Multiple `signed_block` fields found", - "RestPublishedSignedBlockContents") - signed_block_data = Opt.some(reader.readValue(JsonString)) - if message.isSome() or signature.isSome(): - reader.raiseUnexpectedField( - "Found `signed_block` field alongside message or signature fields", - "RestPublishedSignedBlockContents") - signed_message = - try: - Opt.some(RestJson.decode(string(signed_block_data.get()), - RestPublishedSignedBeaconBlock, - requireAllFields = true, - allowUnknownFields = true)) - except SerializationError: - Opt.none(RestPublishedSignedBeaconBlock) - if signed_message.isNone(): - reader.raiseUnexpectedValue("Incorrect signed_block format") - of "kzg_proofs": - if kzg_proofs.isSome(): - reader.raiseUnexpectedField( - "Multiple `kzg_proofs` fields found", - "RestPublishedSignedBlockContents") - if signature.isSome(): - reader.raiseUnexpectedField( - "Found `kzg_proofs` field alongside signature field", - "RestPublishedSignedBlockContents") - kzg_proofs = Opt.some(reader.readValue(deneb.KzgProofs)) - of "blobs": - if blobs.isSome(): - reader.raiseUnexpectedField( - "Multiple `blobs` fields found", - "RestPublishedSignedBlockContents") - if signature.isSome(): - reader.raiseUnexpectedField( - "Found `blobs` field alongside signature field", - "RestPublishedSignedBlockContents") - blobs = Opt.some(reader.readValue(deneb.Blobs)) - else: - unrecognizedFieldWarning(fieldName, typeof(value).name) - - if signed_message.isSome(): - if message.isSome(): - reader.raiseUnexpectedValue("Field `message` found but unsupported") - if signature.isSome(): - reader.raiseUnexpectedValue("Field `signature` found but unsupported") - if kzg_proofs.isNone(): - reader.raiseUnexpectedValue("Field `kzg_proofs` is missing") - if blobs.isNone(): - reader.raiseUnexpectedValue("Field `blobs` is missing") - if kzg_proofs.get.len != blobs.get.len: - reader.raiseUnexpectedValue("Length mismatch of `kzg_proofs` and `blobs`") - - withBlck(distinctBase(signed_message.get)): - when consensusFork >= ConsensusFork.Deneb: - template kzg_commitments: untyped = - forkyBlck.message.body.blob_kzg_commitments - if kzg_proofs.get().len != kzg_commitments.len: - reader.raiseUnexpectedValue( - "Length mismatch of `kzg_proofs` and `blob_kzg_commitments`") - value = RestPublishedSignedBlockContents.init( - consensusFork.BlockContents( - `block`: forkyBlck.message, - kzg_proofs: kzg_proofs.get(), - blobs: blobs.get()), - forkyBlck.root, forkyBlck.signature) - else: - reader.raiseUnexpectedValue("`signed_message` supported post-Deneb") - else: - if signature.isNone(): - reader.raiseUnexpectedValue("Field `signature` is missing") - if message.isNone(): - reader.raiseUnexpectedValue("Field `message` is missing") - if kzg_proofs.isSome(): - reader.raiseUnexpectedValue("Field `kzg_proofs` found but unsupported") - if blobs.isSome(): - reader.raiseUnexpectedValue("Field `blobs` found but unsupported") - - withBlck(distinctBase(message.get)): - when consensusFork < ConsensusFork.Deneb: - value = RestPublishedSignedBlockContents.init( - forkyBlck, forkyBlck.hash_tree_root(), signature.get) - else: - reader.raiseUnexpectedValue("`message` support stopped at Deneb") - ## ForkedSignedBeaconBlock proc readValue*(reader: var JsonReader[RestJson], value: var ForkedSignedBeaconBlock) {. @@ -3378,20 +2852,102 @@ proc decodeBody*( version: string ): Result[RestPublishedSignedBeaconBlock, RestErrorMessage] = if body.contentType == ApplicationJsonMediaType: + let consensusFork = ConsensusFork.decodeString(version).valueOr: + return err(RestErrorMessage.init(Http400, UnableDecodeVersionError, + [version, $error])) let data = - try: - RestJson.decode(body.data, RestPublishedSignedBeaconBlock, - requireAllFields = true, - allowUnknownFields = true) - except SerializationError as exc: - debug "Failed to decode JSON data", - err = exc.formatMsg(""), - data = string.fromBytes(body.data) - return err(RestErrorMessage.init(Http400, UnableDecodeError, - [version, exc.formatMsg("")])) - except CatchableError as exc: - return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, - [version, $exc.msg])) + case consensusFork + of ConsensusFork.Phase0: + try: + let blck = RestJson.decode(body.data, phase0.SignedBeaconBlock, + requireAllFields = true, + allowUnknownFields = true) + RestPublishedSignedBeaconBlock(ForkedSignedBeaconBlock.init(blck)) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + of ConsensusFork.Altair: + try: + let blck = RestJson.decode(body.data, altair.SignedBeaconBlock, + requireAllFields = true, + allowUnknownFields = true) + RestPublishedSignedBeaconBlock(ForkedSignedBeaconBlock.init(blck)) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + of ConsensusFork.Bellatrix: + try: + let blck = RestJson.decode(body.data, bellatrix.SignedBeaconBlock, + requireAllFields = true, + allowUnknownFields = true) + RestPublishedSignedBeaconBlock(ForkedSignedBeaconBlock.init(blck)) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + of ConsensusFork.Capella: + try: + let blck = RestJson.decode(body.data, capella.SignedBeaconBlock, + requireAllFields = true, + allowUnknownFields = true) + RestPublishedSignedBeaconBlock(ForkedSignedBeaconBlock.init(blck)) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + of ConsensusFork.Deneb: + try: + let blck = RestJson.decode(body.data, deneb.SignedBeaconBlock, + requireAllFields = true, + allowUnknownFields = true) + RestPublishedSignedBeaconBlock(ForkedSignedBeaconBlock.init(blck)) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + of ConsensusFork.Electra: + try: + let blck = RestJson.decode(body.data, electra.SignedBeaconBlock, + requireAllFields = true, + allowUnknownFields = true) + RestPublishedSignedBeaconBlock(ForkedSignedBeaconBlock.init(blck)) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + ok(data) elif body.contentType == OctetStreamMediaType: let consensusFork = ConsensusFork.decodeString(version).valueOr: @@ -3474,20 +3030,114 @@ proc decodeBody*( version: string ): Result[RestPublishedSignedBlockContents, RestErrorMessage] = if body.contentType == ApplicationJsonMediaType: + let consensusFork = ConsensusFork.decodeString(version).valueOr: + return err(RestErrorMessage.init(Http400, UnableDecodeVersionError, + [version, $error])) let data = - try: - RestJson.decode(body.data, RestPublishedSignedBlockContents, - requireAllFields = true, - allowUnknownFields = true) - except SerializationError as exc: - debug "Failed to decode JSON data", - err = exc.formatMsg(""), - data = string.fromBytes(body.data) - return err(RestErrorMessage.init(Http400, UnableDecodeError, - [version, exc.formatMsg("")])) - except CatchableError as exc: - return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, - [version, $exc.msg])) + case consensusFork + of ConsensusFork.Phase0: + try: + var res = RestJson.decode(body.data, phase0.SignedBeaconBlock, + requireAllFields = true, + allowUnknownFields = true) + res.root = hash_tree_root(res.message) + RestPublishedSignedBlockContents( + kind: ConsensusFork.Phase0, phase0Data: res) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + of ConsensusFork.Altair: + try: + var res = RestJson.decode(body.data, altair.SignedBeaconBlock, + requireAllFields = true, + allowUnknownFields = true) + res.root = hash_tree_root(res.message) + RestPublishedSignedBlockContents( + kind: ConsensusFork.Altair, altairData: res) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + of ConsensusFork.Bellatrix: + try: + var res = RestJson.decode(body.data, bellatrix.SignedBeaconBlock, + requireAllFields = true, + allowUnknownFields = true) + res.root = hash_tree_root(res.message) + RestPublishedSignedBlockContents( + kind: ConsensusFork.Bellatrix, bellatrixData: res) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + of ConsensusFork.Capella: + try: + var res = RestJson.decode(body.data, capella.SignedBeaconBlock, + requireAllFields = true, + allowUnknownFields = true) + res.root = hash_tree_root(res.message) + RestPublishedSignedBlockContents( + kind: ConsensusFork.Capella, capellaData: res) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + of ConsensusFork.Deneb: + try: + var res = RestJson.decode(body.data, DenebSignedBlockContents, + requireAllFields = true, + allowUnknownFields = true) + res.signed_block.root = hash_tree_root(res.signed_block.message) + RestPublishedSignedBlockContents( + kind: ConsensusFork.Deneb, denebData: res) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + of ConsensusFork.Electra: + try: + var res = RestJson.decode(body.data, ElectraSignedBlockContents, + requireAllFields = true, + allowUnknownFields = true) + res.signed_block.root = hash_tree_root(res.signed_block.message) + RestPublishedSignedBlockContents( + kind: ConsensusFork.Electra, electraData: res) + except SerializationError as exc: + debug "Failed to decode JSON data", + err = exc.formatMsg(""), + data = string.fromBytes(body.data) + return err(RestErrorMessage.init(Http400, UnableDecodeError, + [version, exc.formatMsg("")])) + except CatchableError as exc: + return err(RestErrorMessage.init(Http400, UnexpectedDecodeError, + [version, $exc.msg])) + ok(data) elif body.contentType == OctetStreamMediaType: let consensusFork = ConsensusFork.decodeString(version).valueOr: diff --git a/tests/all_tests.nim b/tests/all_tests.nim index 614428be9e..5c895ec711 100644 --- a/tests/all_tests.nim +++ b/tests/all_tests.nim @@ -56,7 +56,6 @@ import # Unit test ./test_validator_change_pool, ./test_validator_pool, ./test_zero_signature, - ./test_signing_node, ./consensus_spec/all_tests as consensus_all_tests, ./slashing_protection/test_fixtures, ./slashing_protection/test_slashing_protection_db, diff --git a/tests/test_rest_json_serialization.nim b/tests/test_rest_json_serialization.nim index e3d2a7fe91..698f39fc5e 100644 --- a/tests/test_rest_json_serialization.nim +++ b/tests/test_rest_json_serialization.nim @@ -229,18 +229,6 @@ suite "REST JSON encoding and decoding": blck.kzg_proofs.len == 0 blck.blobs.len == 0 - test "RestPublishedSignedBlockContents decoding": - let blck = RestJson.decode( - denebSignedContents, RestPublishedSignedBlockContents, - requireAllFields = true, allowUnknownFields = true).denebData - check: - hash_tree_root(blck.signed_block.message) == Eth2Digest.fromHex( - "0xc67166e600d76d9d129244d10e4f35279d75d800fb39a5ce35e98328d53939da") - blck.signed_block.signature == ValidatorSig.fromHex( - "0x8e2cd6cf4457825818eb380f1ea74f2fc99665041194ab5bcbdbf96f2e22bad4376d2a94f69d762c999ffd500e2525ab0561b01a79158456c83cf5bf0f2104e26f7b0d22f41dcc8f49a0e1cc29bb09aee1c548903fa04bdfcd20603c400d948d")[] - blck.kzg_proofs.len == 0 - blck.blobs.len == 0 - test "KzgCommitment": let zeroString =