Skip to content

Commit 9aa77c5

Browse files
authored
Sim rs 1.3 (#525)
* sim-rs: fix warnings from rust 1.89 * sim-rs: use latest CIP timings * sim-rs: RBs don't have both TXs and endorsements * sim-rs: do not produce empty EBs * sim-rs: update linear leios docs * sim-rs: bump version to 1.3.0
1 parent cd5d190 commit 9aa77c5

File tree

12 files changed

+148
-117
lines changed

12 files changed

+148
-117
lines changed

sim-rs/CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Changelog
22

3+
## v1.3.0
4+
5+
### Linear Leios
6+
7+
- Respect timings according to the latest CIP draft:
8+
- RB headers must be received within `Delta_header`
9+
- Voting must wait until `3 * Delta_header`
10+
- Voting must finish by `3 * Delta_header + L_vote`
11+
- EB cannot be referenced until after `3 * Delta_header + L_vote + L_diff`
12+
- Don't include transactions directly in an RB if it also includes an endorsement
13+
- Don't produce empty EBs
14+
15+
### Other
16+
17+
- Fix linter warnings from newer rust version
18+
319
## v1.2.0
420

521
### All Leios variants

sim-rs/Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sim-rs/implementations/LINEAR_LEIOS.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ The log file schema is currently identical to every other variant (though `pipel
77

88
## Description
99

10-
Whenever a node creates an RB, it also creates an EB. The RB header contains a reference to this new EB. If the RB producer has a certificate for the parent RB’s EB, it will include that certificate in the RB body.
10+
Whenever a node creates an RB, it also has an opportunity to create an EB (though it will not produce empty EBs). The RB header contains a reference to this new EB. If the RB producer has a certificate for the parent RB’s EB, and at least `3 * Δhdr + L_vote + L_diff` has passed since that RB was created, it will include that certificate in the RB body.
1111

1212
RB headers are diffused separately from bodies. When a node receives an RB header, it checks whether that RB should be the new head of its chain. If so, it will request the RB body and the referenced EB (from the first peer which announces them).
1313

@@ -36,17 +36,17 @@ A node will wait at least `3 * Δhdr` after an EB was created before voting for
3636
For a node to vote for an EB, all of the following must be true.
3737
- The RB which announced that EB is currently the head of that node's chain.
3838
- The node received the relevant RB header at most `Δhdr` after it was created.
39-
- The node received the EB body itself at most `L_vote` after it was created.
39+
- The node finished validating the EB body itself at most `3 * Δhdr` + `L_vote` after it was created.
4040

4141
## Mempool behavior
4242

4343
When a node creates an RB, it will follow these steps in order:
4444
1. Try to produce a cert for the parent RB's EB.
4545
1. If this succeeds, remove all of this EB's transactions from its mempool.
46-
2. Create an empty RB and empty EB.
46+
2. Create an empty RB.
4747
3. If we have received and fully validated the RB, along with all referenced transactions,
4848
1. Fill the RB body with transactions from our mempool
49-
2. Fill the EB with transactions from our mempool WITHOUT removing those transactions from the mempool.
49+
2. Build an EB with transactions from our mempool WITHOUT removing those transactions from the mempool.
5050

5151
When a node receives an RB body, it immediately removes all referenced/conflicting transactions from its mempool. If the RB has an EB certificate, it also removes that EB’s transactions from its mempool. If the certified EB arrives after the RB body, we remove its TXs from the mempool once it arrives.
5252

sim-rs/sim-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sim-cli"
3-
version = "1.2.0"
3+
version = "1.3.0"
44
edition = "2024"
55
default-run = "sim-cli"
66
rust-version = "1.88"

sim-rs/sim-cli/src/events.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,10 @@ impl EventMonitor {
114114
remove_zero_decimal: Some(true),
115115
});
116116

117-
if let Some(path) = &self.output_path {
118-
if let Some(parent) = path.parent() {
119-
fs::create_dir_all(parent).await?;
120-
}
117+
if let Some(path) = &self.output_path
118+
&& let Some(parent) = path.parent()
119+
{
120+
fs::create_dir_all(parent).await?;
121121
}
122122

123123
let mut output = match self.output_path.as_mut() {

sim-rs/sim-core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sim-core"
3-
version = "1.2.0"
3+
version = "1.3.0"
44
edition = "2024"
55
rust-version = "1.88"
66

sim-rs/sim-core/src/clock.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,15 @@ impl ClockBarrier {
116116
self.tasks.clone()
117117
}
118118

119-
pub fn wait_until(&mut self, timestamp: Timestamp) -> Waiter {
119+
pub fn wait_until(&mut self, timestamp: Timestamp) -> Waiter<'_> {
120120
self.wait(Some(timestamp.with_resolution(self.timestamp_resolution)))
121121
}
122122

123-
pub fn wait_forever(&mut self) -> Waiter {
123+
pub fn wait_forever(&mut self) -> Waiter<'_> {
124124
self.wait(None)
125125
}
126126

127-
fn wait(&mut self, until: Option<Timestamp>) -> Waiter {
127+
fn wait(&mut self, until: Option<Timestamp>) -> Waiter<'_> {
128128
let (tx, rx) = oneshot::channel();
129129
let done = until.is_some_and(|ts| ts == self.now())
130130
|| self

sim-rs/sim-core/src/events.rs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ use crate::{
88
clock::{Clock, Timestamp},
99
config::{NodeConfiguration, NodeId},
1010
model::{
11-
Block, BlockId, CpuTaskId, EndorserBlockId, InputBlockId, LinearEndorserBlock,
12-
LinearRankingBlock, NoVoteReason, Transaction, TransactionId, TransactionLostReason,
13-
VoteBundle, VoteBundleId,
11+
Block, BlockId, CpuTaskId, EndorserBlockId, InputBlockId, LinearRankingBlock, NoVoteReason,
12+
Transaction, TransactionId, TransactionLostReason, VoteBundle, VoteBundleId,
1413
},
1514
};
1615

@@ -44,7 +43,7 @@ impl Eq for Node {}
4443

4544
impl PartialOrd for Node {
4645
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
47-
Some(self.id.cmp(&other.id))
46+
Some(self.cmp(other))
4847
}
4948
}
5049

@@ -407,7 +406,7 @@ impl EventTracker {
407406
});
408407
}
409408

410-
pub fn track_linear_rb_generated(&self, rb: &LinearRankingBlock, eb: &LinearEndorserBlock) {
409+
pub fn track_linear_rb_generated(&self, rb: &LinearRankingBlock) {
411410
self.send(Event::RBGenerated {
412411
id: self.to_block(rb.header.id),
413412
slot: rb.header.id.slot,
@@ -431,17 +430,6 @@ impl EventTracker {
431430
}),
432431
transactions: rb.transactions.iter().map(|tx| tx.id).collect(),
433432
});
434-
self.send(Event::EBGenerated {
435-
id: self.to_endorser_block(eb.id()),
436-
slot: eb.slot,
437-
pipeline: 0,
438-
producer: self.to_node(eb.producer),
439-
shard: 0,
440-
size_bytes: eb.bytes,
441-
transactions: eb.txs.iter().map(|tx| BlockRef { id: tx.id }).collect(),
442-
input_blocks: vec![],
443-
endorser_blocks: vec![],
444-
});
445433
}
446434

447435
pub fn track_praos_block_sent(&self, block: &Block, sender: NodeId, recipient: NodeId) {
@@ -649,6 +637,20 @@ impl EventTracker {
649637
});
650638
}
651639

640+
pub fn track_linear_eb_generated(&self, block: &crate::model::LinearEndorserBlock) {
641+
self.send(Event::EBGenerated {
642+
id: self.to_endorser_block(block.id()),
643+
slot: block.slot,
644+
pipeline: 0,
645+
producer: self.to_node(block.producer),
646+
shard: 0,
647+
size_bytes: block.bytes,
648+
transactions: block.txs.iter().map(|tx| BlockRef { id: tx.id }).collect(),
649+
input_blocks: vec![],
650+
endorser_blocks: vec![],
651+
});
652+
}
653+
652654
pub fn track_no_eb_generated(&self, node: NodeId, slot: u64) {
653655
self.send(Event::NoEBGenerated {
654656
node: self.to_node(node),

sim-rs/sim-core/src/model.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub struct LinearRankingBlockHeader {
9090
pub vrf: u64,
9191
pub parent: Option<BlockId>,
9292
pub bytes: u64,
93-
pub eb_announcement: EndorserBlockId,
93+
pub eb_announcement: Option<EndorserBlockId>,
9494
}
9595

9696
#[derive(Clone, Debug)]

sim-rs/sim-core/src/sim/leios.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,12 +1114,12 @@ impl LeiosNode {
11141114
}
11151115

11161116
fn receive_request_ib_header(&mut self, from: NodeId, id: InputBlockId) {
1117-
if let Some(ib) = self.leios.ibs.get(&id) {
1118-
if let Some(header) = ib.header() {
1119-
let have_body = matches!(ib, InputBlockState::Received { .. });
1120-
self.queued
1121-
.send_to(from, SimulationMessage::IBHeader(header.clone(), have_body));
1122-
}
1117+
if let Some(ib) = self.leios.ibs.get(&id)
1118+
&& let Some(header) = ib.header()
1119+
{
1120+
let have_body = matches!(ib, InputBlockState::Received { .. });
1121+
self.queued
1122+
.send_to(from, SimulationMessage::IBHeader(header.clone(), have_body));
11231123
}
11241124
}
11251125

0 commit comments

Comments
 (0)