Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: primitive utils and improvements #52

Merged
merged 21 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,25 @@ ruint-macro = { version = "1.0.2", git = "https://github.com/recmo/uint", defaul

# serde
serde = { version = "1.0", default-features = false }
serde_json = { version = "1.0", default-features = false }
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }

# macros
proc-macro2 = "1.0"
quote = "1.0"
syn = "2.0"

derive_more = "0.99"
hex-literal = "0.4"
strum = { version = "0.24", features = ["derive"] }
num_enum = "0.6"
thiserror = "1.0"

# misc
arbitrary = { version = "1.3", default-features = false }
arrayvec = { version = "0.7.2", default-features = false }
bytes = { version = "1.4", default-features = false }
hex = { package = "const-hex", version = ">=1.3", default-features = false }
hex-literal = "0.4"
proptest = { version = "1.1", default-features = false }
hex = { package = "const-hex", version = ">=1.5", default-features = false, features = ["alloc"] }
once_cell = "1.17"
proptest = "1.1"
proptest-derive = "0.3"
thiserror = "1.0"
tiny-keccak = "2.0"
6 changes: 5 additions & 1 deletion crates/dyn-abi/src/eip712/typed_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,14 @@ pub struct TypedData {
/// the signature (e.g. the dapp, protocol, etc. that it's intended for).
/// This data is used to construct the domain seperator of the message.
pub domain: Eip712Domain,

/// The custom types used by this message.
pub resolver: Resolver,
#[serde(rename = "primaryType")]

/// The type of the message.
#[serde(rename = "primaryType")]
pub primary_type: String,

/// The message to be signed.
pub message: serde_json::Value,
}
Expand Down Expand Up @@ -233,6 +236,7 @@ mod tests {
use serde_json::json;

#[test]
#[ignore = "Uint Serde"]
fn test_full_domain() {
let json = json!({
"types": {
Expand Down
8 changes: 2 additions & 6 deletions crates/dyn-abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(not(feature = "std"), no_std)]
#![doc = include_str!("../README.md")]
#![warn(
missing_docs,
unreachable_pub,
Expand All @@ -17,11 +17,7 @@
clippy::missing_const_for_fn
)]
#![deny(unused_must_use, rust_2018_idioms)]
#![doc(test(
no_crate_inject,
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
))]
#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]

#[macro_use]
extern crate alloc;
Expand Down
94 changes: 53 additions & 41 deletions crates/dyn-abi/src/value.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{no_std_prelude::*, Word};
use ethers_primitives::{aliases::*, Address, I256, U256};
use ethers_primitives::{Address, I256, U256};

/// This type represents a Solidity value that has been decoded into rust. It
/// is broadly similar to `serde_json::Value` in that it is an enum of possible
Expand Down Expand Up @@ -32,7 +32,7 @@ pub enum DynSolValue {
name: String,
/// The struct's prop names, in declaration order.
prop_names: Vec<String>,
/// A inner types.
/// The inner types.
tuple: Vec<DynSolValue>,
},
/// A user-defined value type.
Expand Down Expand Up @@ -66,7 +66,7 @@ impl DynSolValue {
/// Fallible cast to a single word. Will succeed for any single-word type.
pub fn as_word(&self) -> Option<Word> {
match self {
Self::Address(a) => Some((*a).into()),
Self::Address(a) => Some(a.into_word()),
Self::Bool(b) => Some({
let mut buf = [0u8; 32];
if *b {
Expand Down Expand Up @@ -185,12 +185,12 @@ impl DynSolValue {
/// Encodes the packed value and appends it to the end of a byte array.
pub fn encode_packed_to(&self, buf: &mut Vec<u8>) {
match self {
DynSolValue::Address(addr) => buf.extend_from_slice(addr.as_bytes()),
DynSolValue::Bool(b) => buf.push(*b as u8),
DynSolValue::Bytes(bytes) => buf.extend_from_slice(bytes),
DynSolValue::FixedBytes(word, size) => buf.extend_from_slice(&word.as_bytes()[..*size]),
DynSolValue::Int(num, size) => {
let mut bytes = num.to_be_bytes();
Self::Address(addr) => buf.extend_from_slice(addr.as_bytes()),
Self::Bool(b) => buf.push(*b as u8),
Self::Bytes(bytes) => buf.extend_from_slice(bytes),
Self::FixedBytes(word, size) => buf.extend_from_slice(&word.as_bytes()[..*size]),
Self::Int(num, size) => {
let mut bytes = num.to_be_bytes::<32>();
let start = 32 - *size;
if num.is_negative() {
bytes[start] |= 0x80;
Expand All @@ -199,17 +199,17 @@ impl DynSolValue {
}
buf.extend_from_slice(&bytes[start..])
}
DynSolValue::Uint(num, size) => {
Self::Uint(num, size) => {
buf.extend_from_slice(&num.to_be_bytes::<32>().as_slice()[(32 - *size)..])
}
DynSolValue::String(s) => buf.extend_from_slice(s.as_bytes()),
DynSolValue::Tuple(inner)
| DynSolValue::Array(inner)
| DynSolValue::FixedArray(inner)
| DynSolValue::CustomStruct { tuple: inner, .. } => {
inner.iter().for_each(|v| v.encode_packed_to(buf));
Self::String(s) => buf.extend_from_slice(s.as_bytes()),
Self::Tuple(inner)
| Self::Array(inner)
| Self::FixedArray(inner)
| Self::CustomStruct { tuple: inner, .. } => {
inner.iter().for_each(|v| v.encode_packed_to(buf))
}
DynSolValue::CustomValue { inner, .. } => buf.extend_from_slice(inner.as_bytes()),
Self::CustomValue { inner, .. } => buf.extend_from_slice(inner.as_bytes()),
}
}

Expand All @@ -222,65 +222,77 @@ impl DynSolValue {
}

impl From<Address> for DynSolValue {
#[inline]
fn from(value: Address) -> Self {
Self::Address(value)
}
}

impl From<bool> for DynSolValue {
#[inline]
fn from(value: bool) -> Self {
Self::Bool(value)
}
}

impl From<Vec<u8>> for DynSolValue {
#[inline]
fn from(value: Vec<u8>) -> Self {
Self::Bytes(value)
}
}

macro_rules! impl_from_int {
($size:ty) => {
impl From<$size> for DynSolValue {
fn from(value: $size) -> Self {
let bits = <$size>::BITS as usize;
let bytes = bits / 8;
($($t:ty),+) => {$(
impl From<$t> for DynSolValue {
#[inline]
fn from(value: $t) -> Self {
const BITS: usize = <$t>::BITS as usize;
const BYTES: usize = BITS / 8;
const _: () = assert!(BYTES <= 32);

let mut word = if value.is_negative() {
ethers_primitives::B256::repeat_byte(0xff)
} else {
ethers_primitives::B256::default()
};
word[32 - bytes..].copy_from_slice(&value.to_be_bytes());
word[32 - BYTES..].copy_from_slice(&value.to_be_bytes());

Self::Int(I256::from_be_bytes(word.into()), bits)
Self::Int(I256::from_be_bytes(word.0), BITS)
}
}
};
($($size:ty),+) => {
$(impl_from_int!($size);)+
};
)+};
}

impl_from_int!(
i8, i16, i32, i64, isize, i128, I24, I40, I48, I56, I72, I80, I88, I96, I104, I112, I120, I128,
I136, I144, I152, I160, I168, I176, I184, I192, I200, I208, I216, I224, I232, I240, I248, I256
);
impl_from_int!(i8, i16, i32, i64, isize, i128);

impl From<I256> for DynSolValue {
#[inline]
fn from(value: I256) -> Self {
Self::Int(value, 256)
}
}

macro_rules! impl_from_uint {
($size:ty) => {
impl From<$size> for DynSolValue {
fn from(value: $size) -> Self {
Self::Uint(U256::from(value), <$size>::BITS as usize)
($($t:ty),+) => {$(
impl From<$t> for DynSolValue {
#[inline]
fn from(value: $t) -> Self {
Self::Uint(U256::from(value), <$t>::BITS as usize)
}
}
};
($($size:ty),+) => {
$(impl_from_uint!($size);)+
};
)+};
}

// TODO: more?
impl_from_uint!(u8, u16, u32, u64, usize, u128, U256);
impl_from_uint!(u8, u16, u32, u64, usize, u128);

impl From<U256> for DynSolValue {
#[inline]
fn from(value: U256) -> Self {
Self::Uint(value, 256)
}
}

impl From<String> for DynSolValue {
fn from(value: String) -> Self {
Expand Down
32 changes: 18 additions & 14 deletions crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
description = "Fundamental ethereum types shared by revm, reth and ethers"
readme = "README.md"
keywords = ["ethereum", "ethers", "revm", "reth"]
categories = ["cryptography::cryptocurrencies"]
categories = ["data-structures", "cryptography::cryptocurrencies"]

edition.workspace = true
rust-version.workspace = true
Expand All @@ -15,34 +15,38 @@ repository.workspace = true

[dependencies]
# eth
ruint = { workspace = true, features = ["rlp", "serde"] }
ruint = { workspace = true, features = ["serde"] }

# utility
derive_more = "0.99"
tiny-keccak = { workspace = true, features = ["keccak"] }
bytes.workspace = true
getrandom = "0.2"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

likely breaks wasm?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This? https://docs.rs/getrandom/latest/getrandom/#webassembly-support

This feature should only be enabled for binary, test, or benchmark crates. Library crates should generally not enable this feature, leaving such a decision to users of their library. Also, libraries should not introduce their own js features just to enable getrandom’s js feature.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot 2023-05-31 at 10 10 59 AM

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay only change I want here is documentation that wasm users must set this feature in either their dev-deps or their main deps

that can be in a separate PR

hex.workspace = true
itoa = "1"
tiny-keccak = { workspace = true, features = ["keccak"] }

# optional
serde = { workspace = true, features = ["derive"], optional = true }
# macros
derive_more.workspace = true

# rlp support
# rlp
ethers-rlp = { workspace = true, optional = true }
bytes = { workspace = true, optional = true }

# prop tests
# serde
serde = { workspace = true, optional = true }

# arbitrary
arbitrary = { workspace = true, features = ["derive"], optional = true }
proptest = { workspace = true, optional = true }
proptest-derive = { workspace = true, optional = true }

[dev-dependencies]
hex-literal = "0.4"
hex-literal.workspace = true
serde_json.workspace = true

[features]
default = ["std", "rlp", "serde", "hex/std"]
std = ["serde/std", "ethers-rlp?/std", "bytes?/std", "proptest?/std"]
rlp = ["dep:ethers-rlp", "dep:bytes"]
serde = ["dep:serde", "ruint/serde"]
default = ["std", "rlp", "serde"]
std = ["bytes/std", "hex/std", "ethers-rlp?/std", "proptest?/std", "serde/std"]
rlp = ["dep:ethers-rlp", "ruint/fastrlp"]
serde = ["dep:serde", "bytes/serde", "hex/serde", "ruint/serde"]
arbitrary = [
"ruint/arbitrary",
"ruint/proptest",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
use super::Signed;
//! Type aliases for common primitive types.

use crate::{Signed, B256};

pub use ruint::aliases::{
U0, U1, U1024, U128, U16, U160, U192, U2048, U256, U32, U320, U384, U4096, U448, U512, U64, U8,
};

/// The 0-bit signed integer type, capable of representing 0.
pub type I0 = Signed<0, 0>;
Expand Down Expand Up @@ -101,3 +107,31 @@ pub type I248 = Signed<248, 4>;

/// 256-bit signed integer type.
pub type I256 = Signed<256, 4>;

/// A block hash.
pub type BlockHash = B256;

/// A block number.
pub type BlockNumber = u64;

/// A transaction hash is a kecack hash of an RLP encoded signed transaction.
pub type TxHash = B256;

/// The sequence number of all existing transactions.
pub type TxNumber = u64;

/// The index of transaction in a block.
pub type TxIndex = u64;

/// Chain identifier type (introduced in EIP-155).
pub type ChainId = u64;

/// An account storage key.
pub type StorageKey = B256;

/// An account storage value.
pub type StorageValue = U256;

/// Solidity contract functions are addressed using the first four byte of the
/// Keccak-256 hash of their signature
pub type Selector = [u8; 4];
Loading