Use the new strict Json flavors mechanism for RestJson (#5674)

This requires all object types to be explicitly white-listed for
default serialization. The PR makes the minimal changes, although
a number of similar mechanisms in eth2_rest_serialization can now
be removed.
This commit is contained in:
zah 2023-12-19 17:44:27 +02:00 committed by GitHub
parent f125a5c189
commit 29b29e1945
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 245 additions and 34 deletions

View File

@ -96,7 +96,7 @@ type
Eth1BlockNumber* = uint64 Eth1BlockNumber* = uint64
Eth1BlockTimestamp* = uint64 Eth1BlockTimestamp* = uint64
Eth1Block* = ref object Eth1BlockObj* = object
hash*: Eth2Digest hash*: Eth2Digest
number*: Eth1BlockNumber number*: Eth1BlockNumber
timestamp*: Eth1BlockTimestamp timestamp*: Eth1BlockTimestamp
@ -111,6 +111,8 @@ type
## Global deposits count and hash tree root of the entire sequence ## Global deposits count and hash tree root of the entire sequence
## These are computed when the block is added to the chain (see `addBlock`) ## These are computed when the block is added to the chain (see `addBlock`)
Eth1Block* = ref Eth1BlockObj
Eth1Chain* = object Eth1Chain* = object
db: BeaconChainDB db: BeaconChainDB
cfg: RuntimeConfig cfg: RuntimeConfig

View File

@ -104,6 +104,20 @@ type
peerId*: PeerId peerId*: PeerId
connected*: bool connected*: bool
RestJson.useDefaultSerializationFor(
BlockProposalEth1Data,
Eth1BlockObj,
RestChronosMetricsInfo,
RestConnectionInfo,
RestFutureInfo,
RestPeerInfo,
RestPeerInfoTuple,
RestPeerStats,
RestPeerStatus,
RestPubSubPeer,
RestSimplePeer,
)
proc toInfo(node: BeaconNode, peerId: PeerId): RestPeerInfo = proc toInfo(node: BeaconNode, peerId: PeerId): RestPeerInfo =
RestPeerInfo( RestPeerInfo(
peerId: $peerId, peerId: $peerId,

View File

@ -28,6 +28,10 @@ type
connected*: uint64 connected*: uint64
disconnecting*: uint64 disconnecting*: uint64
RestJson.useDefaultSerializationFor(
RestNodePeerCount,
)
proc validateState(states: seq[PeerStateKind]): Result[ConnectionStateSet, proc validateState(states: seq[PeerStateKind]): Result[ConnectionStateSet,
cstring] = cstring] =
var res: set[ConnectionState] var res: set[ConnectionState]

View File

@ -10,8 +10,9 @@
import std/[typetraits, strutils] import std/[typetraits, strutils]
import stew/[assign2, results, base10, byteutils, endians2], presto/common, import stew/[assign2, results, base10, byteutils, endians2], presto/common,
libp2p/peerid, serialization, json_serialization, libp2p/peerid, serialization, json_serialization,
json_serialization/std/[net, sets], stint, json_serialization/std/[net, sets],
chronicles json_serialization/stew/results as jsonSerializationResults,
stint, chronicles
import ".."/[eth2_ssz_serialization, forks, keystore], import ".."/[eth2_ssz_serialization, forks, keystore],
".."/../consensus_object_pools/block_pools_types, ".."/../consensus_object_pools/block_pools_types,
".."/datatypes/[phase0, altair, bellatrix], ".."/datatypes/[phase0, altair, bellatrix],
@ -25,7 +26,8 @@ from ".."/datatypes/deneb import BeaconState
export export
eth2_ssz_serialization, results, peerid, common, serialization, chronicles, eth2_ssz_serialization, results, peerid, common, serialization, chronicles,
json_serialization, net, sets, rest_types, slashing_protection_common json_serialization, net, sets, rest_types, slashing_protection_common,
jsonSerializationResults
from web3/primitives import BlockHash from web3/primitives import BlockHash
export primitives.BlockHash export primitives.BlockHash
@ -36,7 +38,218 @@ func decodeMediaType*(
return err("Missing or incorrect Content-Type") return err("Missing or incorrect Content-Type")
ok contentType.get.mediaType ok contentType.get.mediaType
Json.createFlavor RestJson type
EmptyBody* = object
createJsonFlavor RestJson
RestJson.useDefaultSerializationFor(
AggregateAndProof,
Attestation,
AttestationData,
AttesterSlashing,
BLSToExecutionChange,
BeaconBlockHeader,
BlobSidecar,
BlobsBundle,
Checkpoint,
ContributionAndProof,
DataEnclosedObject,
DataMetaEnclosedObject,
DataOptimisticAndFinalizedObject,
DataOptimisticObject,
DataRootEnclosedObject,
DataVersionEnclosedObject,
DeleteKeystoresBody,
DeleteKeystoresResponse,
DeleteRemoteKeystoresResponse,
DenebSignedBlockContents,
Deposit,
DepositData,
DistributedKeystoreInfo,
EmptyBody,
Eth1Data,
EventBeaconBlockObject,
ExecutionPayloadAndBlobsBundle,
Fork,
GetBlockAttestationsResponse,
GetBlockHeaderResponse,
GetBlockHeadersResponse,
GetDepositContractResponse,
GetDepositSnapshotResponse,
GetDistributedKeystoresResponse,
GetEpochCommitteesResponse,
GetEpochSyncCommitteesResponse,
GetForkChoiceResponse,
GetForkScheduleResponse,
GetGenesisResponse,
GetHeaderResponseCapella,
GetHeaderResponseDeneb,
GetKeystoresResponse,
GetNextWithdrawalsResponse,
GetPoolAttesterSlashingsResponse,
GetPoolProposerSlashingsResponse,
GetPoolVoluntaryExitsResponse,
GetRemoteKeystoresResponse,
GetSpecVCResponse,
GetStateFinalityCheckpointsResponse,
GetStateForkResponse,
GetStateRandaoResponse,
GetStateRootResponse,
GetStateValidatorBalancesResponse,
GetStateValidatorResponse,
GetStateValidatorsResponse,
GetValidatorGasLimitResponse,
HistoricalSummary,
ImportDistributedKeystoresBody,
ImportRemoteKeystoresBody,
IndexedAttestation,
KeymanagerGenericError,
KeystoreInfo,
ListFeeRecipientResponse,
ListGasLimitResponse,
PendingAttestation,
PostKeystoresResponse,
PrepareBeaconProposer,
ProposerSlashing,
RemoteKeystoreInfo,
RemoteSignerInfo,
RequestItemStatus,
RestAttesterDuty,
RestBeaconCommitteeSelection,
RestBeaconStatesCommittees,
RestBeaconStatesFinalityCheckpoints,
RestBlockHeader,
RestBlockHeaderInfo,
RestCommitteeSubscription,
RestContributionAndProof,
RestDepositContract,
RestDepositSnapshot,
RestEpochRandao,
RestEpochSyncCommittee,
RestExecutionPayload,
RestExtraData,
RestGenesis,
RestIndexedErrorMessage,
RestIndexedErrorMessageItem,
RestMetadata,
RestNetworkIdentity,
RestNimbusTimestamp1,
RestNimbusTimestamp2,
RestNode,
RestNodeExtraData,
RestNodePeer,
RestNodeVersion,
RestPeerCount,
RestProposerDuty,
RestRoot,
RestSignedBlockHeader,
RestSignedContributionAndProof,
RestSyncCommitteeContribution,
RestSyncCommitteeDuty,
RestSyncCommitteeMessage,
RestSyncCommitteeSelection,
RestSyncCommitteeSubscription,
RestSyncInfo,
RestValidator,
RestValidatorBalance,
SPDIR,
SPDIR_Meta,
SPDIR_SignedAttestation,
SPDIR_SignedBlock,
SPDIR_Validator,
SetFeeRecipientRequest,
SetGasLimitRequest,
SignedAggregateAndProof,
SignedBLSToExecutionChange,
SignedBeaconBlockHeader,
SignedContributionAndProof,
SignedValidatorRegistrationV1,
SignedVoluntaryExit,
SubmitBlindedBlockResponseCapella,
SubmitBlindedBlockResponseDeneb,
SyncAggregate,
SyncAggregatorSelectionData,
SyncCommittee,
SyncCommitteeContribution,
SyncCommitteeMessage,
TrustedAttestation,
Validator,
ValidatorRegistrationV1,
VoluntaryExit,
Web3SignerAggregationSlotData,
Web3SignerDepositData,
Web3SignerErrorResponse,
Web3SignerForkInfo,
Web3SignerMerkleProof,
Web3SignerRandaoRevealData,
Web3SignerSignatureResponse,
Web3SignerStatusResponse,
Web3SignerSyncCommitteeMessageData,
Web3SignerValidatorRegistration,
Withdrawal,
altair.BeaconBlock,
altair.BeaconBlockBody,
altair.BeaconState,
altair.LightClientBootstrap,
altair.LightClientFinalityUpdate,
altair.LightClientHeader,
altair.LightClientOptimisticUpdate,
altair.LightClientUpdate,
altair.SignedBeaconBlock,
bellatrix.BeaconBlock,
bellatrix.BeaconBlockBody,
bellatrix.BeaconState,
bellatrix.ExecutionPayload,
bellatrix.ExecutionPayloadHeader,
bellatrix.SignedBeaconBlock,
bellatrix_mev.BlindedBeaconBlock,
bellatrix_mev.SignedBlindedBeaconBlock,
capella.BeaconBlock,
capella.BeaconBlockBody,
capella.BeaconState,
capella.ExecutionPayload,
capella.ExecutionPayloadHeader,
capella.LightClientBootstrap,
capella.LightClientFinalityUpdate,
capella.LightClientHeader,
capella.LightClientOptimisticUpdate,
capella.LightClientUpdate,
capella.SignedBeaconBlock,
capella_mev.BlindedBeaconBlock,
capella_mev.BlindedBeaconBlockBody,
capella_mev.BuilderBid,
capella_mev.SignedBlindedBeaconBlock,
capella_mev.SignedBuilderBid,
deneb.BeaconBlock,
deneb.BeaconBlockBody,
deneb.BeaconState,
deneb.BlockContents,
deneb.ExecutionPayload,
deneb.ExecutionPayloadHeader,
deneb.LightClientBootstrap,
deneb.LightClientFinalityUpdate,
deneb.LightClientHeader,
deneb.LightClientOptimisticUpdate,
deneb.LightClientUpdate,
deneb.SignedBeaconBlock,
deneb_mev.BlindedBeaconBlock,
deneb_mev.BlindedBeaconBlockBody,
deneb_mev.BuilderBid,
deneb_mev.SignedBlindedBeaconBlock,
deneb_mev.SignedBuilderBid,
phase0.BeaconBlock,
phase0.BeaconBlockBody,
phase0.BeaconState,
phase0.SignedBeaconBlock,
)
# TODO
# Tuples are widely used in the responses of the REST server
# If we switch to concrete types there, it would be possible
# to remove this overly generic definition.
template writeValue*(w: JsonWriter[RestJson], value: tuple) =
writeRecordValue(w, value)
## The RestJson format implements JSON serialization in the way specified ## The RestJson format implements JSON serialization in the way specified
## by the Beacon API: ## by the Beacon API:
@ -84,8 +297,6 @@ const
UnexpectedDecodeError = "Unexpected decoding error" UnexpectedDecodeError = "Unexpected decoding error"
type type
EmptyBody* = object
EncodeTypes* = EncodeTypes* =
AttesterSlashing | AttesterSlashing |
DeleteKeystoresBody | DeleteKeystoresBody |
@ -3087,37 +3298,12 @@ proc writeValue*(
writer.writeField("execution_optimistic", value.optimistic.get()) writer.writeField("execution_optimistic", value.optimistic.get())
writer.endRecord() writer.endRecord()
## EventBeaconBlockObject
proc writeValue*(
writer: var JsonWriter[RestJson], value: EventBeaconBlockObject
) {.raises: [IOError].} =
writer.beginRecord()
writer.writeField("slot", value.slot)
writer.writeField("block", value.block_root)
if value.optimistic.isSome():
writer.writeField("execution_optimistic", value.optimistic.get())
writer.endRecord()
## RestNodeValidity ## RestNodeValidity
proc writeValue*( proc writeValue*(
writer: var JsonWriter[RestJson], value: RestNodeValidity writer: var JsonWriter[RestJson], value: RestNodeValidity
) {.raises: [IOError].} = ) {.raises: [IOError].} =
writer.writeValue($value) writer.writeValue($value)
## RestSyncInfo
proc writeValue*(
writer: var JsonWriter[RestJson], value: RestSyncInfo
) {.raises: [IOError].} =
writer.beginRecord()
writer.writeField("head_slot", value.head_slot)
writer.writeField("sync_distance", value.sync_distance)
writer.writeField("is_syncing", value.is_syncing)
if value.is_optimistic.isSome():
writer.writeField("is_optimistic", value.is_optimistic.get())
if value.el_offline.isSome():
writer.writeField("el_offline", value.el_offline.get())
writer.endRecord()
## RestErrorMessage ## RestErrorMessage
proc readValue*(reader: var JsonReader[RestJson], proc readValue*(reader: var JsonReader[RestJson],
value: var RestErrorMessage) {. value: var RestErrorMessage) {.

View File

@ -316,6 +316,11 @@ type
SyncCommitteeBitsObject = object SyncCommitteeBitsObject = object
data: SyncCommitteeAggregationBits data: SyncCommitteeAggregationBits
RestJson.useDefaultSerializationFor(
AttestationBitsObject,
SyncCommitteeBitsObject
)
const const
AttestationDataVectors = [ AttestationDataVectors = [
# Attestation score with block monitoring enabled (perfect). # Attestation score with block monitoring enabled (perfect).

@ -1 +1 @@
Subproject commit 85b7ea093cb85ee4f433a617b97571bd709d30df Subproject commit 1693db7a57b839f12ffd27d4b7ffec622723ef77

@ -1 +1 @@
Subproject commit 543b2f3dd0724f7cf631feba6c2a3ec438f3d230 Subproject commit 68722b14fc7856045eb787150c1c0b95553ba62b