Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into bitvector
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelsproul committed Sep 3, 2024
2 parents 90804d4 + c28ae8c commit c8a1294
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 53 deletions.
11 changes: 6 additions & 5 deletions ssz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ethereum_ssz"
version = "0.5.4"
version = "0.7.1"
edition = "2021"
description = "SimpleSerialize (SSZ) as used in Ethereum"
license = "Apache-2.0"
Expand All @@ -14,11 +14,12 @@ categories = ["cryptography::cryptocurrencies"]
name = "ssz"

[dev-dependencies]
ethereum_ssz_derive = { version = "0.5.4", path = "../ssz_derive" }
alloy-primitives = { version = "0.8.0", features = ["getrandom"] }
ethereum_ssz_derive = { version = "0.7.1", path = "../ssz_derive" }

[dependencies]
ethereum-types = "0.14.1"
ethereum_serde_utils = "0.5.0"
alloy-primitives = "0.8.0"
ethereum_serde_utils = "0.7.0"
smallvec = { version = "1.6.1", features = ["const_generics"] }
itertools = "0.13.0"
serde = "1.0.0"
Expand All @@ -28,4 +29,4 @@ derivative = "2.1.1"
arbitrary = { version = "1.0", features = ["derive"], optional = true }

[features]
arbitrary = ["dep:arbitrary", "ethereum-types/arbitrary"]
arbitrary = ["dep:arbitrary", "alloy-primitives/arbitrary"]
57 changes: 47 additions & 10 deletions ssz/src/decode/impls.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::*;
use crate::decode::try_from_iter::{TryCollect, TryFromIter};
use alloy_primitives::{Address, Bloom, Bytes, FixedBytes, U128, U256};
use core::num::NonZeroUsize;
use ethereum_types::{H160, H256, U128, U256};
use itertools::process_results;
use smallvec::SmallVec;
use std::collections::{BTreeMap, BTreeSet};
Expand Down Expand Up @@ -275,7 +275,7 @@ impl<T: Decode> Decode for Arc<T> {
}
}

impl Decode for H160 {
impl Decode for Address {
fn is_ssz_fixed_len() -> bool {
true
}
Expand All @@ -296,13 +296,37 @@ impl Decode for H160 {
}
}

impl Decode for H256 {
impl<const N: usize> Decode for FixedBytes<N> {
fn is_ssz_fixed_len() -> bool {
true
}

fn ssz_fixed_len() -> usize {
32
N
}

fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
if bytes.len() != N {
return Err(DecodeError::InvalidByteLength {
len: bytes.len(),
expected: N,
});
}

let mut fixed_array = [0u8; N];
fixed_array.copy_from_slice(bytes);

Ok(Self(fixed_array))
}
}

impl Decode for Bloom {
fn is_ssz_fixed_len() -> bool {
true
}

fn ssz_fixed_len() -> usize {
256
}

fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
Expand All @@ -312,7 +336,7 @@ impl Decode for H256 {
if len != expected {
Err(DecodeError::InvalidByteLength { len, expected })
} else {
Ok(H256::from_slice(bytes))
Ok(Self::from_slice(bytes))
}
}
}
Expand All @@ -333,11 +357,23 @@ impl Decode for U256 {
if len != expected {
Err(DecodeError::InvalidByteLength { len, expected })
} else {
Ok(U256::from_little_endian(bytes))
Ok(U256::from_le_slice(bytes))
}
}
}

impl Decode for Bytes {
#[inline]
fn is_ssz_fixed_len() -> bool {
false
}

#[inline]
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
Ok(bytes.to_vec().into())
}
}

impl Decode for U128 {
fn is_ssz_fixed_len() -> bool {
true
Expand All @@ -354,7 +390,7 @@ impl Decode for U128 {
if len != expected {
Err(DecodeError::InvalidByteLength { len, expected })
} else {
Ok(U128::from_little_endian(bytes))
Ok(U128::from_le_slice(bytes))
}
}
}
Expand Down Expand Up @@ -527,6 +563,7 @@ pub fn decode_list_of_variable_length_items<T: Decode, Container: TryFromIter<T>
#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::B256;

// Note: decoding of valid bytes is generally tested "indirectly" in the `/tests` dir, by
// encoding then decoding the element.
Expand Down Expand Up @@ -576,17 +613,17 @@ mod tests {
}

#[test]
fn invalid_h256() {
fn invalid_b256() {
assert_eq!(
H256::from_ssz_bytes(&[0; 33]),
B256::from_ssz_bytes(&[0; 33]),
Err(DecodeError::InvalidByteLength {
len: 33,
expected: 32
})
);

assert_eq!(
H256::from_ssz_bytes(&[0; 31]),
B256::from_ssz_bytes(&[0; 31]),
Err(DecodeError::InvalidByteLength {
len: 31,
expected: 32
Expand Down
93 changes: 72 additions & 21 deletions ssz/src/encode/impls.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use alloy_primitives::{Address, Bloom, Bytes, FixedBytes, U128, U256};
use core::num::NonZeroUsize;
use ethereum_types::{H160, H256, U128, U256};
use smallvec::SmallVec;
use std::collections::{BTreeMap, BTreeSet};
use std::sync::Arc;
Expand Down Expand Up @@ -409,7 +409,7 @@ impl Encode for NonZeroUsize {
}
}

impl Encode for H160 {
impl Encode for Address {
fn is_ssz_fixed_len() -> bool {
true
}
Expand All @@ -423,25 +423,83 @@ impl Encode for H160 {
}

fn ssz_append(&self, buf: &mut Vec<u8>) {
buf.extend_from_slice(self.as_bytes());
buf.extend_from_slice(self.as_slice());
}
}

impl Encode for H256 {
impl<const N: usize> Encode for FixedBytes<N> {
#[inline]
fn is_ssz_fixed_len() -> bool {
true
}

#[inline]
fn ssz_bytes_len(&self) -> usize {
N
}

#[inline]
fn ssz_fixed_len() -> usize {
32
N
}

#[inline]
fn ssz_append(&self, buf: &mut Vec<u8>) {
buf.extend_from_slice(&self.0);
}

#[inline]
fn as_ssz_bytes(&self) -> Vec<u8> {
self.0.to_vec()
}
}

impl Encode for Bloom {
#[inline]
fn is_ssz_fixed_len() -> bool {
true
}

#[inline]
fn ssz_bytes_len(&self) -> usize {
32
256
}

#[inline]
fn ssz_fixed_len() -> usize {
256
}

#[inline]
fn ssz_append(&self, buf: &mut Vec<u8>) {
buf.extend_from_slice(self.as_bytes());
buf.extend_from_slice(&self.0 .0);
}

#[inline]
fn as_ssz_bytes(&self) -> Vec<u8> {
self.0.to_vec()
}
}

impl Encode for Bytes {
#[inline]
fn is_ssz_fixed_len() -> bool {
false
}

#[inline]
fn ssz_bytes_len(&self) -> usize {
self.0.len()
}

#[inline]
fn ssz_append(&self, buf: &mut Vec<u8>) {
buf.extend_from_slice(&self.0);
}

#[inline]
fn as_ssz_bytes(&self) -> Vec<u8> {
self.0.to_vec()
}
}

Expand All @@ -459,11 +517,7 @@ impl Encode for U256 {
}

fn ssz_append(&self, buf: &mut Vec<u8>) {
let n = <Self as Encode>::ssz_fixed_len();
let s = buf.len();

buf.resize(s + n, 0);
self.to_little_endian(&mut buf[s..]);
buf.extend_from_slice(self.as_le_slice());
}
}

Expand All @@ -481,11 +535,7 @@ impl Encode for U128 {
}

fn ssz_append(&self, buf: &mut Vec<u8>) {
let n = <Self as Encode>::ssz_fixed_len();
let s = buf.len();

buf.resize(s + n, 0);
self.to_little_endian(&mut buf[s..]);
buf.extend_from_slice(self.as_le_slice());
}
}

Expand Down Expand Up @@ -518,6 +568,7 @@ impl_encodable_for_u8_array!(48);
#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::B256;

#[test]
fn vec_of_u8() {
Expand Down Expand Up @@ -619,16 +670,16 @@ mod tests {
}

#[test]
fn ssz_encode_h256() {
assert_eq!(H256::from(&[0; 32]).as_ssz_bytes(), vec![0; 32]);
assert_eq!(H256::from(&[1; 32]).as_ssz_bytes(), vec![1; 32]);
fn ssz_encode_b256() {
assert_eq!(B256::from(&[0; 32]).as_ssz_bytes(), vec![0; 32]);
assert_eq!(B256::from(&[1; 32]).as_ssz_bytes(), vec![1; 32]);

let bytes = vec![
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
];

assert_eq!(H256::from_slice(&bytes).as_ssz_bytes(), bytes);
assert_eq!(B256::from_slice(&bytes).as_ssz_bytes(), bytes);
}

#[test]
Expand Down
Loading

0 comments on commit c8a1294

Please sign in to comment.