parent
c74b53be2e
commit
4ccc19f5a3
|
@ -97,7 +97,11 @@ impl SimulationApp {
|
||||||
);
|
);
|
||||||
CarnotNode::<FlatOverlay<RoundRobin>>::new(
|
CarnotNode::<FlatOverlay<RoundRobin>>::new(
|
||||||
node_id,
|
node_id,
|
||||||
CarnotSettings::new(nodes, simulation_settings.node_settings.timeout),
|
CarnotSettings::new(
|
||||||
|
nodes,
|
||||||
|
simulation_settings.node_settings.timeout,
|
||||||
|
simulation_settings.record_settings.clone(),
|
||||||
|
),
|
||||||
overlay_settings,
|
overlay_settings,
|
||||||
genesis,
|
genesis,
|
||||||
network_interface,
|
network_interface,
|
||||||
|
|
|
@ -30,12 +30,38 @@ use nomos_consensus::{
|
||||||
network::messages::{NewViewMsg, TimeoutMsg, VoteMsg},
|
network::messages::{NewViewMsg, TimeoutMsg, VoteMsg},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Serialize)]
|
const CURRENT_VIEW: &str = "current_view";
|
||||||
|
const HIGHEST_VOTED_VIEW: &str = "highest_voted_view";
|
||||||
|
const LOCAL_HIGH_QC: &str = "local_high_qc";
|
||||||
|
const SAFE_BLOCKS: &str = "safe_blocks";
|
||||||
|
const LAST_VIEW_TIMEOUT_QC: &str = "last_view_timeout_qc";
|
||||||
|
const LATEST_COMMITTED_BLOCK: &str = "latest_committed_block";
|
||||||
|
const LATEST_COMMITTED_VIEW: &str = "latest_committed_view";
|
||||||
|
const ROOT_COMMITTEE: &str = "root_committee";
|
||||||
|
const PARENT_COMMITTEE: &str = "parent_committee";
|
||||||
|
const CHILD_COMMITTEES: &str = "child_committees";
|
||||||
|
const COMMITTED_BLOCKS: &str = "committed_blocks";
|
||||||
|
|
||||||
|
pub const CARNOT_RECORD_KEYS: &[&str] = &[
|
||||||
|
CURRENT_VIEW,
|
||||||
|
HIGHEST_VOTED_VIEW,
|
||||||
|
LOCAL_HIGH_QC,
|
||||||
|
SAFE_BLOCKS,
|
||||||
|
LAST_VIEW_TIMEOUT_QC,
|
||||||
|
LATEST_COMMITTED_BLOCK,
|
||||||
|
LATEST_COMMITTED_VIEW,
|
||||||
|
ROOT_COMMITTEE,
|
||||||
|
PARENT_COMMITTEE,
|
||||||
|
CHILD_COMMITTEES,
|
||||||
|
COMMITTED_BLOCKS,
|
||||||
|
];
|
||||||
|
|
||||||
|
static RECORD_SETTINGS: std::sync::OnceLock<HashMap<String, bool>> = std::sync::OnceLock::new();
|
||||||
|
|
||||||
pub struct CarnotState {
|
pub struct CarnotState {
|
||||||
current_view: View,
|
current_view: View,
|
||||||
highest_voted_view: View,
|
highest_voted_view: View,
|
||||||
local_high_qc: StandardQc,
|
local_high_qc: StandardQc,
|
||||||
#[serde(serialize_with = "serialize_blocks")]
|
|
||||||
safe_blocks: HashMap<BlockId, Block>,
|
safe_blocks: HashMap<BlockId, Block>,
|
||||||
last_view_timeout_qc: Option<TimeoutQc>,
|
last_view_timeout_qc: Option<TimeoutQc>,
|
||||||
latest_committed_block: Block,
|
latest_committed_block: Block,
|
||||||
|
@ -46,6 +72,81 @@ pub struct CarnotState {
|
||||||
committed_blocks: Vec<BlockId>,
|
committed_blocks: Vec<BlockId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl serde::Serialize for CarnotState {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
use serde::ser::SerializeStruct;
|
||||||
|
if let Some(rs) = RECORD_SETTINGS.get() {
|
||||||
|
let keys = rs
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(k, v)| {
|
||||||
|
if CARNOT_RECORD_KEYS.contains(&k.trim()) && *v {
|
||||||
|
Some(k)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut ser = serializer.serialize_struct("CarnotState", keys.len())?;
|
||||||
|
for k in keys {
|
||||||
|
match k.trim() {
|
||||||
|
CURRENT_VIEW => ser.serialize_field(CURRENT_VIEW, &self.current_view)?,
|
||||||
|
HIGHEST_VOTED_VIEW => {
|
||||||
|
ser.serialize_field(HIGHEST_VOTED_VIEW, &self.highest_voted_view)?
|
||||||
|
}
|
||||||
|
LOCAL_HIGH_QC => ser.serialize_field(LOCAL_HIGH_QC, &self.local_high_qc)?,
|
||||||
|
SAFE_BLOCKS => {
|
||||||
|
#[derive(Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
struct SafeBlockHelper<'a> {
|
||||||
|
#[serde(serialize_with = "serialize_blocks")]
|
||||||
|
safe_blocks: &'a HashMap<BlockId, Block>,
|
||||||
|
}
|
||||||
|
ser.serialize_field(
|
||||||
|
SAFE_BLOCKS,
|
||||||
|
&SafeBlockHelper {
|
||||||
|
safe_blocks: &self.safe_blocks,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
LAST_VIEW_TIMEOUT_QC => {
|
||||||
|
ser.serialize_field(LAST_VIEW_TIMEOUT_QC, &self.last_view_timeout_qc)?
|
||||||
|
}
|
||||||
|
LATEST_COMMITTED_BLOCK => {
|
||||||
|
ser.serialize_field(LATEST_COMMITTED_BLOCK, &self.latest_committed_block)?
|
||||||
|
}
|
||||||
|
LATEST_COMMITTED_VIEW => {
|
||||||
|
ser.serialize_field(LATEST_COMMITTED_VIEW, &self.latest_committed_view)?
|
||||||
|
}
|
||||||
|
ROOT_COMMITTEE => ser.serialize_field(ROOT_COMMITTEE, &self.root_committe)?,
|
||||||
|
PARENT_COMMITTEE => {
|
||||||
|
ser.serialize_field(PARENT_COMMITTEE, &self.parent_committe)?
|
||||||
|
}
|
||||||
|
CHILD_COMMITTEES => {
|
||||||
|
ser.serialize_field(CHILD_COMMITTEES, &self.child_committees)?
|
||||||
|
}
|
||||||
|
COMMITTED_BLOCKS => {
|
||||||
|
ser.serialize_field(COMMITTED_BLOCKS, &self.committed_blocks)?
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ser.end()
|
||||||
|
} else {
|
||||||
|
serializer.serialize_none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CarnotState {
|
||||||
|
const fn keys() -> &'static [&'static str] {
|
||||||
|
CARNOT_RECORD_KEYS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Have to implement this manually because of the `serde_json` will panic if the key of map
|
/// Have to implement this manually because of the `serde_json` will panic if the key of map
|
||||||
/// is not a string.
|
/// is not a string.
|
||||||
fn serialize_blocks<S>(blocks: &HashMap<BlockId, Block>, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize_blocks<S>(blocks: &HashMap<BlockId, Block>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
@ -87,11 +188,20 @@ impl<O: Overlay> From<&Carnot<O>> for CarnotState {
|
||||||
pub struct CarnotSettings {
|
pub struct CarnotSettings {
|
||||||
nodes: Vec<consensus_engine::NodeId>,
|
nodes: Vec<consensus_engine::NodeId>,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
|
record_settings: HashMap<String, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CarnotSettings {
|
impl CarnotSettings {
|
||||||
pub fn new(nodes: Vec<consensus_engine::NodeId>, timeout: Duration) -> Self {
|
pub fn new(
|
||||||
Self { nodes, timeout }
|
nodes: Vec<consensus_engine::NodeId>,
|
||||||
|
timeout: Duration,
|
||||||
|
record_settings: HashMap<String, bool>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
nodes,
|
||||||
|
timeout,
|
||||||
|
record_settings,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,11 +230,12 @@ impl<O: Overlay> CarnotNode<O> {
|
||||||
let engine = Carnot::from_genesis(id, genesis.header().clone(), overlay);
|
let engine = Carnot::from_genesis(id, genesis.header().clone(), overlay);
|
||||||
let state = CarnotState::from(&engine);
|
let state = CarnotState::from(&engine);
|
||||||
let timeout = settings.timeout;
|
let timeout = settings.timeout;
|
||||||
|
RECORD_SETTINGS.get_or_init(|| settings.record_settings.clone());
|
||||||
// pk is generated in an insecure way, but for simulation purpouses using a rng like smallrng is more useful
|
// pk is generated in an insecure way, but for simulation purpouses using a rng like smallrng is more useful
|
||||||
let mut pk_buff = [0; 32];
|
let mut pk_buff = [0; 32];
|
||||||
rng.fill_bytes(&mut pk_buff);
|
rng.fill_bytes(&mut pk_buff);
|
||||||
let random_beacon_pk = PrivateKey::new(pk_buff);
|
let random_beacon_pk = PrivateKey::new(pk_buff);
|
||||||
Self {
|
let mut this = Self {
|
||||||
id,
|
id,
|
||||||
state,
|
state,
|
||||||
settings,
|
settings,
|
||||||
|
@ -133,7 +244,9 @@ impl<O: Overlay> CarnotNode<O> {
|
||||||
event_builder: event_builder::EventBuilder::new(id, timeout),
|
event_builder: event_builder::EventBuilder::new(id, timeout),
|
||||||
engine,
|
engine,
|
||||||
random_beacon_pk,
|
random_beacon_pk,
|
||||||
}
|
};
|
||||||
|
this.state = CarnotState::from(&this.engine);
|
||||||
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn send_message(&self, message: NetworkMessage<CarnotMessage>) {
|
pub(crate) fn send_message(&self, message: NetworkMessage<CarnotMessage>) {
|
||||||
|
|
|
@ -149,6 +149,7 @@ where
|
||||||
leaders_count: _,
|
leaders_count: _,
|
||||||
network_settings: _,
|
network_settings: _,
|
||||||
step_time: _,
|
step_time: _,
|
||||||
|
record_settings: _,
|
||||||
} = settings;
|
} = settings;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
runner_settings,
|
runner_settings,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::network::NetworkSettings;
|
use crate::network::NetworkSettings;
|
||||||
use crate::overlay::OverlaySettings;
|
use crate::overlay::OverlaySettings;
|
||||||
use crate::streaming::StreamSettings;
|
use crate::streaming::StreamSettings;
|
||||||
|
@ -31,6 +33,8 @@ pub struct NodeSettings {
|
||||||
pub struct SimulationSettings {
|
pub struct SimulationSettings {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub wards: Vec<Ward>,
|
pub wards: Vec<Ward>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub record_settings: HashMap<String, bool>,
|
||||||
pub network_settings: NetworkSettings,
|
pub network_settings: NetworkSettings,
|
||||||
pub overlay_settings: OverlaySettings,
|
pub overlay_settings: OverlaySettings,
|
||||||
pub node_settings: NodeSettings,
|
pub node_settings: NodeSettings,
|
||||||
|
|
Loading…
Reference in New Issue