Skip to content

Commit

Permalink
Change FixBytes internal encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
danhper committed Sep 15, 2024
1 parent 4d172e5 commit 099f937
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 22 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Not released

### Other changes

* Encode `FixedBytes` as with zero padding on the left instead of the right

## v0.1.3 (2024-08-15)

### Features
Expand Down
39 changes: 22 additions & 17 deletions src/interpreter/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,11 +467,11 @@ impl Type {
(Type::Int(size), Value::Uint(v, _)) => {
Value::Int((*v).try_into()?, *size).validate_int()
}
(Type::FixBytes(bytes_num), Value::Uint(v, bits_num))
(t @ Type::FixBytes(bytes_num), Value::Uint(v, bits_num))
if *bytes_num * 8 == *bits_num =>
{
let bytes = B256::from_slice(&v.to_be_bytes_vec());
Ok(Value::FixBytes(bytes, *bytes_num))
t.cast(&Value::FixBytes(bytes, 32))
}
(Type::Uint(bits_num), Value::FixBytes(v, bytes_num))
if *bytes_num * 8 == *bits_num =>
Expand All @@ -480,9 +480,13 @@ impl Type {
Ok(Value::Uint(num, *bits_num))
}
(Type::FixBytes(target_bytes_num), Value::FixBytes(bytes, _)) => {
let mut new_bytes = bytes.0.to_vec();
new_bytes.resize(*target_bytes_num, 0); // "erase" all bytes after target_bytes_num
new_bytes.resize(32, 0); // pad with zero to be able to create a B256
let mut new_bytes = bytes.to_vec();
if *target_bytes_num < 32 {
let to_fill = 32 - *target_bytes_num;
let filler = vec![0; to_fill];
new_bytes[..to_fill].copy_from_slice(&filler);
}
new_bytes[..bytes.0.len()].copy_from_slice(&bytes.0);
Ok(Value::FixBytes(
B256::from_slice(&new_bytes),
*target_bytes_num,
Expand All @@ -491,10 +495,14 @@ impl Type {
(Type::Transaction, Value::FixBytes(v, 32)) => Ok(Value::Transaction(*v)),
(Type::Bytes, Value::Str(v)) => Ok(Value::Bytes(v.as_bytes().to_vec())),
(type_ @ Type::FixBytes(_), Value::Str(_)) => type_.cast(&Type::Bytes.cast(value)?),
(Type::Bytes, Value::FixBytes(v, _)) => Ok(Value::Bytes(v.0.to_vec())),
(Type::FixBytes(size), Value::Bytes(v)) => {
let mut new_vector = v.clone();
new_vector.resize(*size, 0);
Ok(Value::FixBytes(B256::from_slice(&new_vector), *size))
let mut new_bytes = v.clone();
if new_bytes.len() > *size {
new_bytes = new_bytes[new_bytes.len() - *size..].to_vec();
}
new_bytes.resize(32, 0);
Ok(Value::FixBytes(B256::from_slice(&new_bytes), *size))
}
(Type::NamedTuple(name, types_), Value::Tuple(values)) => {
let mut new_values = IndexMap::new();
Expand Down Expand Up @@ -678,16 +686,13 @@ mod tests {

#[test]
fn cast_bytes() {
let signature =
Value::from_hex("0x70a08231b98ef4ca268c9cc3f6b4590e4bfec28280db06bb5d45e689f2a360be")
let b256_value =
Value::from_hex("0x00000000000000000000000000000000000000000000000000000000281dd5af")
.unwrap();
let selector = Value::from_hex("0x70a08231").unwrap();
assert_eq!(Type::FixBytes(4).cast(&signature).unwrap(), selector);
let padded_selector = "0x70a0823100000000000000000000000000000000000000000000000000000000";
assert_eq!(
Type::FixBytes(32).cast(&selector).unwrap(),
Value::from_hex(padded_selector).unwrap()
);
println!("{:?}", b256_value);
let b4_value = Value::from_hex("0x281dd5af").unwrap();
assert_eq!(Type::FixBytes(4).cast(&b256_value).unwrap(), b4_value);
assert_eq!(Type::FixBytes(32).cast(&b4_value).unwrap(), b256_value);
}

#[test]
Expand Down
12 changes: 7 additions & 5 deletions src/interpreter/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl Display for Value {
Value::Addr(a) => write!(f, "{}", a.to_checksum(None)),
Value::Str(s) => write!(f, "\"{}\"", s),
Value::FixBytes(w, s) => {
let bytes = w[..*s].to_vec();
let bytes = w[32 - *s..].to_vec();
write!(f, "0x{}", hex::encode(bytes))
}
Value::Bytes(bytes) => write!(f, "0x{}", hex::encode(bytes)),
Expand Down Expand Up @@ -292,8 +292,9 @@ impl FromHex for Value {
} else if hex.as_ref().len() == 42 {
Value::Addr(Address::from_hex(hex)?)
} else if hex.as_ref().len() <= 66 {
let mut bytes = Vec::from_hex(&hex.as_ref()[2..])?;
bytes.resize(32, 0);
let data = Vec::from_hex(&hex.as_ref()[2..])?;
let mut bytes = vec![0; 32];
bytes[32 - data.len()..].copy_from_slice(&data);
Value::FixBytes(B256::from_slice(&bytes), (hex.as_ref().len() - 2) / 2)
} else {
Value::Bytes(Vec::from_hex(&hex.as_ref()[2..])?)
Expand Down Expand Up @@ -748,8 +749,9 @@ mod tests {
assert_eq!(value, Value::Addr(addr));

let value = Value::from_hex("0xdeadbeef").unwrap();
let mut bytes = Vec::from_hex("deadbeef").unwrap();
bytes.resize(32, 0);
let bytes =
Vec::from_hex("00000000000000000000000000000000000000000000000000000000deadbeef")
.unwrap();
let fix_bytes = B256::from_slice(&bytes);
assert_eq!(value, Value::FixBytes(fix_bytes, 4));
}
Expand Down

0 comments on commit 099f937

Please sign in to comment.