Skip to content

Commit 3809850

Browse files
committed
feat: move state mutations and transient data inline
1 parent 77c526d commit 3809850

File tree

12 files changed

+134
-190
lines changed

12 files changed

+134
-190
lines changed

crates/check/benches/check_intents.rs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use essential_state_read_vm as state_read_vm;
1010
use essential_state_read_vm::StateRead;
1111
use essential_types::{
1212
intent::{Directive, Intent},
13-
solution::{Mutation, Mutations, Solution, SolutionData},
13+
solution::{Mutation, Solution, SolutionData},
1414
ContentAddress, IntentAddress, Key, Signed, Word,
1515
};
1616
use secp256k1::{PublicKey, Secp256k1, SecretKey};
@@ -145,15 +145,13 @@ impl State {
145145

146146
/// Apply all mutations proposed by the given solution.
147147
pub fn apply_mutations(&mut self, solution: &Solution) {
148-
for state_mutation in &solution.state_mutations {
149-
let set = &solution
150-
.data
151-
.get(state_mutation.pathway as usize)
152-
.expect("intent pathway not found in solution data")
153-
.intent_to_solve
154-
.set;
155-
for mutation in state_mutation.mutations.iter() {
156-
self.set(set.clone(), &mutation.key, mutation.value.clone());
148+
for data in &solution.data {
149+
for mutation in &data.state_mutations {
150+
self.set(
151+
data.intent_to_solve.set.clone(),
152+
&mutation.key,
153+
mutation.value.clone(),
154+
);
157155
}
158156
}
159157
}
@@ -250,24 +248,15 @@ fn test_intent_42_solution_pair(
250248
intent: ContentAddress(essential_hash::hash(intents.data.get(i).unwrap())),
251249
},
252250
decision_variables: vec![42],
253-
})
254-
.collect();
255-
256-
let state_mutations = (0..amount)
257-
.map(|i| Mutations {
258-
pathway: i as u16,
259-
mutations: vec![Mutation {
251+
state_mutations: vec![Mutation {
260252
key: vec![0, 0, 0, 0],
261253
value: vec![42],
262254
}],
255+
transient_data: vec![],
263256
})
264257
.collect();
265258

266-
let solution = Solution {
267-
data,
268-
transient_data: vec![],
269-
state_mutations,
270-
};
259+
let solution = Solution { data };
271260

272261
(intents, solution)
273262
}

crates/check/src/solution.rs

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -229,29 +229,19 @@ pub fn check_data(data_slice: &[SolutionData]) -> Result<(), InvalidSolutionData
229229
pub fn check_state_mutations(solution: &Solution) -> Result<(), InvalidStateMutations> {
230230
// Validate state mutations.
231231
// Ensure that solution state mutations length is below limit length.
232-
if solution.state_mutations.len() > MAX_STATE_MUTATIONS {
232+
if solution.state_mutations_len() > MAX_STATE_MUTATIONS {
233233
return Err(InvalidStateMutations::TooMany(
234-
solution.state_mutations.len(),
234+
solution.state_mutations_len(),
235235
));
236236
}
237237

238-
// Ensure that all state mutations with a pathway points to some solution data.
239-
for state_mut in &solution.state_mutations {
240-
if solution.data.len() <= usize::from(state_mut.pathway) {
241-
return Err(InvalidStateMutations::PathwayOutOfRangeOfSolutionData(
242-
state_mut.pathway,
243-
));
244-
}
245-
}
246-
247238
// Ensure that no more than one mutation per slot is proposed.
248-
let mut mut_keys = HashSet::new();
249-
for state_mutation in &solution.state_mutations {
250-
let intent_addr = &solution.data[state_mutation.pathway as usize].intent_to_solve;
251-
for mutation in &state_mutation.mutations {
252-
if !mut_keys.insert((intent_addr, &mutation.key)) {
239+
for data in &solution.data {
240+
let mut mut_keys = HashSet::new();
241+
for mutation in &data.state_mutations {
242+
if !mut_keys.insert(&mutation.key) {
253243
return Err(InvalidStateMutations::MultipleMutationsForSlot(
254-
intent_addr.clone(),
244+
data.intent_to_solve.clone(),
255245
mutation.key.clone(),
256246
));
257247
}
@@ -265,17 +255,8 @@ pub fn check_state_mutations(solution: &Solution) -> Result<(), InvalidStateMuta
265255
pub fn check_transient_data(solution: &Solution) -> Result<(), InvalidTransientData> {
266256
// Validate transient data.
267257
// Ensure that solution transient data length is below limit length.
268-
if solution.transient_data.len() > MAX_TRANSIENT_DATA {
269-
return Err(InvalidTransientData::TooMany(solution.transient_data.len()));
270-
}
271-
272-
// Ensure that all transient data with a pathway points to some solution data.
273-
for transient_datum in &solution.transient_data {
274-
if solution.data.len() <= usize::from(transient_datum.pathway) {
275-
return Err(InvalidTransientData::PathwayOutOfRangeOfSolutionData(
276-
transient_datum.pathway,
277-
));
278-
}
258+
if solution.transient_data_len() > MAX_TRANSIENT_DATA {
259+
return Err(InvalidTransientData::TooMany(solution.transient_data_len()));
279260
}
280261

281262
Ok(())

crates/check/tests/solution.rs

Lines changed: 33 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use essential_constraint_vm as constraint_vm;
44
use essential_state_read_vm as state_read_vm;
55
use essential_types::{
66
intent::{Directive, Intent},
7-
solution::{Mutation, Mutations, Solution, SolutionData},
8-
ContentAddress, IntentAddress,
7+
solution::{Mutation, Solution, SolutionData},
8+
ContentAddress, IntentAddress, Word,
99
};
1010
use std::sync::Arc;
1111
use util::{empty_solution, intent_addr, random_keypair, State};
@@ -23,13 +23,15 @@ fn test_solution_data() -> SolutionData {
2323
SolutionData {
2424
intent_to_solve: test_intent_addr(),
2525
decision_variables: vec![],
26+
state_mutations: vec![],
27+
transient_data: vec![],
2628
}
2729
}
2830

29-
fn test_state_mutation() -> Mutations {
30-
Mutations {
31-
pathway: 0,
32-
mutations: vec![],
31+
fn test_mutation(salt: usize) -> Mutation {
32+
Mutation {
33+
key: vec![salt as Word; 4],
34+
value: vec![42],
3335
}
3436
}
3537

@@ -48,7 +50,6 @@ fn too_many_solution_data() {
4850
data: (0..solution::MAX_SOLUTION_DATA + 1)
4951
.map(|_| test_solution_data())
5052
.collect(),
51-
..empty_solution()
5253
};
5354
assert!(matches!(
5455
solution::check(&solution).unwrap_err(),
@@ -63,8 +64,9 @@ fn too_many_decision_variables() {
6364
data: vec![SolutionData {
6465
intent_to_solve: test_intent_addr(),
6566
decision_variables: vec![0; (solution::MAX_DECISION_VARIABLES + 1) as usize],
67+
state_mutations: vec![],
68+
transient_data: vec![],
6669
}],
67-
..empty_solution()
6870
};
6971
assert!(matches!(
7072
solution::check(&solution).unwrap_err(),
@@ -76,9 +78,14 @@ fn too_many_decision_variables() {
7678
#[test]
7779
fn too_many_state_mutations() {
7880
let solution = Solution {
79-
data: vec![test_solution_data()],
80-
transient_data: vec![],
81-
state_mutations: vec![test_state_mutation(); solution::MAX_STATE_MUTATIONS + 1],
81+
data: vec![SolutionData {
82+
intent_to_solve: test_intent_addr(),
83+
decision_variables: vec![],
84+
state_mutations: (0..(solution::MAX_STATE_MUTATIONS + 1))
85+
.map(test_mutation)
86+
.collect(),
87+
transient_data: vec![],
88+
}],
8289
};
8390
assert!(matches!(
8491
solution::check(&solution).unwrap_err(),
@@ -87,39 +94,20 @@ fn too_many_state_mutations() {
8794
));
8895
}
8996

90-
#[test]
91-
fn state_mutation_pathways_must_have_associated_solution_data() {
92-
let solution = Solution {
93-
state_mutations: vec![Mutations {
94-
// Note: pathway out of bounds of solution data to trigger error.
95-
pathway: 1,
96-
mutations: Default::default(),
97-
}],
98-
transient_data: vec![],
99-
data: vec![test_solution_data()],
100-
};
101-
assert!(matches!(
102-
solution::check(&solution).unwrap_err(),
103-
solution::InvalidSolution::StateMutations(
104-
solution::InvalidStateMutations::PathwayOutOfRangeOfSolutionData(1)
105-
),
106-
));
107-
}
108-
10997
#[test]
11098
fn multiple_mutations_for_slot() {
11199
let solution = Solution {
112-
data: vec![test_solution_data()],
113-
transient_data: vec![],
114-
state_mutations: vec![Mutations {
115-
pathway: 0,
116-
mutations: vec![
100+
data: vec![SolutionData {
101+
intent_to_solve: test_intent_addr(),
102+
decision_variables: vec![],
103+
state_mutations: vec![
117104
Mutation {
118105
key: vec![0; 4],
119106
value: vec![42],
120107
};
121108
2
122109
],
110+
transient_data: vec![],
123111
}],
124112
};
125113
assert!(matches!(
@@ -132,9 +120,14 @@ fn multiple_mutations_for_slot() {
132120
#[test]
133121
fn too_many_transient_data() {
134122
let solution = Solution {
135-
data: vec![test_solution_data()],
136-
transient_data: vec![test_state_mutation(); solution::MAX_TRANSIENT_DATA + 1],
137-
state_mutations: vec![],
123+
data: vec![SolutionData {
124+
intent_to_solve: test_intent_addr(),
125+
decision_variables: vec![],
126+
state_mutations: vec![],
127+
transient_data: (0..(solution::MAX_TRANSIENT_DATA + 1))
128+
.map(test_mutation)
129+
.collect(),
130+
}],
138131
};
139132
assert!(matches!(
140133
solution::check(&solution).unwrap_err(),
@@ -143,25 +136,6 @@ fn too_many_transient_data() {
143136
));
144137
}
145138

146-
#[test]
147-
fn transient_data_pathways_must_have_associated_solution_data() {
148-
let solution = Solution {
149-
state_mutations: vec![],
150-
transient_data: vec![Mutations {
151-
// Note: pathway out of bounds of solution data to trigger error.
152-
pathway: 1,
153-
mutations: Default::default(),
154-
}],
155-
data: vec![test_solution_data()],
156-
};
157-
assert!(matches!(
158-
solution::check(&solution).unwrap_err(),
159-
solution::InvalidSolution::TransientData(
160-
solution::InvalidTransientData::PathwayOutOfRangeOfSolutionData(1)
161-
),
162-
));
163-
}
164-
165139
// Tests an intent for setting slot 0 to 42 against its associated solution.
166140
#[tokio::test]
167141
async fn check_intent_42_with_solution() {
@@ -296,11 +270,7 @@ async fn intent_with_multiple_state_reads_and_slots() {
296270
data: vec![SolutionData {
297271
intent_to_solve: intent_addr,
298272
decision_variables: Default::default(),
299-
}],
300-
transient_data: vec![],
301-
state_mutations: vec![Mutations {
302-
pathway: 0,
303-
mutations: vec![
273+
state_mutations: vec![
304274
Mutation {
305275
key: vec![0],
306276
value: vec![0, 1, 2, 3, 4],
@@ -322,6 +292,7 @@ async fn intent_with_multiple_state_reads_and_slots() {
322292
value: vec![8],
323293
},
324294
],
295+
transient_data: vec![],
325296
}],
326297
};
327298

crates/check/tests/util.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use essential_check::{
55
state_read_vm::StateRead,
66
types::{
77
intent::{Directive, Intent},
8-
solution::{Mutation, Mutations, Solution, SolutionData},
8+
solution::{Mutation, Solution, SolutionData},
99
ContentAddress, IntentAddress, Key, Signed, Word,
1010
},
1111
};
@@ -94,15 +94,13 @@ impl State {
9494

9595
/// Apply all mutations proposed by the given solution.
9696
pub fn apply_mutations(&mut self, solution: &Solution) {
97-
for state_mutation in &solution.state_mutations {
98-
let set = &solution
99-
.data
100-
.get(state_mutation.pathway as usize)
101-
.expect("intent pathway not found in solution data")
102-
.intent_to_solve
103-
.set;
104-
for mutation in state_mutation.mutations.iter() {
105-
self.set(set.clone(), &mutation.key, mutation.value.clone());
97+
for data in &solution.data {
98+
for mutation in data.state_mutations.iter() {
99+
self.set(
100+
data.intent_to_solve.set.clone(),
101+
&mutation.key,
102+
mutation.value.clone(),
103+
);
106104
}
107105
}
108106
}
@@ -126,8 +124,6 @@ impl StateRead for State {
126124
pub fn empty_solution() -> Solution {
127125
Solution {
128126
data: Default::default(),
129-
transient_data: Default::default(),
130-
state_mutations: Default::default(),
131127
}
132128
}
133129

@@ -217,14 +213,11 @@ pub fn test_intent_42_solution_pair(
217213
data: vec![SolutionData {
218214
intent_to_solve: intent_addr,
219215
decision_variables,
220-
}],
221-
transient_data: vec![],
222-
state_mutations: vec![Mutations {
223-
pathway: 0,
224-
mutations: vec![Mutation {
216+
state_mutations: vec![Mutation {
225217
key: vec![0, 0, 0, 0],
226218
value: vec![42],
227219
}],
220+
transient_data: vec![],
228221
}],
229222
};
230223

crates/constraint-vm/benches/eval.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ pub fn bench(c: &mut Criterion) {
1717
intent: ContentAddress([0; 32]),
1818
},
1919
decision_variables: vec![],
20+
state_mutations: vec![],
21+
transient_data: vec![],
2022
}],
2123
index: 0,
2224
mutable_keys: &mutable_keys,

0 commit comments

Comments
 (0)