Skip to content

Commit 22ea1d2

Browse files
committed
Add mapping of mappings test cases to the integration test.
1 parent c21fe13 commit 22ea1d2

File tree

12 files changed

+2980
-600
lines changed

12 files changed

+2980
-600
lines changed

mp2-v1/src/values_extraction/leaf_mapping_of_mappings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,9 @@ where
186186
.collect();
187187
let hash = b.hash_n_to_hash_no_pad::<CHasher>(inputs);
188188
let row_id = hash_to_int_target(b, hash);
189-
let row_id = b.biguint_to_nonnative(&row_id);
190189

191190
// values_digest = values_digest * row_id
191+
let row_id = b.biguint_to_nonnative(&row_id);
192192
let values_digest = b.curve_scalar_mul(values_digest, &row_id);
193193

194194
// Only one leaf in this node.

mp2-v1/test-contracts/src/Simple.sol

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ contract Simple {
2222
MappingOperation operation;
2323
}
2424

25+
struct MappingOfSingleValueMappingsChange {
26+
uint256 outerKey;
27+
uint256 innerKey;
28+
uint256 value;
29+
MappingOperation operation;
30+
}
31+
32+
struct MappingOfStructMappingsChange {
33+
uint256 outerKey;
34+
uint256 innerKey;
35+
uint256 field1;
36+
uint128 field2;
37+
uint128 field3;
38+
MappingOperation operation;
39+
}
40+
2541
struct LargeStruct {
2642
// This field should live in one EVM word
2743
uint256 field1;
@@ -48,9 +64,13 @@ contract Simple {
4864
// Test mapping struct (slot 8)
4965
mapping(uint256 => LargeStruct) public structMapping;
5066

51-
// Test mapping of mappings (slot 9)
67+
// Test mapping of single value mappings (slot 9)
68+
mapping(uint256 => mapping(uint256 => uint256))
69+
public mappingOfSingleValueMappings;
70+
71+
// Test mapping of struct mappings (slot 10)
5272
mapping(uint256 => mapping(uint256 => LargeStruct))
53-
public mappingOfMappings;
73+
public mappingOfStructMappings;
5474

5575
// Set the simple slots.
5676
function setSimples(
@@ -125,4 +145,49 @@ contract Simple {
125145
}
126146
}
127147

148+
// Set mapping of single value mappings.
149+
function setMappingOfSingleValueMappings(
150+
uint256 outerKey,
151+
uint256 innerKey,
152+
uint256 value
153+
) public {
154+
mappingOfSingleValueMappings[outerKey][innerKey] = value;
155+
}
156+
157+
function changeMappingOfSingleValueMappings(MappingOfSingleValueMappingsChange[] memory changes) public {
158+
for (uint256 i = 0; i < changes.length; i++) {
159+
if (changes[i].operation == MappingOperation.Deletion) {
160+
delete mappingOfSingleValueMappings[changes[i].outerKey][changes[i].innerKey];
161+
} else if (
162+
changes[i].operation == MappingOperation.Insertion ||
163+
changes[i].operation == MappingOperation.Update
164+
) {
165+
setMappingOfSingleValueMappings(changes[i].outerKey, changes[i].innerKey, changes[i].value);
166+
}
167+
}
168+
}
169+
170+
// Set mapping of struct mappings.
171+
function setMappingOfStructMappings(
172+
uint256 outerKey,
173+
uint256 innerKey,
174+
uint256 field1,
175+
uint128 field2,
176+
uint128 field3
177+
) public {
178+
mappingOfStructMappings[outerKey][innerKey] = LargeStruct(field1, field2, field3);
179+
}
180+
181+
function changeMappingOfStructMappings(MappingOfStructMappingsChange[] memory changes) public {
182+
for (uint256 i = 0; i < changes.length; i++) {
183+
if (changes[i].operation == MappingOperation.Deletion) {
184+
delete mappingOfStructMappings[changes[i].outerKey][changes[i].innerKey];
185+
} else if (
186+
changes[i].operation == MappingOperation.Insertion ||
187+
changes[i].operation == MappingOperation.Update
188+
) {
189+
setMappingOfStructMappings(changes[i].outerKey, changes[i].innerKey, changes[i].field1, changes[i].field2, changes[i].field3);
190+
}
191+
}
192+
}
128193
}

mp2-v1/tests/common/bindings/simple.rs

Lines changed: 1920 additions & 311 deletions
Large diffs are not rendered by default.

mp2-v1/tests/common/cases/contract.rs

Lines changed: 166 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
use super::{
2-
indexing::MappingUpdate,
3-
storage_slot_value::{LargeStruct, StorageSlotValue},
2+
slot_info::{LargeStruct, MappingKey, MappingOfMappingsKey, StorageSlotValue},
43
table_source::DEFAULT_ADDRESS,
54
};
65
use crate::common::{
76
bindings::simple::{
87
Simple,
9-
Simple::{MappingChange, MappingOperation, MappingStructChange},
8+
Simple::{
9+
MappingChange, MappingOfSingleValueMappingsChange, MappingOfStructMappingsChange,
10+
MappingOperation, MappingStructChange,
11+
},
1012
},
1113
TestContext,
1214
};
@@ -121,7 +123,27 @@ impl ContractController for LargeStruct {
121123
}
122124
}
123125

124-
impl ContractController for Vec<MappingUpdate<Address>> {
126+
#[derive(Clone, Debug)]
127+
pub enum MappingUpdate<K, V> {
128+
// key and value
129+
Insertion(K, V),
130+
// key and value
131+
Deletion(K, V),
132+
// key, previous value and new value
133+
Update(K, V, V),
134+
}
135+
136+
impl<K, V> From<&MappingUpdate<K, V>> for MappingOperation {
137+
fn from(update: &MappingUpdate<K, V>) -> Self {
138+
Self::from(match update {
139+
MappingUpdate::Deletion(_, _) => 0,
140+
MappingUpdate::Update(_, _, _) => 1,
141+
MappingUpdate::Insertion(_, _) => 2,
142+
})
143+
}
144+
}
145+
146+
impl ContractController for Vec<MappingUpdate<MappingKey, Address>> {
125147
async fn current_values(_ctx: &TestContext, _contract: &Contract) -> Self {
126148
unimplemented!("Unimplemented for fetching the all mapping values")
127149
}
@@ -178,7 +200,7 @@ impl ContractController for Vec<MappingUpdate<Address>> {
178200
}
179201
}
180202

181-
impl ContractController for Vec<MappingUpdate<LargeStruct>> {
203+
impl ContractController for Vec<MappingUpdate<MappingKey, LargeStruct>> {
182204
async fn current_values(_ctx: &TestContext, _contract: &Contract) -> Self {
183205
unimplemented!("Unimplemented for fetching the all mapping values")
184206
}
@@ -233,3 +255,142 @@ impl ContractController for Vec<MappingUpdate<LargeStruct>> {
233255
log::info!("Updated simple contract for mapping values of LargeStruct");
234256
}
235257
}
258+
259+
impl ContractController for Vec<MappingUpdate<MappingOfMappingsKey, U256>> {
260+
async fn current_values(_ctx: &TestContext, _contract: &Contract) -> Self {
261+
unimplemented!("Unimplemented for fetching the all mapping of mappings")
262+
}
263+
264+
async fn update_contract(&self, ctx: &TestContext, contract: &Contract) {
265+
let provider = ProviderBuilder::new()
266+
.with_recommended_fillers()
267+
.wallet(ctx.wallet())
268+
.on_http(ctx.rpc_url.parse().unwrap());
269+
let contract = Simple::new(contract.address, &provider);
270+
271+
let changes = self
272+
.iter()
273+
.map(|tuple| {
274+
let operation: MappingOperation = tuple.into();
275+
let operation = operation.into();
276+
let (k, v) = match tuple {
277+
MappingUpdate::Insertion(k, v)
278+
| MappingUpdate::Deletion(k, v)
279+
| MappingUpdate::Update(k, _, v) => (k, v),
280+
};
281+
282+
MappingOfSingleValueMappingsChange {
283+
operation,
284+
outerKey: k.outer_key,
285+
innerKey: k.inner_key,
286+
value: v.clone(),
287+
}
288+
})
289+
.collect_vec();
290+
291+
let call = contract.changeMappingOfSingleValueMappings(changes);
292+
call.send().await.unwrap().watch().await.unwrap();
293+
// Sanity check
294+
for update in self.iter() {
295+
match update {
296+
MappingUpdate::Insertion(k, v) => {
297+
let res = contract
298+
.mappingOfSingleValueMappings(k.outer_key, k.inner_key)
299+
.call()
300+
.await
301+
.unwrap();
302+
assert_eq!(&res._0, v, "Insertion is wrong on contract");
303+
}
304+
MappingUpdate::Deletion(k, _) => {
305+
let res = contract
306+
.mappingOfSingleValueMappings(k.outer_key, k.inner_key)
307+
.call()
308+
.await
309+
.unwrap();
310+
assert_eq!(res._0, U256::ZERO, "Deletion is wrong on contract");
311+
}
312+
MappingUpdate::Update(k, _, v) => {
313+
let res = contract
314+
.mappingOfSingleValueMappings(k.outer_key, k.inner_key)
315+
.call()
316+
.await
317+
.unwrap();
318+
assert_eq!(&res._0, v, "Update is wrong on contract");
319+
}
320+
}
321+
}
322+
log::info!("Updated simple contract for mapping of single value mappings");
323+
}
324+
}
325+
326+
impl ContractController for Vec<MappingUpdate<MappingOfMappingsKey, LargeStruct>> {
327+
async fn current_values(_ctx: &TestContext, _contract: &Contract) -> Self {
328+
unimplemented!("Unimplemented for fetching the all mapping of mappings")
329+
}
330+
331+
async fn update_contract(&self, ctx: &TestContext, contract: &Contract) {
332+
let provider = ProviderBuilder::new()
333+
.with_recommended_fillers()
334+
.wallet(ctx.wallet())
335+
.on_http(ctx.rpc_url.parse().unwrap());
336+
let contract = Simple::new(contract.address, &provider);
337+
338+
let changes = self
339+
.iter()
340+
.map(|tuple| {
341+
let operation: MappingOperation = tuple.into();
342+
let operation = operation.into();
343+
let (k, v) = match tuple {
344+
MappingUpdate::Insertion(k, v)
345+
| MappingUpdate::Deletion(k, v)
346+
| MappingUpdate::Update(k, _, v) => (k, v),
347+
};
348+
349+
MappingOfStructMappingsChange {
350+
operation,
351+
outerKey: k.outer_key,
352+
innerKey: k.inner_key,
353+
field1: v.field1,
354+
field2: v.field2,
355+
field3: v.field3,
356+
}
357+
})
358+
.collect_vec();
359+
360+
let call = contract.changeMappingOfStructMappings(changes);
361+
call.send().await.unwrap().watch().await.unwrap();
362+
// Sanity check
363+
for update in self.iter() {
364+
match update {
365+
MappingUpdate::Insertion(k, v) => {
366+
let res = contract
367+
.mappingOfStructMappings(k.outer_key, k.inner_key)
368+
.call()
369+
.await
370+
.unwrap();
371+
let res = LargeStruct::from(res);
372+
assert_eq!(&res, v, "Insertion is wrong on contract");
373+
}
374+
MappingUpdate::Deletion(k, _) => {
375+
let res = contract
376+
.mappingOfStructMappings(k.outer_key, k.inner_key)
377+
.call()
378+
.await
379+
.unwrap();
380+
let res = LargeStruct::from(res);
381+
assert_eq!(res, LargeStruct::default(), "Deletion is wrong on contract");
382+
}
383+
MappingUpdate::Update(k, _, v) => {
384+
let res = contract
385+
.mappingOfStructMappings(k.outer_key, k.inner_key)
386+
.call()
387+
.await
388+
.unwrap();
389+
let res = LargeStruct::from(res);
390+
assert_eq!(&res, v, "Update is wrong on contract");
391+
}
392+
}
393+
}
394+
log::info!("Updated simple contract for mapping of LargeStruct mappings");
395+
}
396+
}

0 commit comments

Comments
 (0)