Skip to content

Commit 216c2e2

Browse files
committed
Make bench runtime more deterministic
1 parent f3a6533 commit 216c2e2

6 files changed

Lines changed: 43 additions & 32 deletions

File tree

.github/workflows/benchmarks.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ jobs:
1111
# Run benchmarks and stores the output to a file
1212
benchmark:
1313
name: Benchmark
14-
runs-on: ubuntu-latest
14+
# Pin to a specific image to reduce runner-image drift between comparisons.
15+
runs-on: ubuntu-24.04
1516
permissions:
1617
contents: write
1718
steps:

Cargo.lock

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

ledger/benches/dag.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ use snarkvm_utilities::bytes::unchecked_deserialize;
1919

2020
use criterion::{Criterion, criterion_group, criterion_main};
2121

22+
/// Fixed RNG seed so benchmark inputs are reproducible across CI runs.
23+
const BENCH_RNG_SEED: u64 = 0x00BA_6DAB_5EED_00D1;
24+
2225
/// Helper method to benchmark serialization.
2326
fn bench_serialization<T: Serialize + DeserializeOwned + ToBytes + FromBytes + Clone>(
2427
c: &mut Criterion,
@@ -76,7 +79,7 @@ fn bench_serialization<T: Serialize + DeserializeOwned + ToBytes + FromBytes + C
7679
}
7780

7881
fn subdag_serialization(c: &mut Criterion) {
79-
let rng = &mut TestRng::default();
82+
let rng = &mut TestRng::fixed(BENCH_RNG_SEED);
8083
let subdag = sample_subdag(rng);
8184
let batch = subdag.iter().next().unwrap().1.iter().next().unwrap().clone();
8285
let batch_header = batch.batch_header().clone();
@@ -86,10 +89,6 @@ fn subdag_serialization(c: &mut Criterion) {
8689
bench_serialization(c, "Subdag", subdag.clone());
8790
}
8891

89-
criterion_group! {
90-
name = subdag;
91-
config = Criterion::default().sample_size(10);
92-
targets = subdag_serialization
93-
}
92+
criterion_group!(subdag, subdag_serialization);
9493

9594
criterion_main!(subdag);

ledger/benches/transaction.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ type LedgerType = snarkvm_ledger_store::helpers::memory::ConsensusMemory<Mainnet
3636
#[cfg(feature = "rocks")]
3737
type LedgerType = snarkvm_ledger_store::helpers::rocksdb::ConsensusDB<MainnetV0>;
3838

39+
/// Fixed RNG seed so benchmark inputs are reproducible across CI runs.
40+
const BENCH_RNG_SEED: u64 = 0xB34D_CAFE_CDEC_0123;
41+
3942
fn initialize_vm<R: Rng + CryptoRng>(
4043
private_key: &PrivateKey<MainnetV0>,
4144
rng: &mut R,
@@ -60,7 +63,7 @@ fn initialize_vm<R: Rng + CryptoRng>(
6063
}
6164

6265
fn deploy(c: &mut Criterion) {
63-
let rng = &mut TestRng::default();
66+
let rng = &mut TestRng::fixed(BENCH_RNG_SEED);
6467

6568
// Sample a new private key and address.
6669
let private_key = PrivateKey::<MainnetV0>::new(rng).unwrap();
@@ -93,7 +96,7 @@ function hello:
9396
}
9497

9598
fn execute(c: &mut Criterion) {
96-
let rng = &mut TestRng::default();
99+
let rng = &mut TestRng::fixed(BENCH_RNG_SEED ^ 1);
97100

98101
// Sample a new private key and address.
99102
let private_key = PrivateKey::<MainnetV0>::new(rng).unwrap();
@@ -135,8 +138,12 @@ fn execute(c: &mut Criterion) {
135138

136139
// Bench the Transaction.write_le method using the LimitedWriter.
137140
c.bench_function("LimitedWriter::new - transfer_public", |b| {
141+
let max = MainnetV0::LATEST_MAX_TRANSACTION_SIZE();
138142
let mut buffer = Vec::with_capacity(3000);
139-
b.iter(|| transaction.write_le(LimitedWriter::new(&mut buffer, MainnetV0::LATEST_MAX_TRANSACTION_SIZE())))
143+
b.iter(|| {
144+
buffer.clear();
145+
transaction.write_le(LimitedWriter::new(&mut buffer, max))
146+
})
140147
});
141148

142149
// Bench the execution of transfer_public.
@@ -181,8 +188,12 @@ fn execute(c: &mut Criterion) {
181188

182189
// Bench the Transaction.write_le method using the LimitedWriter.
183190
c.bench_function("LimitedWriter::new - transfer_private", |b| {
191+
let max = MainnetV0::LATEST_MAX_TRANSACTION_SIZE();
184192
let mut buffer = Vec::with_capacity(3000);
185-
b.iter(|| transaction.write_le(LimitedWriter::new(&mut buffer, MainnetV0::LATEST_MAX_TRANSACTION_SIZE())))
193+
b.iter(|| {
194+
buffer.clear();
195+
transaction.write_le(LimitedWriter::new(&mut buffer, max))
196+
})
186197
});
187198

188199
// Bench the check_transaction method.
@@ -270,21 +281,24 @@ function main:
270281

271282
// Bench the Transaction.write_le method using the LimitedWriter.
272283
c.bench_function("LimitedWriter::new - too_big.aleo", |b| {
273-
let mut buffer = Vec::with_capacity(MainnetV0::LATEST_MAX_TRANSACTION_SIZE());
274-
b.iter(|| transaction.write_le(LimitedWriter::new(&mut buffer, MainnetV0::LATEST_MAX_TRANSACTION_SIZE())))
284+
let max = MainnetV0::LATEST_MAX_TRANSACTION_SIZE();
285+
let mut buffer = Vec::with_capacity(max);
286+
b.iter(|| {
287+
buffer.clear();
288+
transaction.write_le(LimitedWriter::new(&mut buffer, max))
289+
})
275290
});
276291

277-
// Bench the check_transaction method.
278-
c.bench_function("Transaction::Execute(too_big.aleo) - verify", |b| {
279-
b.iter(|| vm.check_transaction(&transaction, None, rng))
292+
// At genesis height the active cap is V1 (128 KiB); this transaction exceeds it and rejects before full verification.
293+
c.bench_function("Transaction::Execute(too_big.aleo) - oversize_reject", |b| {
294+
b.iter(|| {
295+
vm.check_transaction(&transaction, None, rng)
296+
.expect_err("transaction must exceed V1 MAX_TRANSACTION_SIZE at genesis height");
297+
})
280298
});
281299
}
282300
}
283301

284-
criterion_group! {
285-
name = transaction;
286-
config = Criterion::default().sample_size(10);
287-
targets = deploy, execute
288-
}
302+
criterion_group!(transaction, deploy, execute);
289303

290304
criterion_main!(transaction);

ledger/narwhal/batch-header/Cargo.toml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ edition = "2024"
2727
default = [ "rayon" ]
2828
serial = [ "snarkvm-console/serial" ]
2929
wasm = [ "snarkvm-console/wasm" ]
30-
test-helpers = [ "snarkvm-ledger-narwhal-transmission-id/test-helpers", "time" ]
30+
test-helpers = [ "snarkvm-ledger-narwhal-transmission-id/test-helpers" ]
3131

3232
[dependencies.snarkvm-console]
3333
workspace = true
@@ -47,10 +47,6 @@ optional = true
4747
workspace = true
4848
features = [ "preserve_order" ]
4949

50-
[dependencies.time]
51-
workspace = true
52-
optional = true
53-
5450
[dev-dependencies.bincode]
5551
workspace = true
5652

ledger/narwhal/batch-header/src/lib.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,11 @@ impl<N: Network> BatchHeader<N> {
273273
#[cfg(any(test, feature = "test-helpers"))]
274274
pub mod test_helpers {
275275
use super::*;
276-
use console::{account::PrivateKey, network::MainnetV0, prelude::TestRng};
277-
278-
use time::OffsetDateTime;
276+
use console::{
277+
account::PrivateKey,
278+
network::MainnetV0,
279+
prelude::{TestRng, Uniform},
280+
};
279281

280282
type CurrentNetwork = MainnetV0;
281283

@@ -322,8 +324,8 @@ pub mod test_helpers {
322324
let transmission_ids = snarkvm_ledger_narwhal_transmission_id::test_helpers::sample_transmission_ids(rng)
323325
.into_iter()
324326
.collect::<IndexSet<_>>();
325-
// Checkpoint the timestamp for the batch.
326-
let timestamp = OffsetDateTime::now_utc().unix_timestamp();
327+
// Derive the timestamp from the RNG so sample data is reproducible for a fixed seed.
328+
let timestamp = i64::rand(rng);
327329
// Return the batch header.
328330
BatchHeader::new(private_key, round, timestamp, committee_id, transmission_ids, previous_certificate_ids, rng)
329331
.unwrap()

0 commit comments

Comments
 (0)