Skip to content

Commit 5d9d537

Browse files
authored
chore: consolidate RLP numeric assertions with ToBEBytes trait (#14)
1 parent 85fb44a commit 5d9d537

File tree

9 files changed

+118
-179
lines changed

9 files changed

+118
-179
lines changed

ethereum/circuits/lib/src/rlp/README.md

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,22 +59,14 @@ Whe working with RLP data - it's a common pattern to have a structure (Tx, Log,
5959
```rust
6060
let rlp = [...];
6161
let decoded = decode_list(Fragment::from_array(rlp));
62-
decoded.get(0).assert_eq_u64("nonce", rlp, 0x10);
63-
decoded.get(1).assert_eq_address("to", rlp, [...]);
62+
decoded.get(0).assert_eq_value("nonce", rlp, 0x10);
63+
decoded.get(1).assert_eq_value("to", rlp, [...]);
6464
```
6565

6666
### The full list of those methods:
6767

68-
- `assert_eq_bytes`
69-
- `assert_eq_bounded_vec`
68+
- `assert_eq_value`
7069
- `assert_empty_string`
71-
- `assert_eq_u1`
72-
- `assert_eq_u8`
73-
- `assert_eq_u32`
74-
- `assert_eq_u64`
75-
- `assert_eq_u128`
76-
- `assert_eq_address`
77-
- `assert_eq_bytes32`
7870

7971
## RlpList
8072

Lines changed: 61 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
use crate::misc::bytes::byte_value;
22
use crate::misc::fragment::Fragment;
33
use crate::misc::types::{Address, Bytes32};
4-
use crate::verifiers::tx_helpers::idx::u32_to_u8;
5-
use crate::verifiers::tx_helpers::idx::u64_to_u8;
64

75
// Enum for RLP data type
86
pub(crate) global STRING: u32 = 0;
97
pub(crate) global LIST: u32 = 1;
10-
118
pub type RlpList<let MAX_FIELDS: u32> = BoundedVec<RlpFragment, MAX_FIELDS>;
129

1310
pub struct RlpHeader {
@@ -31,112 +28,101 @@ pub struct RlpFragment {
3128
}
3229

3330
impl RlpFragment {
34-
pub(crate) fn assert_eq_bytes<let FIELD_NAME_LEN: u32, let MAX_RLP_LEN: u32, let MAX_VALUE_LEN: u32>(
31+
pub fn assert_eq_value<let FIELD_NAME_LEN: u32, let MAX_RLP_LEN: u32, let MAX_VALUE_LEN: u32, VALUE_TYPE>(
3532
self,
3633
field_name: str<FIELD_NAME_LEN>,
3734
rlp: Fragment<MAX_RLP_LEN, u8>,
38-
value: Fragment<MAX_VALUE_LEN, u8>,
39-
) {
35+
value: VALUE_TYPE,
36+
)
37+
where
38+
VALUE_TYPE: ToRlpFragment<MAX_VALUE_LEN>,
39+
{
40+
let value_fragment = value.to_fragment();
4041
assert(self.data_type == STRING, f"{field_name}: Invalid RLP type");
41-
assert(self.length == value.length, f"{field_name}: Invalid RLP length");
42+
assert(self.length == value_fragment.length, f"{field_name}: Invalid RLP length");
4243
assert(
43-
rlp.subfragment(self.offset, self.length).eq(value),
44+
rlp.subfragment(self.offset, self.length).eq(value_fragment),
4445
f"{field_name}: Invalid RLP value",
4546
);
4647
}
4748

48-
pub(crate) fn assert_eq_bounded_vec<let FIELD_NAME_LEN: u32, let MAX_RLP_LEN: u32, let MAX_VALUE_LEN: u32>(
49-
self,
50-
field_name: str<FIELD_NAME_LEN>,
51-
rlp: Fragment<MAX_RLP_LEN, u8>,
52-
value: BoundedVec<u8, MAX_VALUE_LEN>,
53-
) {
54-
self.assert_eq_bytes(field_name, rlp, Fragment::from_vec(value));
55-
}
56-
5749
pub(crate) fn assert_empty_string<let FIELD_NAME_LEN: u32>(
5850
self,
5951
field_name: str<FIELD_NAME_LEN>,
6052
) {
6153
assert(self.data_type == STRING, f"{field_name}: Invalid RLP type");
6254
assert(self.length == 0, f"{field_name}: Expected empty string");
6355
}
56+
}
6457

65-
pub(crate) fn assert_eq_u1<let FIELD_NAME_LEN: u32, let MAX_RLP_LEN: u32>(
66-
self,
67-
field_name: str<FIELD_NAME_LEN>,
68-
rlp: Fragment<MAX_RLP_LEN, u8>,
69-
value: u1,
70-
) {
71-
self.assert_eq_bytes(field_name, rlp, Fragment::from_array([value as u8]));
58+
impl Default for RlpFragment {
59+
fn default() -> Self {
60+
RlpFragment { offset: 0, length: 0, data_type: 0 }
7261
}
62+
}
7363

74-
pub(crate) fn assert_eq_u8<let FIELD_NAME_LEN: u32, let MAX_RLP_LEN: u32>(
75-
self,
76-
field_name: str<FIELD_NAME_LEN>,
77-
rlp: Fragment<MAX_RLP_LEN, u8>,
78-
value: u8,
79-
) {
80-
self.assert_eq_bounded_vec(field_name, rlp, byte_value([value]));
64+
impl Eq for RlpFragment {
65+
fn eq(self, other: Self) -> bool {
66+
(self.offset == other.offset)
67+
& (self.length == other.length)
68+
& (self.data_type == other.data_type)
8169
}
70+
}
8271

83-
pub(crate) fn assert_eq_u32<let FIELD_NAME_LEN: u32, let MAX_RLP_LEN: u32>(
84-
self,
85-
field_name: str<FIELD_NAME_LEN>,
86-
rlp: Fragment<MAX_RLP_LEN, u8>,
87-
value: u32,
88-
) {
89-
self.assert_eq_bounded_vec(field_name, rlp, byte_value(u32_to_u8(value)));
72+
trait ToRlpFragment<let MAX_VALUE_LEN: u32> {
73+
fn to_fragment(self) -> Fragment<MAX_VALUE_LEN, u8>;
74+
}
75+
76+
impl ToRlpFragment<1> for u1 {
77+
fn to_fragment(self) -> Fragment<1, u8> {
78+
Fragment::from_array([self as u8])
9079
}
80+
}
9181

92-
pub fn assert_eq_u64<let FIELD_NAME_LEN: u32, let MAX_RLP_LEN: u32>(
93-
self,
94-
field_name: str<FIELD_NAME_LEN>,
95-
rlp: Fragment<MAX_RLP_LEN, u8>,
96-
value: u64,
97-
) {
98-
self.assert_eq_bounded_vec(field_name, rlp, byte_value(u64_to_u8(value)));
82+
impl ToRlpFragment<1> for u8 {
83+
fn to_fragment(self) -> Fragment<1, u8> {
84+
Fragment::from_vec(byte_value::<1>([self]))
9985
}
86+
}
10087

101-
pub fn assert_eq_u128<let FIELD_NAME_LEN: u32, let MAX_RLP_LEN: u32>(
102-
self,
103-
field_name: str<FIELD_NAME_LEN>,
104-
rlp: Fragment<MAX_RLP_LEN, u8>,
105-
value: u128,
106-
) {
107-
let val: Field = value as Field;
108-
self.assert_eq_bounded_vec(field_name, rlp, byte_value(val.to_be_bytes::<16>()));
88+
impl ToRlpFragment<4> for u32 {
89+
fn to_fragment(self) -> Fragment<4, u8> {
90+
Fragment::from_vec(byte_value::<4>((self as Field).to_be_bytes::<4>()))
10991
}
92+
}
11093

111-
pub(crate) fn assert_eq_address<let FIELD_NAME_LEN: u32, let MAX_RLP_LEN: u32>(
112-
self,
113-
field_name: str<FIELD_NAME_LEN>,
114-
rlp: Fragment<MAX_RLP_LEN, u8>,
115-
value: Address,
116-
) {
117-
self.assert_eq_bytes(field_name, rlp, Fragment::from_array(value));
94+
impl ToRlpFragment<8> for u64 {
95+
fn to_fragment(self) -> Fragment<8, u8> {
96+
Fragment::from_vec(byte_value::<8>((self as Field).to_be_bytes::<8>()))
11897
}
98+
}
11999

120-
pub(crate) fn assert_eq_bytes32<let FIELD_NAME_LEN: u32, let MAX_RLP_LEN: u32>(
121-
self,
122-
field_name: str<FIELD_NAME_LEN>,
123-
rlp: Fragment<MAX_RLP_LEN, u8>,
124-
value: Bytes32,
125-
) {
126-
self.assert_eq_bytes(field_name, rlp, Fragment::from_array(value));
100+
impl ToRlpFragment<16> for u128 {
101+
fn to_fragment(self) -> Fragment<16, u8> {
102+
Fragment::from_vec(byte_value::<16>((self as Field).to_be_bytes::<16>()))
127103
}
128104
}
129105

130-
impl Default for RlpFragment {
131-
fn default() -> Self {
132-
RlpFragment { offset: 0, length: 0, data_type: 0 }
106+
impl ToRlpFragment<20> for Address {
107+
fn to_fragment(self) -> Fragment<20, u8> {
108+
Fragment::from_array(self)
133109
}
134110
}
135111

136-
impl Eq for RlpFragment {
137-
fn eq(self, other: Self) -> bool {
138-
(self.offset == other.offset)
139-
& (self.length == other.length)
140-
& (self.data_type == other.data_type)
112+
impl ToRlpFragment<32> for Bytes32 {
113+
fn to_fragment(self) -> Fragment<32, u8> {
114+
Fragment::from_array(self)
115+
}
116+
}
117+
118+
impl<let MAX_FIELD_VALUE_LEN: u32> ToRlpFragment<MAX_FIELD_VALUE_LEN> for BoundedVec<u8, MAX_FIELD_VALUE_LEN> {
119+
fn to_fragment(self) -> Fragment<MAX_FIELD_VALUE_LEN, u8> {
120+
Fragment::from_vec(self)
121+
}
122+
}
123+
124+
impl<let MAX_FIELD_VALUE_LEN: u32> ToRlpFragment<MAX_FIELD_VALUE_LEN> for Fragment<MAX_FIELD_VALUE_LEN, u8> {
125+
fn to_fragment(self) -> Fragment<MAX_FIELD_VALUE_LEN, u8> {
126+
self
141127
}
142128
}

0 commit comments

Comments
 (0)