Skip to content

Commit bee8ea3

Browse files
g-r-a-n-tcburgdorf
authored andcommitted
stdlib: add storage map tuple key impls
Add StorageKey implementations for 3- through 6-element tuples and cover them with a runtime storage map fixture.
1 parent 44adaa4 commit bee8ea3

2 files changed

Lines changed: 190 additions & 0 deletions

File tree

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
msg TupleKeyMsg {
2+
#[selector = 1]
3+
Put3 { a: u256, b: u256, c: u256, value: u256 } -> u256,
4+
5+
#[selector = 2]
6+
Read3 { a: u256, b: u256, c: u256 } -> u256,
7+
8+
#[selector = 3]
9+
Put4 { a: u256, b: u256, c: u256, d: u256, value: u256 } -> u256,
10+
11+
#[selector = 4]
12+
Read4 { a: u256, b: u256, c: u256, d: u256 } -> u256,
13+
14+
#[selector = 5]
15+
Put5 { a: u256, b: u256, c: u256, d: u256, e: u256, value: u256 } -> u256,
16+
17+
#[selector = 6]
18+
Read5 { a: u256, b: u256, c: u256, d: u256, e: u256 } -> u256,
19+
20+
#[selector = 7]
21+
Put6 { a: u256, b: u256, c: u256, d: u256, e: u256, f: u256, value: u256 } -> u256,
22+
23+
#[selector = 8]
24+
Read6 { a: u256, b: u256, c: u256, d: u256, e: u256, f: u256 } -> u256,
25+
}
26+
27+
struct Store {
28+
triples: StorageMap<(u256, u256, u256), u256>,
29+
quartets: StorageMap<(u256, u256, u256, u256), u256>,
30+
quintets: StorageMap<(u256, u256, u256, u256, u256), u256>,
31+
sextets: StorageMap<(u256, u256, u256, u256, u256, u256), u256>,
32+
}
33+
34+
pub contract C {
35+
mut store: Store
36+
37+
init() uses (mut store) {}
38+
39+
recv TupleKeyMsg {
40+
Put3 { a, b, c, value } -> u256 uses (mut store) {
41+
store.triples.set(key: (a, b, c), value: value)
42+
store.triples.get(key: (a, b, c))
43+
}
44+
45+
Read3 { a, b, c } -> u256 uses (store) {
46+
store.triples.get(key: (a, b, c))
47+
}
48+
49+
Put4 { a, b, c, d, value } -> u256 uses (mut store) {
50+
store.quartets.set(key: (a, b, c, d), value: value)
51+
store.quartets.get(key: (a, b, c, d))
52+
}
53+
54+
Read4 { a, b, c, d } -> u256 uses (store) {
55+
store.quartets.get(key: (a, b, c, d))
56+
}
57+
58+
Put5 { a, b, c, d, e, value } -> u256 uses (mut store) {
59+
store.quintets.set(key: (a, b, c, d, e), value: value)
60+
store.quintets.get(key: (a, b, c, d, e))
61+
}
62+
63+
Read5 { a, b, c, d, e } -> u256 uses (store) {
64+
store.quintets.get(key: (a, b, c, d, e))
65+
}
66+
67+
Put6 { a, b, c, d, e, f, value } -> u256 uses (mut store) {
68+
store.sextets.set(key: (a, b, c, d, e, f), value: value)
69+
store.sextets.get(key: (a, b, c, d, e, f))
70+
}
71+
72+
Read6 { a, b, c, d, e, f } -> u256 uses (store) {
73+
store.sextets.get(key: (a, b, c, d, e, f))
74+
}
75+
}
76+
}
77+
78+
#[test]
79+
fn test_storage_map_tuple_keys() uses (evm: mut Evm) {
80+
let c = evm.create2<C>(value: 0, args: (), salt: 0)
81+
assert!(c.inner != 0)
82+
83+
let v3: u256 = evm.call(
84+
addr: c,
85+
gas: 1000000,
86+
value: 0,
87+
message: TupleKeyMsg::Put3 { a: 1, b: 2, c: 3, value: 33 },
88+
)
89+
assert!(v3 == 33)
90+
let v3: u256 = evm.call(addr: c, gas: 1000000, value: 0, message: TupleKeyMsg::Read3 { a: 1, b: 2, c: 3 })
91+
assert!(v3 == 33)
92+
let v3_missing: u256 = evm.call(addr: c, gas: 1000000, value: 0, message: TupleKeyMsg::Read3 { a: 1, b: 2, c: 4 })
93+
assert!(v3_missing == 0)
94+
95+
let v4: u256 = evm.call(
96+
addr: c,
97+
gas: 1000000,
98+
value: 0,
99+
message: TupleKeyMsg::Put4 { a: 4, b: 5, c: 6, d: 7, value: 44 },
100+
)
101+
assert!(v4 == 44)
102+
let v4: u256 = evm.call(addr: c, gas: 1000000, value: 0, message: TupleKeyMsg::Read4 { a: 4, b: 5, c: 6, d: 7 })
103+
assert!(v4 == 44)
104+
105+
let v5: u256 = evm.call(
106+
addr: c,
107+
gas: 1000000,
108+
value: 0,
109+
message: TupleKeyMsg::Put5 { a: 8, b: 9, c: 10, d: 11, e: 12, value: 55 },
110+
)
111+
assert!(v5 == 55)
112+
let v5: u256 = evm.call(addr: c, gas: 1000000, value: 0, message: TupleKeyMsg::Read5 { a: 8, b: 9, c: 10, d: 11, e: 12 })
113+
assert!(v5 == 55)
114+
115+
let v6: u256 = evm.call(
116+
addr: c,
117+
gas: 1000000,
118+
value: 0,
119+
message: TupleKeyMsg::Put6 { a: 13, b: 14, c: 15, d: 16, e: 17, f: 18, value: 66 },
120+
)
121+
assert!(v6 == 66)
122+
let v6: u256 = evm.call(addr: c, gas: 1000000, value: 0, message: TupleKeyMsg::Read6 { a: 13, b: 14, c: 15, d: 16, e: 17, f: 18 })
123+
assert!(v6 == 66)
124+
let v6_missing: u256 = evm.call(addr: c, gas: 1000000, value: 0, message: TupleKeyMsg::Read6 { a: 13, b: 14, c: 15, d: 16, e: 17, f: 19 })
125+
assert!(v6_missing == 0)
126+
}

ingots/std/src/evm/storage_map.fe

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,67 @@ where A: StorageKey,
204204
a_len + b_len
205205
}
206206
}
207+
208+
impl<A, B, C> StorageKey for (A, B, C)
209+
where A: StorageKey,
210+
B: StorageKey,
211+
C: StorageKey {
212+
#[inline(always)]
213+
fn write_key(ptr: u256, self) -> u256 {
214+
let a_len = A::write_key(ptr: ptr, self.0)
215+
let b_len = B::write_key(ptr: ptr + a_len, self.1)
216+
let c_len = C::write_key(ptr: ptr + a_len + b_len, self.2)
217+
a_len + b_len + c_len
218+
}
219+
}
220+
221+
impl<A, B, C, D> StorageKey for (A, B, C, D)
222+
where A: StorageKey,
223+
B: StorageKey,
224+
C: StorageKey,
225+
D: StorageKey {
226+
#[inline(always)]
227+
fn write_key(ptr: u256, self) -> u256 {
228+
let a_len = A::write_key(ptr: ptr, self.0)
229+
let b_len = B::write_key(ptr: ptr + a_len, self.1)
230+
let c_len = C::write_key(ptr: ptr + a_len + b_len, self.2)
231+
let d_len = D::write_key(ptr: ptr + a_len + b_len + c_len, self.3)
232+
a_len + b_len + c_len + d_len
233+
}
234+
}
235+
236+
impl<A, B, C, D, E> StorageKey for (A, B, C, D, E)
237+
where A: StorageKey,
238+
B: StorageKey,
239+
C: StorageKey,
240+
D: StorageKey,
241+
E: StorageKey {
242+
#[inline(always)]
243+
fn write_key(ptr: u256, self) -> u256 {
244+
let a_len = A::write_key(ptr: ptr, self.0)
245+
let b_len = B::write_key(ptr: ptr + a_len, self.1)
246+
let c_len = C::write_key(ptr: ptr + a_len + b_len, self.2)
247+
let d_len = D::write_key(ptr: ptr + a_len + b_len + c_len, self.3)
248+
let e_len = E::write_key(ptr: ptr + a_len + b_len + c_len + d_len, self.4)
249+
a_len + b_len + c_len + d_len + e_len
250+
}
251+
}
252+
253+
impl<A, B, C, D, E, F> StorageKey for (A, B, C, D, E, F)
254+
where A: StorageKey,
255+
B: StorageKey,
256+
C: StorageKey,
257+
D: StorageKey,
258+
E: StorageKey,
259+
F: StorageKey {
260+
#[inline(always)]
261+
fn write_key(ptr: u256, self) -> u256 {
262+
let a_len = A::write_key(ptr: ptr, self.0)
263+
let b_len = B::write_key(ptr: ptr + a_len, self.1)
264+
let c_len = C::write_key(ptr: ptr + a_len + b_len, self.2)
265+
let d_len = D::write_key(ptr: ptr + a_len + b_len + c_len, self.3)
266+
let e_len = E::write_key(ptr: ptr + a_len + b_len + c_len + d_len, self.4)
267+
let f_len = F::write_key(ptr: ptr + a_len + b_len + c_len + d_len + e_len, self.5)
268+
a_len + b_len + c_len + d_len + e_len + f_len
269+
}
270+
}

0 commit comments

Comments
 (0)