1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#![cfg(feature = "rlp")]
#![cfg_attr(has_doc_cfg, doc(cfg(feature = "rlp")))]
use crate::Uint;
use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
impl<const BITS: usize, const LIMBS: usize> Encodable for Uint<BITS, LIMBS> {
fn rlp_append(&self, s: &mut RlpStream) {
let bytes = self.to_be_bytes_vec();
let bytes = trim_leading_zeros(&bytes);
bytes.rlp_append(s);
}
}
impl<const BITS: usize, const LIMBS: usize> Decodable for Uint<BITS, LIMBS> {
fn decode(s: &Rlp) -> Result<Self, DecoderError> {
Self::try_from_be_slice(s.data()?).ok_or(DecoderError::Custom(
"RLP integer value too large for Uint.",
))
}
}
fn trim_leading_zeros(bytes: &[u8]) -> &[u8] {
let zeros = bytes.iter().position(|&b| b != 0).unwrap_or(bytes.len());
&bytes[zeros..]
}
#[cfg(test)]
mod test {
use super::*;
use crate::{
aliases::{U0, U256},
const_for, nlimbs,
};
use hex_literal::hex;
use proptest::proptest;
#[test]
fn test_rlp() {
assert_eq!(U0::from(0).rlp_bytes()[..], hex!("80"));
assert_eq!(U256::from(0).rlp_bytes()[..], hex!("80"));
assert_eq!(U256::from(15).rlp_bytes()[..], hex!("0f"));
assert_eq!(U256::from(1024).rlp_bytes()[..], hex!("820400"));
assert_eq!(U256::from(0x1234_5678).rlp_bytes()[..], hex!("8412345678"));
}
#[test]
fn test_roundtrip() {
const_for!(BITS in SIZES {
const LIMBS: usize = nlimbs(BITS);
proptest!(|(value: Uint<BITS, LIMBS>)| {
let serialized = value.rlp_bytes();
let deserialized = Uint::decode(&Rlp::new(&serialized)).unwrap();
assert_eq!(value, deserialized);
});
});
}
}