Skip to content

Commit

Permalink
fix(decode): use proper bigint crate to map on ffi
Browse files Browse the repository at this point in the history
  • Loading branch information
ozgrakkurt committed Jun 12, 2024
1 parent 2a9fbde commit 211f5fa
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 23 deletions.
4 changes: 3 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[package]
name = "hypersync"
version = "0.7.4"
version = "0.7.5"
edition = "2021"

[lib]
name = "hypersync"
crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.20", features = ["extension-module", "anyhow"] }
pyo3 = { version = "0.20", features = ["extension-module", "anyhow", "num-bigint"] }
pyo3-asyncio = { version = "0.20", features = ["tokio-runtime"] }
tokio = "1"
dict_derive = "0.5"
Expand All @@ -24,3 +24,4 @@ prefix-hex = "0.7"
env_logger = "0.11"
faster-hex = "0.9"
ruint = "1"
num-bigint = "0.4"
66 changes: 46 additions & 20 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::str::FromStr;

use alloy_dyn_abi::DynSolValue;
use alloy_primitives::Signed;
use alloy_primitives::{Signed, U256};
use anyhow::{Context, Result};
use hypersync_client::{format, format::Hex, net_types, simple_types};
use pyo3::{ffi, pyclass, IntoPy, PyObject, Python};
use ruint::Uint;
use num_bigint::{BigInt, BigUint};
use pyo3::{pyclass, IntoPy, PyObject, Python};
use serde::{Deserialize, Serialize};

/// Data relating to a single event (log)
Expand Down Expand Up @@ -214,23 +216,8 @@ impl DecodedSolValue {
pub fn new(py: Python, val: DynSolValue, checksummed_addresses: bool) -> Self {
let val = match val {
DynSolValue::Bool(b) => b.into_py(py),
DynSolValue::Int(v, _) => {
let bytes: [u8; Signed::<256, 4>::BYTES] = v.to_le_bytes();
let ptr: *const u8 = bytes.as_ptr();
unsafe {
let obj = ffi::_PyLong_FromByteArray(ptr, Signed::<256, 4>::BYTES, 1, 1);
PyObject::from_owned_ptr(py, obj)
}
}
DynSolValue::Uint(v, _) => {
//v.into_py(py)
let bytes: [u8; Uint::<256, 4>::BYTES] = v.to_le_bytes();
let ptr: *const u8 = bytes.as_ptr();
unsafe {
let obj = ffi::_PyLong_FromByteArray(ptr, Uint::<256, 4>::BYTES, 1, 0);
PyObject::from_owned_ptr(py, obj)
}
}
DynSolValue::Int(v, _) => convert_bigint_signed(v).into_py(py),
DynSolValue::Uint(v, _) => convert_bigint_unsigned(v).into_py(py),
DynSolValue::FixedBytes(bytes, _) => encode_prefix_hex(bytes.as_slice()).into_py(py),
DynSolValue::Address(addr) => {
if !checksummed_addresses {
Expand Down Expand Up @@ -458,3 +445,42 @@ impl RollbackGuard {
})
}
}

fn convert_bigint_signed(v: Signed<256, 4>) -> BigInt {
BigInt::from_str(&v.to_string()).unwrap()
}

fn convert_bigint_unsigned(v: U256) -> BigUint {
BigUint::from_str(&v.to_string()).unwrap()
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_bigint_convert_signed() {
for i in (i128::from(i64::MIN)..i128::from(u64::MAX))
.step_by(usize::try_from(u64::MAX / 31).unwrap())
.take(1024)
{
let v = Signed::<256, 4>::try_from(i).unwrap();
let out = convert_bigint_signed(v);

assert_eq!(i128::try_from(v).unwrap(), i128::try_from(out).unwrap());
}
}

#[test]
fn test_bigint_convert_unsigned() {
for i in (u128::from(u64::MIN)..u128::MAX)
.step_by(usize::try_from(u64::MAX / 31).unwrap())
.take(1024)
{
let v = U256::from(i);
let out = convert_bigint_unsigned(v);

assert_eq!(u128::try_from(v).unwrap(), u128::try_from(out).unwrap());
}
}
}

0 comments on commit 211f5fa

Please sign in to comment.