arbos/util/
serialization.rs

1use alloy_primitives::{Address, B256, U256};
2use std::io::{self, Read, Write};
3
4/// Reads a 32-byte hash from a reader.
5pub fn hash_from_reader<R: Read>(r: &mut R) -> io::Result<B256> {
6    let mut buf = [0u8; 32];
7    r.read_exact(&mut buf)?;
8    Ok(B256::from(buf))
9}
10
11/// Writes a 32-byte hash to a writer.
12pub fn hash_to_writer<W: Write>(w: &mut W, hash: &B256) -> io::Result<()> {
13    w.write_all(hash.as_slice())
14}
15
16/// Reads a U256 from a reader (big-endian).
17pub fn uint256_from_reader<R: Read>(r: &mut R) -> io::Result<U256> {
18    let hash = hash_from_reader(r)?;
19    Ok(U256::from_be_bytes(hash.0))
20}
21
22/// Reads a 20-byte address from a reader.
23pub fn address_from_reader<R: Read>(r: &mut R) -> io::Result<Address> {
24    let mut buf = [0u8; 20];
25    r.read_exact(&mut buf)?;
26    Ok(Address::from(buf))
27}
28
29/// Writes a 20-byte address to a writer.
30pub fn address_to_writer<W: Write>(w: &mut W, addr: &Address) -> io::Result<()> {
31    w.write_all(addr.as_slice())
32}
33
34/// Reads a 32-byte padded address from a reader (last 20 bytes are the address).
35pub fn address_from_256_from_reader<R: Read>(r: &mut R) -> io::Result<Address> {
36    let hash = hash_from_reader(r)?;
37    Ok(Address::from_slice(&hash[12..]))
38}
39
40/// Writes a 32-byte padded address to a writer (left-padded with zeros).
41pub fn address_to_256_to_writer<W: Write>(w: &mut W, addr: &Address) -> io::Result<()> {
42    let mut buf = [0u8; 32];
43    buf[12..].copy_from_slice(addr.as_slice());
44    w.write_all(&buf)
45}
46
47/// Reads a uint64 from a reader (big-endian).
48pub fn uint64_from_reader<R: Read>(r: &mut R) -> io::Result<u64> {
49    let mut buf = [0u8; 8];
50    r.read_exact(&mut buf)?;
51    Ok(u64::from_be_bytes(buf))
52}
53
54/// Writes a uint64 to a writer (big-endian).
55pub fn uint64_to_writer<W: Write>(w: &mut W, val: u64) -> io::Result<()> {
56    w.write_all(&val.to_be_bytes())
57}
58
59/// Reads a length-prefixed byte string from a reader.
60pub fn bytestring_from_reader<R: Read>(r: &mut R) -> io::Result<Vec<u8>> {
61    let len = uint64_from_reader(r)? as usize;
62    let mut buf = vec![0u8; len];
63    r.read_exact(&mut buf)?;
64    Ok(buf)
65}
66
67/// Writes a length-prefixed byte string to a writer.
68pub fn bytestring_to_writer<W: Write>(w: &mut W, data: &[u8]) -> io::Result<()> {
69    uint64_to_writer(w, data.len() as u64)?;
70    w.write_all(data)
71}
72
73/// Converts a signed integer to a B256 hash (big-endian).
74pub fn int_to_hash(val: i64) -> B256 {
75    let mut buf = [0u8; 32];
76    if val >= 0 {
77        buf[24..].copy_from_slice(&(val as u64).to_be_bytes());
78    } else {
79        // Two's complement for negative values: fill with 0xFF.
80        buf.fill(0xFF);
81        buf[24..].copy_from_slice(&(val as u64).to_be_bytes());
82    }
83    B256::from(buf)
84}
85
86/// Converts an unsigned integer to a B256 hash (big-endian).
87pub fn uint_to_hash(val: u64) -> B256 {
88    let mut buf = [0u8; 32];
89    buf[24..].copy_from_slice(&val.to_be_bytes());
90    B256::from(buf)
91}
92
93/// Converts an address to a B256 hash (left-padded with zeros).
94pub fn address_to_hash(addr: &Address) -> B256 {
95    let mut buf = [0u8; 32];
96    buf[12..].copy_from_slice(addr.as_slice());
97    B256::from(buf)
98}