Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion data/simulation/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,21 @@ export interface Config {
* If false, RBs will only contain a cert.
*/
"praos-fallback-enabled": boolean;

// Linear Leios specific configuration
/**
* How long the EB voting stage is allowed to last.
* Should be more than 3x leios-header-diffusion-time-ms.
* Matches L_vote from the paper.
*/
"linear-vote-stage-length-slots": bigint;

/**
* How long after the EB voting stage are votes allowed to diffuse.
* Matches L_diff from the paper.
*/
"linear-diffuse-stage-length-slots": bigint;

// Transaction Configuration
/** Only supported by Rust simulation. */
"tx-generation-distribution": Distribution;
Expand Down Expand Up @@ -155,6 +170,7 @@ export interface Config {
"eb-validation-cpu-time-ms": number;
"eb-size-bytes-constant": bigint;
"eb-size-bytes-per-ib": bigint;
"eb-body-avg-size-bytes": bigint;
/** Only supported by Haskell simulation. */
"eb-diffusion-strategy": DiffusionStrategy;
/** Only supported by Haskell simulation. */
Expand Down Expand Up @@ -198,6 +214,7 @@ export interface Config {
"vote-generation-probability": number;
"vote-generation-cpu-time-ms-constant": number;
"vote-generation-cpu-time-ms-per-ib": number;
"vote-generation-cpu-time-ms-per-tx": number;
"vote-validation-cpu-time-ms": number;
"vote-threshold": bigint;
"vote-bundle-size-bytes-constant": bigint;
Expand Down Expand Up @@ -277,7 +294,9 @@ export enum LeiosVariant {
/** Full Leios Without IBs: EBs reference TXs directly, as well as other EBs */
FullWithoutIbs = "full-without-ibs",
/** Full Leios With TX References: IBs only contain references to TXs instead of the whole body */
FullWithTXReferences = "full-with-tx-references"
FullWithTXReferences = "full-with-tx-references",
/** Linear Leios: Leios with as little concurrency as possible. */
Linear = "linear",
}

export enum MempoolSamplingStrategy {
Expand Down
6 changes: 6 additions & 0 deletions data/simulation/config.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ leios-mempool-aggressive-pruning: false
praos-chain-quality: 40
praos-fallback-enabled: true

linear-vote-stage-length-slots: 5
linear-diffuse-stage-length-slots: 5

################################################################################
# Transaction Configuration
################################################################################
Expand Down Expand Up @@ -132,6 +135,7 @@ eb-generation-probability: 1.5
eb-size-bytes-constant: 240
# IB hash
eb-size-bytes-per-ib: 32
eb-body-avg-size-bytes: 0
# Collecting the IBs to reference and cryptography are the main tasks.
# A comparable task is maybe mempool snapshotting.
# Sec 2.3 Forging, of the benchmark cluster report, lists
Expand Down Expand Up @@ -184,6 +188,8 @@ vote-threshold: 300
vote-generation-cpu-time-ms-constant: 164e-3
# No benchmark yet.
vote-generation-cpu-time-ms-per-ib: 0
# No benchmark yet.
vote-generation-cpu-time-ms-per-tx: 0
# vote-spec#"Verify vote" 0.8*670e-3 + 0.2*1.4
vote-validation-cpu-time-ms: 816e-3
# The `Vote` structure counted in the -per-eb already identifies slot
Expand Down
28 changes: 27 additions & 1 deletion data/simulation/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,13 @@
"type": "object"
},
"LeiosVariant": {
"enum": ["short", "full", "full-without-ibs", "full-with-tx-references"],
"enum": [
"short",
"full",
"full-without-ibs",
"full-with-tx-references",
"linear"
],
"type": "string"
},
"LogNormalDistribution": {
Expand Down Expand Up @@ -143,6 +149,11 @@
"$ref": "#/definitions/CleanupPolicies",
"description": "Only supported by Haskell simulation."
},
"eb-body-avg-size-bytes": {
"additionalProperties": false,
"properties": {},
"type": "number"
},
"eb-diffusion-max-bodies-to-request": {
"additionalProperties": false,
"description": "Only supported by Haskell simulation.",
Expand Down Expand Up @@ -302,6 +313,18 @@
"description": "Determines whether a Leios pipeline has separate Vote (Send) and Vote (Recv) stages.\nIf this is set to `true`, it is recommended to set `leios-stage-active-voting-slots`\nto be equal to `leios-stage-length-slots`.\n\nOnly supported by Haskell simulation.",
"type": "boolean"
},
"linear-diffuse-stage-length-slots": {
"additionalProperties": false,
"description": "How long after the EB voting stage are votes allowed to diffuse.\nMatches L_diff from the paper.",
"properties": {},
"type": "number"
},
"linear-vote-stage-length-slots": {
"additionalProperties": false,
"description": "How long the EB voting stage is allowed to last.\nShould be more than 3x leios-header-diffusion-time-ms.\nMatches L_vote from the paper.",
"properties": {},
"type": "number"
},
"multiplex-mini-protocols": {
"description": "Only supported by Haskell simulation.",
"type": "boolean"
Expand Down Expand Up @@ -435,6 +458,9 @@
"vote-generation-cpu-time-ms-per-ib": {
"type": "number"
},
"vote-generation-cpu-time-ms-per-tx": {
"type": "number"
},
"vote-generation-probability": {
"type": "number"
},
Expand Down
1 change: 1 addition & 0 deletions data/simulation/variants/config.linear.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
leios-variant: linear
30 changes: 30 additions & 0 deletions sim-rs/LINEAR_LEIOS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Linear Leios (rust simulation)

To run it, set `leios-variant` to `linear`.

The log file schema is currently identical to every other variant (though `pipeline` is always 0).

## Description

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.

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).

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.

When a node receives an EB body, it immediately runs a VRF lottery, and if successful, transmits votes for that EB. If the EB has been certified after L_vote + L_diff slots have passed, the node removes all of its transactions from the mempool (under the assumption that the EB will make it on-chain).

## New parameters

|Name|Description|Default value|
|---|---|---|
|`linear-vote-stage-length-slots`|How many slots the EB voting stage is allowed to last. For equivocation protection, this should be at least 3 * delta_hdr (which is currently 1 second).|5|
|`linear-diffuse-stage-length-slots`|How many slots are votes allowed to diffuse.|5|
|`eb-body-avg-size-bytes`|If `simulate-transactions` is false, this controls the size of the EBs we generate.|0|
|`vote-generation-cpu-time-ms-per-tx`|A per-transaction CPU cost to apply when generating new vote bundles.|0|

## Not yet implemented
- Freshest first delivery is not implemented for EBs, though EBs are created infrequently enough that this likely doesn't matter.
- We are not yet applying voting rules; if you’re allowed to vote, you will always vote.
- We are not yet accounting for equivocation.
- Nodes are supposed to wait until the diffuse stage to vote for an EB, they are currently voting as soon as they can.
2 changes: 2 additions & 0 deletions sim-rs/parameters/linear.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
leios-variant: linear
timestamp-resolution-ms: 0.05
4 changes: 3 additions & 1 deletion sim-rs/sim-cli/src/events/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ impl LivenessMonitor {
}
Event::VTBundleGenerated { votes, .. } => {
for (eb_id, count) in &votes.0 {
let eb = self.ebs.get_mut(eb_id).unwrap();
let Some(eb) = self.ebs.get_mut(eb_id) else {
continue;
};
eb.votes += *count as u64;
if eb.votes >= self.vote_threshold {
for ib_id in &eb.ibs {
Expand Down
29 changes: 25 additions & 4 deletions sim-rs/sim-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ pub struct RawParameters {
pub leios_mempool_aggressive_pruning: bool,
pub praos_chain_quality: u64,
pub praos_fallback_enabled: bool,
pub linear_vote_stage_length_slots: u64,
pub linear_diffuse_stage_length_slots: u64,

// Transaction configuration
pub tx_generation_distribution: DistributionConfig,
Expand Down Expand Up @@ -117,10 +119,12 @@ pub struct RawParameters {
pub eb_size_bytes_per_ib: u64,
pub eb_max_age_slots: u64,
pub eb_referenced_txs_max_size_bytes: u64,
pub eb_body_avg_size_bytes: u64,

// Vote configuration
pub vote_generation_probability: f64,
pub vote_generation_cpu_time_ms_constant: f64,
pub vote_generation_cpu_time_ms_per_tx: f64,
pub vote_generation_cpu_time_ms_per_ib: f64,
pub vote_validation_cpu_time_ms: f64,
pub vote_threshold: u64,
Expand Down Expand Up @@ -151,6 +155,7 @@ pub enum LeiosVariant {
Full,
FullWithoutIbs,
FullWithTxReferences,
Linear,
}

#[derive(Debug, Copy, Clone, Deserialize, PartialEq, Eq)]
Expand Down Expand Up @@ -315,7 +320,8 @@ impl From<RawTopology> for Topology {
pub(crate) struct CpuTimeConfig {
pub tx_validation: Duration,
pub rb_generation: Duration,
pub rb_validation_constant: Duration,
pub rb_head_validation: Duration,
pub rb_body_validation_constant: Duration,
pub rb_validation_per_byte: Duration,
pub ib_generation: Duration,
pub ib_head_validation: Duration,
Expand All @@ -324,6 +330,7 @@ pub(crate) struct CpuTimeConfig {
pub eb_generation: Duration,
pub eb_validation: Duration,
pub vote_generation_constant: Duration,
pub vote_generation_per_tx: Duration,
pub vote_generation_per_ib: Duration,
pub vote_validation: Duration,
pub cert_generation_constant: Duration,
Expand All @@ -336,9 +343,9 @@ impl CpuTimeConfig {
Self {
tx_validation: duration_ms(params.tx_validation_cpu_time_ms),
rb_generation: duration_ms(params.rb_generation_cpu_time_ms),
rb_validation_constant: duration_ms(
params.rb_head_validation_cpu_time_ms
+ params.rb_body_legacy_praos_payload_validation_cpu_time_ms_constant,
rb_head_validation: duration_ms(params.rb_head_validation_cpu_time_ms),
rb_body_validation_constant: duration_ms(
params.rb_body_legacy_praos_payload_validation_cpu_time_ms_constant,
),
rb_validation_per_byte: duration_ms(
params.rb_body_legacy_praos_payload_validation_cpu_time_ms_per_byte,
Expand All @@ -354,6 +361,7 @@ impl CpuTimeConfig {
eb_generation: duration_ms(params.eb_generation_cpu_time_ms),
eb_validation: duration_ms(params.eb_validation_cpu_time_ms),
vote_generation_constant: duration_ms(params.vote_generation_cpu_time_ms_constant),
vote_generation_per_tx: duration_ms(params.vote_generation_cpu_time_ms_per_tx),
vote_generation_per_ib: duration_ms(params.vote_generation_cpu_time_ms_per_ib),
vote_validation: duration_ms(params.vote_validation_cpu_time_ms),
cert_generation_constant: duration_ms(params.cert_generation_cpu_time_ms_constant),
Expand Down Expand Up @@ -407,6 +415,10 @@ impl BlockSizeConfig {
self.eb_constant + self.eb_per_ib * (txs + ibs + ebs) as u64
}

pub fn linear_eb(&self, txs: &[Arc<Transaction>]) -> u64 {
self.eb_constant + txs.iter().map(|tx| tx.bytes).sum::<u64>()
}

pub fn vote_bundle(&self, ebs: usize) -> u64 {
self.vote_constant + self.vote_per_eb * ebs as u64
}
Expand Down Expand Up @@ -441,6 +453,7 @@ impl TransactionConfig {
next_id: Arc::new(AtomicU64::new(0)),
ib_size: params.ib_body_avg_size_bytes,
rb_size: params.rb_body_legacy_praos_payload_avg_size_bytes,
eb_size: params.eb_body_avg_size_bytes,
})
}
}
Expand All @@ -462,6 +475,7 @@ pub(crate) struct MockTransactionConfig {
next_id: Arc<AtomicU64>,
pub ib_size: u64,
pub rb_size: u64,
pub eb_size: u64,
}

impl MockTransactionConfig {
Expand Down Expand Up @@ -494,6 +508,7 @@ pub struct SimConfiguration {
pub late_ib_inclusion: bool,
pub variant: LeiosVariant,
pub vote_threshold: u64,
pub(crate) total_stake: u64,
pub(crate) praos_fallback: bool,
pub(crate) header_diffusion_time: Duration,
pub(crate) ib_generation_time: Duration,
Expand All @@ -506,6 +521,8 @@ pub struct SimConfiguration {
pub(crate) eb_generation_probability: f64,
pub(crate) vote_probability: f64,
pub(crate) vote_slot_length: u64,
pub(crate) linear_vote_stage_length: u64,
pub(crate) linear_diffuse_stage_length: u64,
pub(crate) max_block_size: u64,
pub(crate) max_ib_size: u64,
pub(crate) max_eb_size: u64,
Expand Down Expand Up @@ -539,6 +556,7 @@ impl SimConfiguration {
params.ib_shard_period_length_slots
);
}
let total_stake = topology.nodes.iter().map(|n| n.stake).sum();
Ok(Self {
seed: 0,
timestamp_resolution: duration_ms(params.timestamp_resolution_ms),
Expand All @@ -552,6 +570,7 @@ impl SimConfiguration {
max_eb_age: params.eb_max_age_slots,
late_ib_inclusion: params.leios_late_ib_inclusion,
variant: params.leios_variant,
total_stake,
praos_fallback: params.praos_fallback_enabled,
header_diffusion_time: duration_ms(params.leios_header_diffusion_time_ms),
ib_generation_time: duration_ms(params.leios_ib_generation_time_ms),
Expand All @@ -565,6 +584,8 @@ impl SimConfiguration {
vote_probability: params.vote_generation_probability,
vote_threshold: params.vote_threshold,
vote_slot_length: params.leios_stage_active_voting_slots,
linear_vote_stage_length: params.linear_vote_stage_length_slots,
linear_diffuse_stage_length: params.linear_diffuse_stage_length_slots,
max_block_size: params.rb_body_max_size_bytes,
max_ib_size: params.ib_body_max_size_bytes,
max_eb_size: params.eb_referenced_txs_max_size_bytes,
Expand Down
Loading