Skip to content

Commit f8ea4d5

Browse files
committed
sim-rs: apply sharding strategy
1 parent af3b54d commit f8ea4d5

File tree

13 files changed

+88
-19
lines changed

13 files changed

+88
-19
lines changed

data/simulation/config.d.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ export interface Config {
5858
"tx-generation-distribution": Distribution;
5959
/** Only supported by Rust simulation. */
6060
"tx-size-bytes-distribution": Distribution;
61+
/**
62+
* What percentage of transactions have at least one sharded input?
63+
*
64+
* Only supported by Rust simulation. */
65+
"tx-sharded-percentage": number;
6166
/** Only supported by Rust simulation. */
6267
"tx-validation-cpu-time-ms": number;
6368
/** Only supported by Rust simulation. */
@@ -76,8 +81,24 @@ export interface Config {
7681
// Input Block Configuration
7782
"ib-generation-probability": number;
7883
"ib-generation-cpu-time-ms": number;
79-
/** Only supported by Rust simulation. */
84+
/**
85+
* The total number of shards available for IBs.
86+
* Must be divisible by ib_shard_group_count.
87+
88+
* Only supported by Rust simulation. */
8089
"ib-shards": number;
90+
/**
91+
* The "m" IB sharding parameter.
92+
* Controls how many slots in a row will use the same list of shards.
93+
*
94+
* Only supported by Rust simulation. */
95+
"ib-shard-period-length-slots": number;
96+
/**
97+
* The "k" IB sharding parameter.
98+
* Controls how many groups of shards are assigned at a time.
99+
100+
* Only supported by Rust simulation. */
101+
"ib-shard-group-count": number;
81102
"ib-head-size-bytes": bigint;
82103
"ib-head-validation-cpu-time-ms": number;
83104
"ib-body-validation-cpu-time-ms-constant": number;

data/simulation/config.default.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ tx-size-bytes-distribution:
4343
distribution: log-normal
4444
mu: 6.833
4545
sigma: 1.127
46+
tx-sharded-percentage: 0.5
4647
tx-validation-cpu-time-ms: 1.5
4748
tx-max-size-bytes: 16384
4849

@@ -74,7 +75,9 @@ rb-body-legacy-praos-payload-validation-cpu-time-ms-per-byte: 0.0005
7475
################################################################################
7576

7677
ib-generation-probability: 5.0
77-
ib-shards: 1
78+
ib-shards: 50
79+
ib-shard-period-length-slots: 5
80+
ib-shard-group-count: 25
7881

7982
# ProducerId 32
8083
# SlotNo 64

data/simulation/config.schema.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,16 @@
243243
"ib-head-validation-cpu-time-ms": {
244244
"type": "number"
245245
},
246+
"ib-shard-group-count": {
247+
"description": "The \"k\" IB sharding parameter.\nControls how many groups of shards are assigned at a time.\n\nOnly supported by Rust simulation.",
248+
"type": "number"
249+
},
250+
"ib-shard-period-length-slots": {
251+
"description": "The \"m\" IB sharding parameter.\nControls how many slots in a row will use the same list of shards.\n\nOnly supported by Rust simulation.",
252+
"type": "number"
253+
},
246254
"ib-shards": {
247-
"description": "Only supported by Rust simulation.",
255+
"description": "The total number of shards available for IBs.\nMust be divisible by ib_shard_group_count.\n\nOnly supported by Rust simulation.",
248256
"type": "number"
249257
},
250258
"leios-header-diffusion-time-ms": {
@@ -335,6 +343,10 @@
335343
"properties": {},
336344
"type": "number"
337345
},
346+
"tx-sharded-percentage": {
347+
"description": "What percentage of transactions have at least one sharded input?\n\nOnly supported by Rust simulation.",
348+
"type": "number"
349+
},
338350
"tx-size-bytes-distribution": {
339351
"$ref": "#/definitions/Distribution",
340352
"description": "Only supported by Rust simulation."

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ impl TraceAggregator {
5959
id,
6060
publisher,
6161
size_bytes,
62+
..
6263
} => {
6364
self.transactions.insert(
6465
id,

sim-rs/sim-cli/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ fn read_config(args: &Args) -> Result<SimConfiguration> {
9090
}
9191

9292
let params: RawParameters = raw_params.extract()?;
93-
let mut config = SimConfiguration::build(params, topology);
93+
let mut config = SimConfiguration::build(params, topology)?;
9494
if let Some(slots) = args.slots {
9595
config.slots = Some(slots);
9696
}

sim-rs/sim-core/src/config.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub struct RawParameters {
6767
// Transaction configuration
6868
pub tx_generation_distribution: DistributionConfig,
6969
pub tx_size_bytes_distribution: DistributionConfig,
70+
pub tx_sharded_percentage: f64,
7071
pub tx_validation_cpu_time_ms: f64,
7172
pub tx_max_size_bytes: u64,
7273

@@ -85,6 +86,8 @@ pub struct RawParameters {
8586
pub ib_generation_probability: f64,
8687
pub ib_generation_cpu_time_ms: f64,
8788
pub ib_shards: u64,
89+
pub ib_shard_period_length_slots: u64,
90+
pub ib_shard_group_count: u64,
8891
pub ib_head_size_bytes: u64,
8992
pub ib_head_validation_cpu_time_ms: f64,
9093
pub ib_body_validation_cpu_time_ms_constant: f64,
@@ -371,6 +374,7 @@ impl TransactionConfig {
371374
if params.simulate_transactions {
372375
Self::Real(RealTransactionConfig {
373376
max_size: params.tx_max_size_bytes,
377+
sharded_percentage: params.tx_sharded_percentage,
374378
frequency_ms: params.tx_generation_distribution.into(),
375379
size_bytes: params.tx_size_bytes_distribution.into(),
376380
})
@@ -387,6 +391,7 @@ impl TransactionConfig {
387391
#[derive(Debug, Clone)]
388392
pub(crate) struct RealTransactionConfig {
389393
pub max_size: u64,
394+
pub sharded_percentage: f64,
390395
pub frequency_ms: FloatDistribution,
391396
pub size_bytes: FloatDistribution,
392397
}
@@ -434,14 +439,23 @@ pub struct SimConfiguration {
434439
pub(crate) ib_diffusion_strategy: DiffusionStrategy,
435440
pub(crate) max_ib_requests_per_peer: usize,
436441
pub(crate) ib_shards: u64,
442+
pub(crate) ib_shard_period_slots: u64,
443+
pub(crate) ib_shard_groups: u64,
437444
pub(crate) cpu_times: CpuTimeConfig,
438445
pub(crate) sizes: BlockSizeConfig,
439446
pub(crate) transactions: TransactionConfig,
440447
}
441448

442449
impl SimConfiguration {
443-
pub fn build(params: RawParameters, topology: Topology) -> Self {
444-
Self {
450+
pub fn build(params: RawParameters, topology: Topology) -> Result<Self> {
451+
if params.ib_shards % params.ib_shard_group_count != 0 {
452+
bail!(
453+
"ib-shards ({}) is not divisible by ib-shard-group-count ({})",
454+
params.ib_shards,
455+
params.ib_shard_group_count
456+
);
457+
}
458+
Ok(Self {
445459
seed: 0,
446460
slots: None,
447461
emit_conformance_events: false,
@@ -467,10 +481,12 @@ impl SimConfiguration {
467481
ib_diffusion_strategy: params.ib_diffusion_strategy,
468482
max_ib_requests_per_peer: params.ib_diffusion_max_bodies_to_request as usize,
469483
ib_shards: params.ib_shards,
484+
ib_shard_period_slots: params.ib_shard_period_length_slots,
485+
ib_shard_groups: params.ib_shard_group_count,
470486
cpu_times: CpuTimeConfig::new(&params),
471487
sizes: BlockSizeConfig::new(&params),
472488
transactions: TransactionConfig::new(&params),
473-
}
489+
})
474490
}
475491
}
476492

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ pub enum Event {
102102
id: TransactionId,
103103
publisher: Node,
104104
size_bytes: u64,
105+
shard: Option<u64>,
105106
},
106107
TXSent {
107108
id: TransactionId,
@@ -158,6 +159,7 @@ pub enum Event {
158159
pipeline: u64,
159160
producer: Node,
160161
index: u64,
162+
shard: u64,
161163
header_bytes: u64,
162164
tx_payload_bytes: u64,
163165
size_bytes: u64,
@@ -417,6 +419,7 @@ impl EventTracker {
417419
id: transaction.id,
418420
publisher: self.to_node(publisher),
419421
size_bytes: transaction.bytes,
422+
shard: transaction.shard,
420423
});
421424
}
422425

@@ -461,6 +464,7 @@ impl EventTracker {
461464
pipeline: block.header.id.pipeline,
462465
producer: self.to_node(block.header.id.producer),
463466
index: block.header.id.index,
467+
shard: block.header.shard,
464468
header_bytes,
465469
tx_payload_bytes,
466470
size_bytes: header_bytes + tx_payload_bytes,

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ id_wrapper!(TransactionId, u64);
8989
#[derive(Debug, Clone, PartialEq, Eq)]
9090
pub struct Transaction {
9191
pub id: TransactionId,
92-
pub shard: u64,
92+
pub shard: Option<u64>,
9393
pub bytes: u64,
9494
}
9595

@@ -125,6 +125,7 @@ impl<Node: Display> Serialize for InputBlockId<Node> {
125125
pub struct InputBlockHeader {
126126
pub id: InputBlockId,
127127
pub vrf: u64,
128+
pub shard: u64,
128129
pub timestamp: Timestamp,
129130
pub bytes: u64,
130131
}

sim-rs/sim-core/src/sim/node.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,8 @@ impl Node {
548548
}
549549
}
550550
for (slot, vrfs) in slot_vrfs {
551+
let shards = self.find_available_ib_shards(slot);
552+
assert!(!shards.is_empty());
551553
let headers = vrfs
552554
.into_iter()
553555
.enumerate()
@@ -559,6 +561,7 @@ impl Node {
559561
index: index as u64,
560562
},
561563
vrf,
564+
shard: shards[vrf as usize % shards.len()],
562565
timestamp: self.clock.now(),
563566
bytes: self.sim_config.sizes.ib_header,
564567
})
@@ -567,6 +570,13 @@ impl Node {
567570
}
568571
}
569572

573+
fn find_available_ib_shards(&self, slot: u64) -> Vec<u64> {
574+
let period = slot / self.sim_config.ib_shard_period_slots;
575+
let group = period % self.sim_config.ib_shard_groups;
576+
let shards_per_group = self.sim_config.ib_shards / self.sim_config.ib_shard_groups;
577+
(group * shards_per_group..(group + 1) * shards_per_group).collect()
578+
}
579+
570580
fn generate_endorser_blocks(&mut self, slot: u64) {
571581
for next_p in vrf_probabilities(self.sim_config.eb_generation_probability) {
572582
if self.run_vrf(next_p).is_some() {
@@ -719,7 +729,7 @@ impl Node {
719729
// Add one transaction, the right size for the extra RB payload
720730
let tx = Transaction {
721731
id: config.next_id(),
722-
shard: 0,
732+
shard: None,
723733
bytes: config.rb_size,
724734
};
725735
self.tracker.track_transaction_generated(&tx, self.id);
@@ -1267,21 +1277,20 @@ impl Node {
12671277
if let TransactionConfig::Mock(config) = &self.sim_config.transactions {
12681278
let tx = Transaction {
12691279
id: config.next_id(),
1270-
shard: 0,
1280+
shard: None,
12711281
bytes: config.ib_size,
12721282
};
12731283
self.tracker.track_transaction_generated(&tx, self.id);
12741284
ib.transactions.push(Arc::new(tx));
12751285
return;
12761286
}
12771287

1278-
let shard = ib.header.vrf % self.sim_config.ib_shards;
12791288
let candidate_txs: Vec<_> = self
12801289
.leios
12811290
.mempool
12821291
.values()
12831292
.filter_map(|tx| {
1284-
if tx.shard == shard {
1293+
if tx.shard.is_none_or(|shard| shard == ib.header.shard) {
12851294
Some((tx.id, tx.bytes))
12861295
} else {
12871296
None

sim-rs/sim-core/src/sim/tx.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ impl TransactionProducer {
4949
let mut rng = &mut self.rng;
5050
loop {
5151
let id = TransactionId::new(next_tx_id);
52-
let shard = rng.random_range(0..self.ib_shards);
52+
let shard = rng
53+
.random_bool(config.sharded_percentage)
54+
.then(|| rng.random_range(0..self.ib_shards));
5355
let bytes = (config.size_bytes.sample(&mut rng) as u64).min(config.max_size);
5456
let tx = Transaction { id, shard, bytes };
5557

0 commit comments

Comments
 (0)