diff --git a/node/src/components/binary_port/metrics.rs b/node/src/components/binary_port/metrics.rs index eea149414a..e672e90341 100644 --- a/node/src/components/binary_port/metrics.rs +++ b/node/src/components/binary_port/metrics.rs @@ -49,7 +49,7 @@ pub(super) struct Metrics { pub(super) binary_port_get_all_values_count: IntCounter, /// Number of `Get::Trie` queries received. pub(super) binary_port_get_trie_count: IntCounter, - /// Number of `Get::Trie` queries received. + /// Number of distinct connections to binary port. pub(super) binary_port_connections_count: IntCounter, registry: Registry, diff --git a/node/src/components/rest_server.rs b/node/src/components/rest_server.rs index 783ab9cc5e..8da7c5a285 100644 --- a/node/src/components/rest_server.rs +++ b/node/src/components/rest_server.rs @@ -25,7 +25,7 @@ mod filters; mod http_server; mod info; -use std::{net::SocketAddr, sync::Arc, time::Duration}; +use std::{net::SocketAddr, sync::Arc}; use datasize::DataSize; use futures::{future::BoxFuture, join, FutureExt}; @@ -184,7 +184,6 @@ where Effects::new() } Event::RestRequest(RestRequest::Status { responder }) => { - let node_uptime = Duration::from_secs(10); let network_name = self.network_name.clone(); async move { let ( @@ -194,7 +193,7 @@ where consensus_status, reactor_state, last_progress, - _duration, + node_uptime, available_block_range, block_sync, ) = join!( @@ -221,7 +220,7 @@ where peers, ChainspecInfo::new(network_name, next_upgrade), consensus_status, - node_uptime, + node_uptime.into(), reactor_state, last_progress.into_inner(), available_block_range, @@ -350,3 +349,47 @@ impl Finalize for RestServer { .boxed() } } + +#[cfg(test)] +mod schema_tests { + use crate::{testing::assert_schema, types::GetStatusResult}; + use schemars::schema_for; + + use super::{GetChainspecResult, GetValidatorChangesResult}; + + #[test] + fn json_schema_status_check() { + let schema_path = format!( + "{}/../resources/test/rest_schema_status.json", + env!("CARGO_MANIFEST_DIR") + ); + assert_schema( + schema_path, + serde_json::to_string_pretty(&schema_for!(GetStatusResult)).unwrap(), + ); + } + + #[test] + fn json_schema_validator_changes_check() { + let schema_path = format!( + "{}/../resources/test/rest_schema_validator_changes.json", + env!("CARGO_MANIFEST_DIR") + ); + assert_schema( + schema_path, + serde_json::to_string_pretty(&schema_for!(GetValidatorChangesResult)).unwrap(), + ); + } + + #[test] + fn json_schema_chainspec_bytes_check() { + let schema_path = format!( + "{}/../resources/test/rest_schema_chainspec_bytes.json", + env!("CARGO_MANIFEST_DIR") + ); + assert_schema( + schema_path, + serde_json::to_string_pretty(&schema_for!(GetChainspecResult)).unwrap(), + ); + } +} diff --git a/node/src/components/storage.rs b/node/src/components/storage.rs index 5d0807faeb..c9346fce0b 100644 --- a/node/src/components/storage.rs +++ b/node/src/components/storage.rs @@ -379,12 +379,6 @@ impl Storage { let approvals_hashes_dbs = VersionedDatabases::new(&env, "approvals_hashes", "versioned_approvals_hashes")?; - let _x: Vec> = vec![ - Box::new(block_header_dbs), - Box::new(block_body_dbs), - Box::new(block_metadata_db), - ]; - let mut db_mapper: HashMap> = HashMap::new(); db_mapper.insert(DbId::Transaction, Box::new(transaction_dbs)); db_mapper.insert(DbId::ExecutionResult, Box::new(execution_result_dbs)); diff --git a/node/src/components/storage/versioned_databases.rs b/node/src/components/storage/versioned_databases.rs index e15bca16fc..4176bfefae 100644 --- a/node/src/components/storage/versioned_databases.rs +++ b/node/src/components/storage/versioned_databases.rs @@ -117,11 +117,11 @@ pub(super) struct VersionedDatabases { /// Legacy form of the data, with the key as `K::Legacy` type (converted to bytes using /// `AsRef<[u8]>`) and the value bincode-encoded. #[data_size(skip)] - pub(crate) legacy: Database, + pub legacy: Database, /// Current form of the data, with the key as `K` bytesrepr-encoded and the value as `V` also /// bytesrepr-encoded. #[data_size(skip)] - pub(crate) current: Database, + pub current: Database, _phantom: PhantomData<(K, V)>, } diff --git a/node/src/reactor/main_reactor/tests/binary_port.rs b/node/src/reactor/main_reactor/tests/binary_port.rs index 41e5bed93a..19693d6553 100644 --- a/node/src/reactor/main_reactor/tests/binary_port.rs +++ b/node/src/reactor/main_reactor/tests/binary_port.rs @@ -535,12 +535,10 @@ fn node_status() -> TestCase { response, Some(PayloadType::NodeStatus), |node_status| { - dbg!(&node_status); !node_status.peers.into_inner().is_empty() && node_status.chainspec_name == "casper-example" && node_status.last_added_block_info.is_some() && node_status.our_public_signing_key.is_some() - && node_status.round_length.is_some() && node_status.block_sync.historical().is_none() && node_status.block_sync.forward().is_none() && matches!(node_status.reactor_state, ReactorState::Validate) diff --git a/resources/test/rest_schema_chainspec_bytes.json b/resources/test/rest_schema_chainspec_bytes.json new file mode 100644 index 0000000000..4ce0a7acc1 --- /dev/null +++ b/resources/test/rest_schema_chainspec_bytes.json @@ -0,0 +1,69 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GetChainspecResult", + "description": "Result for the \"info_get_chainspec\" RPC.", + "type": "object", + "required": [ + "api_version", + "chainspec_bytes" + ], + "properties": { + "api_version": { + "description": "The RPC API version.", + "type": "string" + }, + "chainspec_bytes": { + "description": "The chainspec file bytes.", + "allOf": [ + { + "$ref": "#/definitions/ChainspecRawBytes" + } + ] + } + }, + "definitions": { + "ChainspecRawBytes": { + "description": "The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files.", + "type": "object", + "required": [ + "chainspec_bytes" + ], + "properties": { + "chainspec_bytes": { + "description": "Raw bytes of the current chainspec.toml file.", + "allOf": [ + { + "$ref": "#/definitions/Bytes" + } + ] + }, + "maybe_genesis_accounts_bytes": { + "description": "Raw bytes of the current genesis accounts.toml file.", + "anyOf": [ + { + "$ref": "#/definitions/Bytes" + }, + { + "type": "null" + } + ] + }, + "maybe_global_state_bytes": { + "description": "Raw bytes of the current global_state.toml file.", + "anyOf": [ + { + "$ref": "#/definitions/Bytes" + }, + { + "type": "null" + } + ] + } + } + }, + "Bytes": { + "description": "Hex-encoded bytes.", + "type": "string" + } + } +} \ No newline at end of file diff --git a/resources/test/rest_schema_status.json b/resources/test/rest_schema_status.json new file mode 100644 index 0000000000..aabe624302 --- /dev/null +++ b/resources/test/rest_schema_status.json @@ -0,0 +1,415 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GetStatusResult", + "description": "Result for \"info_get_status\" RPC response.", + "type": "object", + "required": [ + "api_version", + "available_block_range", + "block_sync", + "build_version", + "chainspec_name", + "last_progress", + "peers", + "reactor_state", + "starting_state_root_hash", + "uptime" + ], + "properties": { + "peers": { + "description": "The node ID and network address of each connected peer.", + "allOf": [ + { + "$ref": "#/definitions/Peers" + } + ] + }, + "api_version": { + "description": "The RPC API version.", + "type": "string" + }, + "build_version": { + "description": "The compiled node version.", + "type": "string" + }, + "chainspec_name": { + "description": "The chainspec name.", + "type": "string" + }, + "starting_state_root_hash": { + "description": "The state root hash of the lowest block in the available block range.", + "allOf": [ + { + "$ref": "#/definitions/Digest" + } + ] + }, + "last_added_block_info": { + "description": "The minimal info of the last block from the linear chain.", + "anyOf": [ + { + "$ref": "#/definitions/MinimalBlockInfo" + }, + { + "type": "null" + } + ] + }, + "our_public_signing_key": { + "description": "Our public signing key.", + "anyOf": [ + { + "$ref": "#/definitions/PublicKey" + }, + { + "type": "null" + } + ] + }, + "round_length": { + "description": "The next round length if this node is a validator.", + "anyOf": [ + { + "$ref": "#/definitions/TimeDiff" + }, + { + "type": "null" + } + ] + }, + "next_upgrade": { + "description": "Information about the next scheduled upgrade.", + "anyOf": [ + { + "$ref": "#/definitions/NextUpgrade" + }, + { + "type": "null" + } + ] + }, + "uptime": { + "description": "Time that passed since the node has started.", + "allOf": [ + { + "$ref": "#/definitions/TimeDiff" + } + ] + }, + "reactor_state": { + "description": "The current state of node reactor.", + "allOf": [ + { + "$ref": "#/definitions/ReactorState" + } + ] + }, + "last_progress": { + "description": "Timestamp of the last recorded progress in the reactor.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + }, + "available_block_range": { + "description": "The available block range in storage.", + "allOf": [ + { + "$ref": "#/definitions/AvailableBlockRange" + } + ] + }, + "block_sync": { + "description": "The status of the block synchronizer builders.", + "allOf": [ + { + "$ref": "#/definitions/BlockSynchronizerStatus" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Peers": { + "description": "Map of peer IDs to network addresses.", + "type": "array", + "items": { + "$ref": "#/definitions/PeerEntry" + } + }, + "PeerEntry": { + "description": "Node peer entry.", + "type": "object", + "required": [ + "address", + "node_id" + ], + "properties": { + "node_id": { + "description": "Node id.", + "type": "string" + }, + "address": { + "description": "Node address.", + "type": "string" + } + }, + "additionalProperties": false + }, + "Digest": { + "description": "Hex-encoded hash digest.", + "type": "string" + }, + "MinimalBlockInfo": { + "description": "Minimal info of a `Block`.", + "type": "object", + "required": [ + "creator", + "era_id", + "hash", + "height", + "state_root_hash", + "timestamp" + ], + "properties": { + "hash": { + "$ref": "#/definitions/BlockHash" + }, + "timestamp": { + "$ref": "#/definitions/Timestamp" + }, + "era_id": { + "$ref": "#/definitions/EraId" + }, + "height": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "state_root_hash": { + "$ref": "#/definitions/Digest" + }, + "creator": { + "$ref": "#/definitions/PublicKey" + } + }, + "additionalProperties": false + }, + "BlockHash": { + "description": "Hex-encoded cryptographic hash of a block.", + "allOf": [ + { + "$ref": "#/definitions/Digest" + } + ] + }, + "Timestamp": { + "description": "Timestamp formatted as per RFC 3339", + "type": "string" + }, + "EraId": { + "description": "Era ID newtype.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "PublicKey": { + "description": "Hex-encoded cryptographic public key, including the algorithm tag prefix.", + "examples": [ + { + "name": "SystemPublicKey", + "description": "A pseudo public key, used for example when the system proposes an immediate switch block after a network upgrade rather than a specific validator. Its hex-encoded value is always '00', as is the corresponding pseudo signature's", + "value": "00" + }, + { + "name": "Ed25519PublicKey", + "description": "An Ed25519 public key. Its hex-encoded value begins '01' and is followed by 64 characters", + "value": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c" + }, + { + "name": "Secp256k1PublicKey", + "description": "A secp256k1 public key. Its hex-encoded value begins '02' and is followed by 66 characters", + "value": "0203408e9526316fd1f8def480dd45b2cc72ffd732771c9ceb5d92ffa4051e6ee084" + } + ], + "type": "string" + }, + "TimeDiff": { + "description": "Human-readable duration.", + "type": "string" + }, + "NextUpgrade": { + "description": "Information about the next protocol upgrade.", + "type": "object", + "required": [ + "activation_point", + "protocol_version" + ], + "properties": { + "activation_point": { + "$ref": "#/definitions/ActivationPoint" + }, + "protocol_version": { + "$ref": "#/definitions/ProtocolVersion" + } + } + }, + "ActivationPoint": { + "description": "The first era to which the associated protocol version applies.", + "anyOf": [ + { + "description": "Era id.", + "allOf": [ + { + "$ref": "#/definitions/EraId" + } + ] + }, + { + "description": "Genesis timestamp.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + } + ] + }, + "ProtocolVersion": { + "description": "Casper Platform protocol version", + "type": "string" + }, + "ReactorState": { + "description": "The state of the reactor.", + "oneOf": [ + { + "description": "Get all components and reactor state set up on start.", + "type": "string", + "enum": [ + "Initialize" + ] + }, + { + "description": "Orient to the network and attempt to catch up to tip.", + "type": "string", + "enum": [ + "CatchUp" + ] + }, + { + "description": "Running commit upgrade and creating immediate switch block.", + "type": "string", + "enum": [ + "Upgrading" + ] + }, + { + "description": "Stay caught up with tip.", + "type": "string", + "enum": [ + "KeepUp" + ] + }, + { + "description": "Node is currently caught up and is an active validator.", + "type": "string", + "enum": [ + "Validate" + ] + }, + { + "description": "Node should be shut down for upgrade.", + "type": "string", + "enum": [ + "ShutdownForUpgrade" + ] + } + ] + }, + "AvailableBlockRange": { + "description": "An unbroken, inclusive range of blocks.", + "type": "object", + "required": [ + "high", + "low" + ], + "properties": { + "low": { + "description": "The inclusive lower bound of the range.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "high": { + "description": "The inclusive upper bound of the range.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "BlockSynchronizerStatus": { + "description": "The status of the block synchronizer.", + "type": "object", + "properties": { + "historical": { + "description": "The status of syncing a historical block, if any.", + "anyOf": [ + { + "$ref": "#/definitions/BlockSyncStatus" + }, + { + "type": "null" + } + ] + }, + "forward": { + "description": "The status of syncing a forward block, if any.", + "anyOf": [ + { + "$ref": "#/definitions/BlockSyncStatus" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "BlockSyncStatus": { + "description": "The status of syncing an individual block.", + "type": "object", + "required": [ + "acquisition_state", + "block_hash" + ], + "properties": { + "block_hash": { + "description": "The block hash.", + "allOf": [ + { + "$ref": "#/definitions/BlockHash" + } + ] + }, + "block_height": { + "description": "The height of the block, if known.", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, + "acquisition_state": { + "description": "The state of acquisition of the data associated with the block.", + "type": "string" + } + }, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/resources/test/rest_schema_validator_changes.json b/resources/test/rest_schema_validator_changes.json new file mode 100644 index 0000000000..c7a7340d4e --- /dev/null +++ b/resources/test/rest_schema_validator_changes.json @@ -0,0 +1,146 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GetValidatorChangesResult", + "description": "Result for the \"info_get_validator_changes\" RPC.", + "type": "object", + "required": [ + "api_version", + "changes" + ], + "properties": { + "api_version": { + "description": "The RPC API version.", + "type": "string" + }, + "changes": { + "description": "The validators' status changes.", + "type": "array", + "items": { + "$ref": "#/definitions/JsonValidatorChanges" + } + } + }, + "additionalProperties": false, + "definitions": { + "JsonValidatorChanges": { + "description": "The changes in a validator's status.", + "type": "object", + "required": [ + "public_key", + "status_changes" + ], + "properties": { + "public_key": { + "description": "The public key of the validator.", + "allOf": [ + { + "$ref": "#/definitions/PublicKey" + } + ] + }, + "status_changes": { + "description": "The set of changes to the validator's status.", + "type": "array", + "items": { + "$ref": "#/definitions/JsonValidatorStatusChange" + } + } + }, + "additionalProperties": false + }, + "PublicKey": { + "description": "Hex-encoded cryptographic public key, including the algorithm tag prefix.", + "examples": [ + { + "name": "SystemPublicKey", + "description": "A pseudo public key, used for example when the system proposes an immediate switch block after a network upgrade rather than a specific validator. Its hex-encoded value is always '00', as is the corresponding pseudo signature's", + "value": "00" + }, + { + "name": "Ed25519PublicKey", + "description": "An Ed25519 public key. Its hex-encoded value begins '01' and is followed by 64 characters", + "value": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c" + }, + { + "name": "Secp256k1PublicKey", + "description": "A secp256k1 public key. Its hex-encoded value begins '02' and is followed by 66 characters", + "value": "0203408e9526316fd1f8def480dd45b2cc72ffd732771c9ceb5d92ffa4051e6ee084" + } + ], + "type": "string" + }, + "JsonValidatorStatusChange": { + "description": "A single change to a validator's status in the given era.", + "type": "object", + "required": [ + "era_id", + "validator_change" + ], + "properties": { + "era_id": { + "description": "The era in which the change occurred.", + "allOf": [ + { + "$ref": "#/definitions/EraId" + } + ] + }, + "validator_change": { + "description": "The change in validator status.", + "allOf": [ + { + "$ref": "#/definitions/ValidatorChange" + } + ] + } + }, + "additionalProperties": false + }, + "EraId": { + "description": "Era ID newtype.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "ValidatorChange": { + "description": "A change to a validator's status between two eras.", + "oneOf": [ + { + "description": "The validator got newly added to the validator set.", + "type": "string", + "enum": [ + "Added" + ] + }, + { + "description": "The validator was removed from the validator set.", + "type": "string", + "enum": [ + "Removed" + ] + }, + { + "description": "The validator was banned from this era.", + "type": "string", + "enum": [ + "Banned" + ] + }, + { + "description": "The validator was excluded from proposing new blocks in this era.", + "type": "string", + "enum": [ + "CannotPropose" + ] + }, + { + "description": "We saw the validator misbehave in this era.", + "type": "string", + "enum": [ + "SeenAsFaulty" + ] + } + ] + } + } +} \ No newline at end of file