Skip to content

Commit b90f317

Browse files
committed
feat: add a more realistic benchmark with better coverage
1 parent b9c5cc6 commit b90f317

File tree

4 files changed

+126
-66
lines changed

4 files changed

+126
-66
lines changed

Cargo.lock

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

crates/check/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ criterion = { workspace = true, features = ["async_tokio"] }
2020
essential-hash = { workspace = true }
2121
rand = { workspace = true }
2222
secp256k1 = { workspace = true, features = ["rand-std"] }
23+
tokio = { workspace = true, features = ["rt-multi-thread"] }
2324

2425
[features]
2526
tracing = ["dep:essential-hash", "dep:tracing"]

crates/check/benches/check_intents.rs

Lines changed: 113 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,37 @@ use secp256k1::{PublicKey, Secp256k1, SecretKey};
1717

1818
pub fn bench(c: &mut Criterion) {
1919
let config = Arc::new(essential_check::solution::CheckIntentConfig::default());
20-
let runtime = tokio::runtime::Builder::new_current_thread()
21-
.build()
22-
.unwrap();
20+
let runtime = tokio::runtime::Builder::new_multi_thread().build().unwrap();
2321

24-
for i in [1, 10, 100, 1000, 10_000] {
25-
let (intents, solution, intents_map) = create(i);
26-
let get_intent = |addr: &IntentAddress| intents_map.get(addr).cloned().unwrap();
27-
let mut pre_state = State::EMPTY;
28-
pre_state.deploy_namespace(essential_hash::intent_set_addr::from_intents(&intents.data));
29-
let mut post_state = pre_state.clone();
30-
post_state.apply_mutations(&solution);
31-
c.bench_function(&format!("check_42_{}", i), |b| {
32-
b.to_async(&runtime).iter(|| {
33-
essential_check::solution::check_intents(
34-
&pre_state,
35-
&post_state,
36-
solution.clone(),
37-
get_intent,
38-
config.clone(),
39-
)
22+
for (i, num_constraints) in [
23+
(1, &[1, 10, 100, 1000, 10_000][..]),
24+
(10, &[1, 10, 100, 1000]),
25+
(100, &[1, 10, 100]),
26+
(1000, &[1, 10]),
27+
(10_000, &[1]),
28+
] {
29+
for num_constraints in num_constraints {
30+
let (intents, solution, intents_map) = create(i, *num_constraints);
31+
let get_intent = |addr: &IntentAddress| intents_map.get(addr).cloned().unwrap();
32+
let mut pre_state = State::EMPTY;
33+
pre_state
34+
.deploy_namespace(essential_hash::intent_set_addr::from_intents(&intents.data));
35+
let mut post_state = pre_state.clone();
36+
post_state.apply_mutations(&solution);
37+
c.bench_function(&format!("check_42_{}_{}", i, num_constraints), |b| {
38+
b.to_async(&runtime).iter(|| async {
39+
essential_check::solution::check_intents(
40+
&pre_state,
41+
&post_state,
42+
solution.clone(),
43+
get_intent,
44+
config.clone(),
45+
)
46+
.await
47+
.unwrap();
48+
});
4049
});
41-
});
50+
}
4251
}
4352
}
4453

@@ -48,12 +57,13 @@ criterion_main!(benches);
4857
#[allow(clippy::type_complexity)]
4958
fn create(
5059
amount: usize,
60+
num_constraints: usize,
5161
) -> (
5262
Signed<Vec<Intent>>,
5363
Arc<Solution>,
5464
HashMap<IntentAddress, Arc<Intent>>,
5565
) {
56-
let (intents, solution) = test_intent_42_solution_pair(amount, [0; 32]);
66+
let (intents, solution) = test_intent_42_solution_pair(amount, num_constraints, [0; 32]);
5767
let set = intent_set_addr(&intents);
5868
let intents_map: HashMap<_, _> = intents
5969
.data
@@ -172,49 +182,78 @@ impl StateRead for State {
172182
}
173183
}
174184

175-
fn test_intent_42(entropy: Word) -> Intent {
185+
fn test_intent_42(entropy: Word, num_constraints: usize) -> Intent {
186+
let mut state_read: Vec<state_read_vm::asm::Op> = vec![
187+
state_read_vm::asm::Stack::Push(2).into(),
188+
state_read_vm::asm::StateSlots::AllocSlots.into(),
189+
state_read_vm::asm::Stack::Push(0).into(),
190+
state_read_vm::asm::Stack::Push(0).into(),
191+
state_read_vm::asm::Stack::Push(0).into(),
192+
state_read_vm::asm::Stack::Push(0).into(),
193+
state_read_vm::asm::Stack::Push(4).into(),
194+
state_read_vm::asm::Stack::Push(1).into(),
195+
state_read_vm::asm::Stack::Push(0).into(),
196+
state_read_vm::asm::StateRead::KeyRange,
197+
];
198+
state_read.extend(vec![
199+
state_read_vm::asm::Op::from(
200+
state_read_vm::asm::Stack::Push(20)
201+
);
202+
32
203+
]);
204+
state_read.extend([
205+
state_read_vm::asm::Stack::Push(32).into(),
206+
state_read_vm::asm::Stack::Push(1).into(),
207+
state_read_vm::asm::Stack::Push(1).into(),
208+
state_read_vm::asm::StateRead::KeyRange,
209+
state_read_vm::asm::ControlFlow::Halt.into(),
210+
]);
176211
Intent {
177212
// State read program to read state slot 0.
178-
state_read: vec![state_read_vm::asm::to_bytes([
179-
state_read_vm::asm::Stack::Push(1).into(),
180-
state_read_vm::asm::StateSlots::AllocSlots.into(),
181-
state_read_vm::asm::Stack::Push(0).into(),
182-
state_read_vm::asm::Stack::Push(0).into(),
183-
state_read_vm::asm::Stack::Push(0).into(),
184-
state_read_vm::asm::Stack::Push(0).into(),
185-
state_read_vm::asm::Stack::Push(4).into(),
186-
state_read_vm::asm::Stack::Push(1).into(),
187-
state_read_vm::asm::Stack::Push(0).into(),
188-
state_read_vm::asm::StateRead::KeyRange,
189-
state_read_vm::asm::ControlFlow::Halt.into(),
190-
])
191-
.collect()],
213+
state_read: vec![state_read_vm::asm::to_bytes(state_read).collect()],
192214
// Program to check pre-mutation value is None and
193215
// post-mutation value is 42 at slot 0.
194-
constraints: vec![constraint_vm::asm::to_bytes([
195-
state_read_vm::asm::Stack::Push(entropy).into(),
196-
state_read_vm::asm::Stack::Pop.into(),
197-
constraint_vm::asm::Stack::Push(0).into(), // slot
198-
constraint_vm::asm::Stack::Push(0).into(), // pre
199-
constraint_vm::asm::Access::StateLen.into(),
200-
constraint_vm::asm::Stack::Push(0).into(),
201-
constraint_vm::asm::Pred::Eq.into(),
202-
constraint_vm::asm::Stack::Push(0).into(), // slot
203-
constraint_vm::asm::Stack::Push(1).into(), // post
204-
constraint_vm::asm::Access::State.into(),
205-
constraint_vm::asm::Stack::Push(42).into(),
206-
constraint_vm::asm::Pred::Eq.into(),
207-
constraint_vm::asm::Pred::And.into(),
208-
constraint_vm::asm::Stack::Push(0).into(),
209-
constraint_vm::asm::Access::DecisionVar.into(),
210-
constraint_vm::asm::Stack::Push(0).into(), // slot
211-
constraint_vm::asm::Stack::Push(1).into(), // post
212-
constraint_vm::asm::Access::State.into(),
213-
constraint_vm::asm::Stack::Push(42).into(),
214-
constraint_vm::asm::Pred::Eq.into(),
215-
constraint_vm::asm::Pred::And.into(),
216-
])
217-
.collect()],
216+
constraints: (0..num_constraints)
217+
.map(|_| {
218+
constraint_vm::asm::to_bytes([
219+
state_read_vm::asm::Stack::Push(entropy).into(),
220+
state_read_vm::asm::Stack::Pop.into(),
221+
constraint_vm::asm::Stack::Push(0).into(), // slot
222+
constraint_vm::asm::Stack::Push(0).into(), // pre
223+
constraint_vm::asm::Access::StateLen.into(),
224+
constraint_vm::asm::Stack::Push(0).into(),
225+
constraint_vm::asm::Pred::Eq.into(),
226+
constraint_vm::asm::Stack::Push(0).into(), // slot
227+
constraint_vm::asm::Stack::Push(1).into(), // post
228+
constraint_vm::asm::Access::State.into(),
229+
constraint_vm::asm::Stack::Push(42).into(),
230+
constraint_vm::asm::Pred::Eq.into(),
231+
constraint_vm::asm::Pred::And.into(),
232+
constraint_vm::asm::Stack::Push(0).into(),
233+
constraint_vm::asm::Access::DecisionVar.into(),
234+
constraint_vm::asm::Stack::Push(0).into(), // slot
235+
constraint_vm::asm::Stack::Push(1).into(), // post
236+
constraint_vm::asm::Access::State.into(),
237+
constraint_vm::asm::Stack::Push(42).into(),
238+
constraint_vm::asm::Pred::Eq.into(),
239+
constraint_vm::asm::Pred::And.into(),
240+
constraint_vm::asm::Stack::Push(1).into(), // slot
241+
constraint_vm::asm::Stack::Push(1).into(), // post
242+
constraint_vm::asm::Access::State.into(),
243+
constraint_vm::asm::Stack::Push(1000).into(),
244+
constraint_vm::asm::Crypto::Sha256.into(),
245+
constraint_vm::asm::Stack::Push(1).into(), // slot
246+
constraint_vm::asm::Stack::Push(1).into(), // post
247+
constraint_vm::asm::Access::State.into(),
248+
constraint_vm::asm::Stack::Push(1000).into(),
249+
constraint_vm::asm::Crypto::Sha256.into(),
250+
constraint_vm::asm::Stack::Push(4).into(),
251+
constraint_vm::asm::Pred::EqRange.into(),
252+
constraint_vm::asm::Pred::And.into(),
253+
])
254+
.collect()
255+
})
256+
.collect(),
218257
directive: Directive::Satisfy,
219258
}
220259
}
@@ -232,10 +271,13 @@ fn random_keypair(seed: [u8; 32]) -> (SecretKey, PublicKey) {
232271

233272
fn test_intent_42_solution_pair(
234273
amount: usize,
274+
num_constraints: usize,
235275
keypair_seed: [u8; 32],
236276
) -> (Signed<Vec<Intent>>, Solution) {
237277
// Create the test intent, ensure its decision_variables match, and sign.
238-
let intents: Vec<_> = (0..amount).map(|i| test_intent_42(i as Word)).collect();
278+
let intents: Vec<_> = (0..amount)
279+
.map(|i| test_intent_42(i as Word, num_constraints))
280+
.collect();
239281
let (sk, _pk) = random_keypair(keypair_seed);
240282
let intents = essential_sign::sign(intents, &sk);
241283

@@ -248,10 +290,16 @@ fn test_intent_42_solution_pair(
248290
intent: ContentAddress(essential_hash::hash(intents.data.get(i).unwrap())),
249291
},
250292
decision_variables: vec![42],
251-
state_mutations: vec![Mutation {
252-
key: vec![0, 0, 0, 0],
253-
value: vec![42],
254-
}],
293+
state_mutations: vec![
294+
Mutation {
295+
key: vec![0, 0, 0, 0],
296+
value: vec![42],
297+
},
298+
Mutation {
299+
key: vec![20; 32],
300+
value: vec![42; 1000],
301+
},
302+
],
255303
transient_data: vec![],
256304
})
257305
.collect();

crates/check/tests/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use essential_check::{
44
state_read_vm,
55
state_read_vm::StateRead,
66
types::{
7-
intent::{Directive, Intent},
7+
intent::{self, Directive, Intent},
88
solution::{Mutation, Solution, SolutionData},
99
ContentAddress, IntentAddress, Key, Word,
1010
},

0 commit comments

Comments
 (0)