Skip to content

Commit 72d6cb8

Browse files
committed
modular raptorcast packet assembly
1 parent 7797e97 commit 72d6cb8

File tree

10 files changed

+1472
-5
lines changed

10 files changed

+1472
-5
lines changed

monad-merkle/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ impl MerkleProof {
3636
siblings,
3737
})
3838
}
39+
3940
pub fn compute_root(&self, leaf: &Hash) -> Option<MerkleHash> {
4041
let mut merkle_hash = hash_to_merkle(leaf);
4142
let mut current_idx = Some(self.tree_leaf_idx as usize);

monad-raptorcast/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,9 @@ tracing-subscriber = { workspace = true, features = ["env-filter"] }
5353
name = "raptor_bench"
5454
harness = false
5555

56+
[[bench]]
57+
name = "encode_bench"
58+
harness = false
59+
5660
[[example]]
5761
name = "service"
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
use std::{collections::HashMap, net::SocketAddr, str::FromStr};
2+
3+
use bytes::Bytes;
4+
use criterion::{criterion_group, criterion_main, Criterion, Throughput};
5+
use itertools::Itertools as _;
6+
use monad_crypto::certificate_signature::{CertificateSignature, CertificateSignaturePubKey};
7+
use monad_dataplane::udp::DEFAULT_SEGMENT_SIZE;
8+
use monad_raptorcast::{
9+
packet, udp,
10+
util::{BuildTarget, EpochValidators, Redundancy},
11+
};
12+
use monad_secp::SecpSignature;
13+
use monad_testutil::signing::get_key;
14+
use monad_types::{NodeId, Stake};
15+
16+
pub fn bench(c: &mut Criterion) {
17+
bench_raptorcast(c, "Raptorcast 128K", 128 * 1024, "raptorcast");
18+
bench_raptorcast(c, "Raptorcast 2M", 2 * 1024 * 1024, "raptorcast");
19+
20+
bench_raptorcast(c, "Broadcast 128K", 128 * 1024, "broadcast");
21+
// 2M broadcast yields more than 65535 packets, so we only
22+
// benchmark for 128K.
23+
}
24+
25+
pub fn bench_raptorcast(c: &mut Criterion, name: &str, message_size: usize, target: &str) {
26+
let message: Bytes = vec![123_u8; message_size].into();
27+
28+
let mut group = c.benchmark_group(name);
29+
group.throughput(Throughput::Bytes(message_size as u64));
30+
31+
let (author, build_target, known_addrs) = match target {
32+
"raptorcast" => setup_raptorcast(),
33+
"broadcast" => setup_broadcast(),
34+
_ => panic!("unsupported target"),
35+
};
36+
37+
group.bench_function("udp::build_messages", |b| {
38+
b.iter(|| {
39+
let _ = udp::build_messages(
40+
&author,
41+
DEFAULT_SEGMENT_SIZE, // segment_size
42+
message.clone(),
43+
Redundancy::from_u8(2),
44+
0, // epoch_no
45+
0, // unix_ts_ms
46+
build_target.clone(),
47+
&known_addrs,
48+
);
49+
});
50+
});
51+
52+
group.bench_function("packet::build_messages", |b| {
53+
let (author, build_target, known_addrs) = setup_raptorcast();
54+
55+
b.iter(|| {
56+
let _ = packet::build_messages(
57+
&author,
58+
DEFAULT_SEGMENT_SIZE, // segment_size
59+
message.clone(),
60+
Redundancy::from_u8(2),
61+
0, // epoch_no
62+
0, // unix_ts_ms
63+
build_target.clone(),
64+
&known_addrs,
65+
&mut rand::thread_rng(),
66+
);
67+
});
68+
});
69+
}
70+
71+
type ST = SecpSignature;
72+
type PT = CertificateSignaturePubKey<ST>;
73+
type KeyPair = <ST as CertificateSignature>::KeyPairType;
74+
75+
fn setup_raptorcast() -> (
76+
KeyPair,
77+
BuildTarget<'static, ST>,
78+
HashMap<NodeId<PT>, SocketAddr>,
79+
) {
80+
let mut keys = (0..100).map(get_key::<ST>).collect_vec();
81+
82+
// leak the value to get a 'static reference
83+
let validators = Box::leak(Box::new(EpochValidators {
84+
validators: keys
85+
.iter()
86+
.map(|key| (NodeId::new(key.pubkey()), Stake::ONE))
87+
.collect(),
88+
}));
89+
90+
let addr = SocketAddr::from_str("127.0.0.1:9999").unwrap();
91+
let known_addresses = keys
92+
.iter()
93+
.map(|key| (NodeId::new(key.pubkey()), addr))
94+
.collect();
95+
96+
let author = keys.pop().unwrap();
97+
let epoch_validators = validators.view_without(vec![&NodeId::new(author.pubkey())]);
98+
99+
(
100+
author,
101+
BuildTarget::Raptorcast(epoch_validators),
102+
known_addresses,
103+
)
104+
}
105+
106+
fn setup_broadcast() -> (
107+
KeyPair,
108+
BuildTarget<'static, ST>,
109+
HashMap<NodeId<PT>, SocketAddr>,
110+
) {
111+
let mut keys = (0..100).map(get_key::<ST>).collect_vec();
112+
113+
// leak the value to get a 'static reference
114+
let validators = Box::leak(Box::new(EpochValidators {
115+
validators: keys
116+
.iter()
117+
.map(|key| (NodeId::new(key.pubkey()), Stake::ONE))
118+
.collect(),
119+
}));
120+
121+
let addr = SocketAddr::from_str("127.0.0.1:9999").unwrap();
122+
let known_addresses = keys
123+
.iter()
124+
.map(|key| (NodeId::new(key.pubkey()), addr))
125+
.collect();
126+
127+
let author = keys.pop().unwrap();
128+
let epoch_validators = validators.view_without(vec![&NodeId::new(author.pubkey())]);
129+
130+
(
131+
author,
132+
BuildTarget::Broadcast(epoch_validators.into()),
133+
known_addresses,
134+
)
135+
}
136+
137+
criterion_group!(benches, bench);
138+
criterion_main!(benches);

monad-raptorcast/benches/raptor_bench.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use monad_crypto::hasher::{Hasher, HasherType};
2323
use monad_dataplane::udp::DEFAULT_SEGMENT_SIZE;
2424
use monad_raptor::ManagedDecoder;
2525
use monad_raptorcast::{
26+
packet,
2627
udp::{build_messages, parse_message, MAX_REDUNDANCY, SIGNATURE_CACHE_SIZE},
2728
util::{BuildTarget, EpochValidators, Redundancy},
2829
};
@@ -78,6 +79,49 @@ pub fn criterion_benchmark(c: &mut Criterion) {
7879
});
7980
});
8081

82+
group.bench_function("Encoding (new)", |b| {
83+
let keys = (0_u8..100_u8)
84+
.map(|n| {
85+
let mut hasher = HasherType::new();
86+
hasher.update(n.to_le_bytes());
87+
let mut hash = hasher.hash();
88+
KeyPair::from_bytes(&mut hash.0).unwrap()
89+
})
90+
.collect_vec();
91+
92+
let validators = EpochValidators {
93+
validators: keys
94+
.iter()
95+
.map(|key| (NodeId::new(key.pubkey()), Stake::ONE))
96+
.collect(),
97+
};
98+
99+
let known_addresses = keys
100+
.iter()
101+
.map(|key| {
102+
(
103+
NodeId::new(key.pubkey()),
104+
SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0),
105+
)
106+
})
107+
.collect();
108+
109+
b.iter(|| {
110+
let epoch_validators = validators.view_without(vec![&NodeId::new(keys[0].pubkey())]);
111+
let _ = packet::build_messages::<SecpSignature, _>(
112+
&keys[0],
113+
DEFAULT_SEGMENT_SIZE, // segment_size
114+
message.clone(),
115+
Redundancy::from_u8(2),
116+
0, // epoch_no
117+
0, // unix_ts_ms
118+
BuildTarget::Raptorcast(epoch_validators),
119+
&known_addresses,
120+
&mut rand::thread_rng(),
121+
);
122+
});
123+
});
124+
81125
group.bench_function("Decoding", |b| {
82126
let keys = (0_u8..100_u8)
83127
.map(|n| {

monad-raptorcast/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ use util::{
6666
pub mod config;
6767
pub mod decoding;
6868
pub mod message;
69+
pub mod packet;
6970
pub mod raptorcast_secondary;
7071
pub mod udp;
7172
pub mod util;

0 commit comments

Comments
 (0)