1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#![allow(clippy::field_reassign_with_default)]
use std::{
collections::BTreeMap,
hash::Hash,
net::{IpAddr, Ipv4Addr, SocketAddr},
};
use once_cell::sync::Lazy;
use schemars::JsonSchema;
use semver::Version;
use serde::{Deserialize, Serialize};
use casper_types::PublicKey;
use crate::{
components::{
chainspec_loader::ChainspecInfo, consensus::EraId, rpc_server::rpcs::docs::DocExample,
},
crypto::hash::Digest,
types::{Block, BlockHash, NodeId, PeersMap, Timestamp},
};
static GET_STATUS_RESULT: Lazy<GetStatusResult> = Lazy::new(|| {
let node_id = NodeId::doc_example();
let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 54321);
let mut peers = BTreeMap::new();
peers.insert(node_id.clone(), socket_addr.to_string());
let status_feed = StatusFeed::<NodeId> {
last_added_block: Some(Block::doc_example().clone()),
peers,
chainspec_info: ChainspecInfo::doc_example().clone(),
version: crate::VERSION_STRING.as_str(),
};
GetStatusResult::from(status_feed)
});
#[derive(Debug, Serialize)]
#[serde(bound = "I: Eq + Hash + Ord + Serialize")]
pub struct StatusFeed<I> {
pub last_added_block: Option<Block>,
pub peers: BTreeMap<I, String>,
pub chainspec_info: ChainspecInfo,
pub version: &'static str,
}
impl<I> StatusFeed<I> {
pub(crate) fn new(
last_added_block: Option<Block>,
peers: BTreeMap<I, String>,
chainspec_info: ChainspecInfo,
) -> Self {
StatusFeed {
last_added_block,
peers,
chainspec_info,
version: crate::VERSION_STRING.as_str(),
}
}
}
#[derive(Serialize, Deserialize, Debug, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct MinimalBlockInfo {
hash: BlockHash,
timestamp: Timestamp,
era_id: EraId,
height: u64,
state_root_hash: Digest,
creator: PublicKey,
}
impl From<Block> for MinimalBlockInfo {
fn from(block: Block) -> Self {
MinimalBlockInfo {
hash: *block.hash(),
timestamp: block.header().timestamp(),
era_id: block.header().era_id(),
height: block.header().height(),
state_root_hash: *block.header().state_root_hash(),
creator: *block.header().proposer(),
}
}
}
#[derive(Serialize, Deserialize, Debug, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct GetStatusResult {
#[schemars(with = "String")]
pub api_version: Version,
pub chainspec_name: String,
pub genesis_root_hash: String,
pub peers: PeersMap,
pub last_added_block_info: Option<MinimalBlockInfo>,
pub build_version: String,
}
impl GetStatusResult {
pub fn set_api_version(&mut self, version: Version) {
self.api_version = version;
}
}
impl DocExample for GetStatusResult {
fn doc_example() -> &'static Self {
&*GET_STATUS_RESULT
}
}
impl From<StatusFeed<NodeId>> for GetStatusResult {
fn from(status_feed: StatusFeed<NodeId>) -> Self {
let chainspec_name = status_feed.chainspec_info.name();
let genesis_root_hash = status_feed
.chainspec_info
.root_hash()
.unwrap_or_default()
.to_string();
let api_version = Version::from((0, 0, 0));
let peers = PeersMap::from(status_feed.peers);
let last_added_block_info = status_feed.last_added_block.map(Into::into);
let build_version = crate::VERSION_STRING.clone();
GetStatusResult {
api_version,
chainspec_name,
genesis_root_hash,
peers,
last_added_block_info,
build_version,
}
}
}