json-rpc: fix crashes on altair+ blocks in certain operations (#2983)
For the v2 interfaces, REST is recommeded instead
This commit is contained in:
parent
1f51331dd3
commit
1da4192f3f
|
@ -384,19 +384,21 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
|
||||||
blockId: string) ->
|
blockId: string) ->
|
||||||
tuple[canonical: bool, header: SignedBeaconBlockHeader]:
|
tuple[canonical: bool, header: SignedBeaconBlockHeader]:
|
||||||
let bd = node.getBlockDataFromBlockId(blockId)
|
let bd = node.getBlockDataFromBlockId(blockId)
|
||||||
# TODO check for Altair blocks and fail, because /v1/
|
return withBlck(bd.data):
|
||||||
let tsbb = bd.data.phase0Block
|
static: doAssert blck.signature is TrustedSig and
|
||||||
static: doAssert tsbb.signature is TrustedSig and
|
sizeof(ValidatorSig) == sizeof(blck.signature)
|
||||||
sizeof(ValidatorSig) == sizeof(tsbb.signature)
|
(
|
||||||
result.header.signature = cast[ValidatorSig](tsbb.signature)
|
canonical: bd.refs.isAncestorOf(node.dag.head),
|
||||||
|
header: SignedBeaconBlockHeader(
|
||||||
result.header.message.slot = tsbb.message.slot
|
message: BeaconBlockHeader(
|
||||||
result.header.message.proposer_index = tsbb.message.proposer_index
|
slot: blck.message.slot,
|
||||||
result.header.message.parent_root = tsbb.message.parent_root
|
proposer_index: blck.message.proposer_index,
|
||||||
result.header.message.state_root = tsbb.message.state_root
|
parent_root: blck.message.parent_root,
|
||||||
result.header.message.body_root = tsbb.message.body.hash_tree_root()
|
state_root: blck.message.state_root,
|
||||||
|
body_root: blck.message.body.hash_tree_root()
|
||||||
result.canonical = bd.refs.isAncestorOf(node.dag.head)
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
rpcServer.rpc("post_v1_beacon_blocks") do (blck: phase0.SignedBeaconBlock) -> int:
|
rpcServer.rpc("post_v1_beacon_blocks") do (blck: phase0.SignedBeaconBlock) -> int:
|
||||||
if not(node.syncManager.inProgress):
|
if not(node.syncManager.inProgress):
|
||||||
|
@ -404,8 +406,6 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
|
||||||
"Beacon node is currently syncing, try again later.")
|
"Beacon node is currently syncing, try again later.")
|
||||||
let head = node.dag.head
|
let head = node.dag.head
|
||||||
if head.slot >= blck.message.slot:
|
if head.slot >= blck.message.slot:
|
||||||
# TODO altair-transition, but not immediate testnet-priority to detect
|
|
||||||
# Altair and fail, since /v1/ doesn't support Altair
|
|
||||||
node.network.broadcastBeaconBlock(ForkedSignedBeaconBlock.init(blck))
|
node.network.broadcastBeaconBlock(ForkedSignedBeaconBlock.init(blck))
|
||||||
# The block failed validation, but was successfully broadcast anyway.
|
# The block failed validation, but was successfully broadcast anyway.
|
||||||
# It was not integrated into the beacon node's database.
|
# It was not integrated into the beacon node's database.
|
||||||
|
@ -415,7 +415,6 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
|
||||||
node, head, AttachedValidator(),
|
node, head, AttachedValidator(),
|
||||||
ForkedSignedBeaconBlock.init(blck))
|
ForkedSignedBeaconBlock.init(blck))
|
||||||
if res == head:
|
if res == head:
|
||||||
# TODO altair-transition, but not immediate testnet-priority
|
|
||||||
node.network.broadcastBeaconBlock(ForkedSignedBeaconBlock.init(blck))
|
node.network.broadcastBeaconBlock(ForkedSignedBeaconBlock.init(blck))
|
||||||
# The block failed validation, but was successfully broadcast anyway.
|
# The block failed validation, but was successfully broadcast anyway.
|
||||||
# It was not integrated into the beacon node''s database.
|
# It was not integrated into the beacon node''s database.
|
||||||
|
@ -427,18 +426,21 @@ proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
|
||||||
|
|
||||||
rpcServer.rpc("get_v1_beacon_blocks_blockId") do (
|
rpcServer.rpc("get_v1_beacon_blocks_blockId") do (
|
||||||
blockId: string) -> phase0.TrustedSignedBeaconBlock:
|
blockId: string) -> phase0.TrustedSignedBeaconBlock:
|
||||||
# TODO detect Altair and fail: /v1/ APIs don't support Altair
|
let blck = node.getBlockDataFromBlockId(blockId).data
|
||||||
return node.getBlockDataFromBlockId(blockId).data.phase0Block
|
if blck.kind == BeaconBlockFork.Phase0:
|
||||||
|
return blck.phase0Block
|
||||||
|
else:
|
||||||
|
raiseNoAltairSupport()
|
||||||
|
|
||||||
rpcServer.rpc("get_v1_beacon_blocks_blockId_root") do (
|
rpcServer.rpc("get_v1_beacon_blocks_blockId_root") do (
|
||||||
blockId: string) -> Eth2Digest:
|
blockId: string) -> Eth2Digest:
|
||||||
# TODO detect Altair and fail: /v1/ APIs don't support Altair
|
return withBlck(node.getBlockDataFromBlockId(blockId).data):
|
||||||
return node.getBlockDataFromBlockId(blockId).data.phase0Block.message.state_root
|
blck.message.state_root
|
||||||
|
|
||||||
rpcServer.rpc("get_v1_beacon_blocks_blockId_attestations") do (
|
rpcServer.rpc("get_v1_beacon_blocks_blockId_attestations") do (
|
||||||
blockId: string) -> seq[TrustedAttestation]:
|
blockId: string) -> seq[TrustedAttestation]:
|
||||||
# TODO detect Altair and fail: /v1/ APIs don't support Altair
|
return withBlck(node.getBlockDataFromBlockId(blockId).data):
|
||||||
return node.getBlockDataFromBlockId(blockId).data.phase0Block.message.body.attestations.asSeq
|
blck.message.body.attestations.asSeq
|
||||||
|
|
||||||
rpcServer.rpc("get_v1_beacon_pool_attestations") do (
|
rpcServer.rpc("get_v1_beacon_pool_attestations") do (
|
||||||
slot: Option[uint64], committee_index: Option[uint64]) ->
|
slot: Option[uint64], committee_index: Option[uint64]) ->
|
||||||
|
|
|
@ -26,7 +26,10 @@ proc installDebugApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
|
||||||
rpcServer.rpc("get_v1_debug_beacon_states_stateId") do (
|
rpcServer.rpc("get_v1_debug_beacon_states_stateId") do (
|
||||||
stateId: string) -> phase0.BeaconState:
|
stateId: string) -> phase0.BeaconState:
|
||||||
withStateForStateId(stateId):
|
withStateForStateId(stateId):
|
||||||
return stateData.data.hbsPhase0.data
|
if stateData.data.beaconStateFork == forkPhase0:
|
||||||
|
return stateData.data.hbsPhase0.data
|
||||||
|
else:
|
||||||
|
raiseNoAltairSupport()
|
||||||
|
|
||||||
rpcServer.rpc("get_v1_debug_beacon_heads") do () -> seq[tuple[root: Eth2Digest, slot: Slot]]:
|
rpcServer.rpc("get_v1_debug_beacon_heads") do () -> seq[tuple[root: Eth2Digest, slot: Slot]]:
|
||||||
return node.dag.heads.mapIt((it.root, it.slot))
|
return node.dag.heads.mapIt((it.root, it.slot))
|
||||||
|
|
|
@ -16,7 +16,11 @@ import
|
||||||
../spec/[forks, helpers],
|
../spec/[forks, helpers],
|
||||||
../spec/eth2_apis/[rpc_types, eth2_json_rpc_serialization]
|
../spec/eth2_apis/[rpc_types, eth2_json_rpc_serialization]
|
||||||
|
|
||||||
export rpc_types, eth2_json_rpc_serialization, blockchain_dag
|
export forks, rpc_types, eth2_json_rpc_serialization, blockchain_dag
|
||||||
|
|
||||||
|
template raiseNoAltairSupport*() =
|
||||||
|
raise (ref ValueError)(msg:
|
||||||
|
"The JSON-RPC interface does not support certain Altair operations due to changes in block structure - see https://nimbus.guide/rest-api.html for full altair support")
|
||||||
|
|
||||||
template withStateForStateId*(stateId: string, body: untyped): untyped =
|
template withStateForStateId*(stateId: string, body: untyped): untyped =
|
||||||
let
|
let
|
||||||
|
|
|
@ -50,9 +50,8 @@ proc installValidatorApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
|
||||||
case blck.kind
|
case blck.kind
|
||||||
of BeaconBlockFork.Phase0:
|
of BeaconBlockFork.Phase0:
|
||||||
return blck.phase0Block
|
return blck.phase0Block
|
||||||
of BeaconBlockFork.Altair, BeaconBlockFork.Merge:
|
else:
|
||||||
raise newException(CatchableError,
|
raiseNoAltairSupport()
|
||||||
"could not retrieve block for altair or merge blocks")
|
|
||||||
|
|
||||||
rpcServer.rpc("post_v1_validator_block") do (body: phase0.SignedBeaconBlock) -> bool:
|
rpcServer.rpc("post_v1_validator_block") do (body: phase0.SignedBeaconBlock) -> bool:
|
||||||
debug "post_v1_validator_block",
|
debug "post_v1_validator_block",
|
||||||
|
|
|
@ -275,7 +275,7 @@ type
|
||||||
|
|
||||||
TrustedBeaconBlockBody* = object
|
TrustedBeaconBlockBody* = object
|
||||||
## A full verified block
|
## A full verified block
|
||||||
randao_reveal*: ValidatorSig
|
randao_reveal*: TrustedSig
|
||||||
eth1_data*: Eth1Data ##\
|
eth1_data*: Eth1Data ##\
|
||||||
## Eth1 data vote
|
## Eth1 data vote
|
||||||
|
|
||||||
|
@ -283,11 +283,11 @@ type
|
||||||
## Arbitrary data
|
## Arbitrary data
|
||||||
|
|
||||||
# Operations
|
# Operations
|
||||||
proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
|
proposer_slashings*: List[TrustedProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
|
||||||
attester_slashings*: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
|
attester_slashings*: List[TrustedAttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
|
||||||
attestations*: List[Attestation, Limit MAX_ATTESTATIONS]
|
attestations*: List[TrustedAttestation, Limit MAX_ATTESTATIONS]
|
||||||
deposits*: List[Deposit, Limit MAX_DEPOSITS]
|
deposits*: List[Deposit, Limit MAX_DEPOSITS]
|
||||||
voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
|
voluntary_exits*: List[TrustedSignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
|
||||||
sync_aggregate*: SyncAggregate
|
sync_aggregate*: SyncAggregate
|
||||||
|
|
||||||
# Execution
|
# Execution
|
||||||
|
|
Loading…
Reference in New Issue