Misc Fixes (#97)
* fix: use generic instead of impl Trait * fix: do not skip first 4 bytes when decoding outputs
This commit is contained in:
parent
c30f45fc72
commit
84aafbbd1f
|
@ -21,6 +21,9 @@ pub enum AbiError {
|
||||||
/// Thrown when detokenizing an argument
|
/// Thrown when detokenizing an argument
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
DetokenizationError(#[from] InvalidOutputType),
|
DetokenizationError(#[from] InvalidOutputType),
|
||||||
|
|
||||||
|
#[error("missing or wrong function selector")]
|
||||||
|
WrongSelector,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A reduced form of `Contract` which just takes the `abi` and produces
|
/// A reduced form of `Contract` which just takes the `abi` and produces
|
||||||
|
@ -33,7 +36,7 @@ pub struct BaseContract {
|
||||||
/// functions in the contract ABI. This is used to avoid allocation when
|
/// functions in the contract ABI. This is used to avoid allocation when
|
||||||
/// searching for matching functions by signature.
|
/// searching for matching functions by signature.
|
||||||
// Adapted from: https://github.com/gnosis/ethcontract-rs/blob/master/src/contract.rs
|
// Adapted from: https://github.com/gnosis/ethcontract-rs/blob/master/src/contract.rs
|
||||||
pub(crate) methods: HashMap<Selector, (String, usize)>,
|
pub methods: HashMap<Selector, (String, usize)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Abi> for BaseContract {
|
impl From<Abi> for BaseContract {
|
||||||
|
@ -68,10 +71,10 @@ impl BaseContract {
|
||||||
///
|
///
|
||||||
/// If the function exists multiple times and you want to use one of the overloaded
|
/// If the function exists multiple times and you want to use one of the overloaded
|
||||||
/// versions, consider using `decode_with_selector`
|
/// versions, consider using `decode_with_selector`
|
||||||
pub fn decode<D: Detokenize>(
|
pub fn decode<D: Detokenize, T: AsRef<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
bytes: impl AsRef<[u8]>,
|
bytes: T,
|
||||||
) -> Result<D, AbiError> {
|
) -> Result<D, AbiError> {
|
||||||
let function = self.abi.function(name)?;
|
let function = self.abi.function(name)?;
|
||||||
decode_fn(function, bytes, true)
|
decode_fn(function, bytes, true)
|
||||||
|
@ -90,10 +93,10 @@ impl BaseContract {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decodes the provided ABI encoded bytes with the selected function selector
|
/// Decodes the provided ABI encoded bytes with the selected function selector
|
||||||
pub fn decode_with_selector<D: Detokenize>(
|
pub fn decode_with_selector<D: Detokenize, T: AsRef<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
signature: Selector,
|
signature: Selector,
|
||||||
bytes: impl AsRef<[u8]>,
|
bytes: T,
|
||||||
) -> Result<D, AbiError> {
|
) -> Result<D, AbiError> {
|
||||||
let function = self.get_from_signature(signature)?;
|
let function = self.get_from_signature(signature)?;
|
||||||
decode_fn(function, bytes, true)
|
decode_fn(function, bytes, true)
|
||||||
|
@ -152,20 +155,19 @@ pub(crate) fn encode_fn<T: Tokenize>(function: &Function, args: T) -> Result<Byt
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for decoding bytes from a specific function
|
// Helper for decoding bytes from a specific function
|
||||||
pub(crate) fn decode_fn<D: Detokenize>(
|
pub fn decode_fn<D: Detokenize, T: AsRef<[u8]>>(
|
||||||
function: &Function,
|
function: &Function,
|
||||||
bytes: impl AsRef<[u8]>,
|
bytes: T,
|
||||||
is_input: bool,
|
is_input: bool,
|
||||||
) -> Result<D, AbiError> {
|
) -> Result<D, AbiError> {
|
||||||
let mut bytes = bytes.as_ref();
|
let bytes = bytes.as_ref();
|
||||||
if bytes.starts_with(&function.selector()) {
|
|
||||||
bytes = &bytes[4..];
|
|
||||||
}
|
|
||||||
|
|
||||||
let tokens = if is_input {
|
let tokens = if is_input {
|
||||||
function.decode_input(bytes.as_ref())?
|
if bytes.len() < 4 || bytes[..4] != function.selector() {
|
||||||
|
return Err(AbiError::WrongSelector);
|
||||||
|
}
|
||||||
|
function.decode_input(&bytes[4..])?
|
||||||
} else {
|
} else {
|
||||||
function.decode_output(bytes.as_ref())?
|
function.decode_output(bytes)?
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(D::from_tokens(tokens)?)
|
Ok(D::from_tokens(tokens)?)
|
||||||
|
|
|
@ -17,7 +17,7 @@ mod contract;
|
||||||
pub use contract::Contract;
|
pub use contract::Contract;
|
||||||
|
|
||||||
mod base;
|
mod base;
|
||||||
pub use base::BaseContract;
|
pub use base::{decode_fn, BaseContract};
|
||||||
|
|
||||||
mod call;
|
mod call;
|
||||||
pub use call::ContractError;
|
pub use call::ContractError;
|
||||||
|
|
|
@ -3,7 +3,7 @@ use serde::de::{Error, Unexpected};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
/// Wrapper type around Vec<u8> to deserialize/serialize "0x" prefixed ethereum hex strings
|
/// Wrapper type around Vec<u8> to deserialize/serialize "0x" prefixed ethereum hex strings
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize, Ord, PartialOrd)]
|
||||||
pub struct Bytes(
|
pub struct Bytes(
|
||||||
#[serde(
|
#[serde(
|
||||||
serialize_with = "serialize_bytes",
|
serialize_with = "serialize_bytes",
|
||||||
|
|
|
@ -380,7 +380,7 @@ pub trait Middleware: Sync + Send + Debug {
|
||||||
req: TransactionRequest,
|
req: TransactionRequest,
|
||||||
trace_type: Vec<TraceType>,
|
trace_type: Vec<TraceType>,
|
||||||
block: Option<BlockNumber>,
|
block: Option<BlockNumber>,
|
||||||
) -> Result<BlockTrace, ProviderError> {
|
) -> Result<BlockTrace, Self::Error> {
|
||||||
self.inner()
|
self.inner()
|
||||||
.trace_call(req, trace_type, block)
|
.trace_call(req, trace_type, block)
|
||||||
.await
|
.await
|
||||||
|
@ -392,7 +392,7 @@ pub trait Middleware: Sync + Send + Debug {
|
||||||
&self,
|
&self,
|
||||||
data: Bytes,
|
data: Bytes,
|
||||||
trace_type: Vec<TraceType>,
|
trace_type: Vec<TraceType>,
|
||||||
) -> Result<BlockTrace, ProviderError> {
|
) -> Result<BlockTrace, Self::Error> {
|
||||||
self.inner()
|
self.inner()
|
||||||
.trace_raw_transaction(data, trace_type)
|
.trace_raw_transaction(data, trace_type)
|
||||||
.await
|
.await
|
||||||
|
@ -404,7 +404,7 @@ pub trait Middleware: Sync + Send + Debug {
|
||||||
&self,
|
&self,
|
||||||
hash: H256,
|
hash: H256,
|
||||||
trace_type: Vec<TraceType>,
|
trace_type: Vec<TraceType>,
|
||||||
) -> Result<BlockTrace, ProviderError> {
|
) -> Result<BlockTrace, Self::Error> {
|
||||||
self.inner()
|
self.inner()
|
||||||
.trace_replay_transaction(hash, trace_type)
|
.trace_replay_transaction(hash, trace_type)
|
||||||
.await
|
.await
|
||||||
|
@ -416,7 +416,7 @@ pub trait Middleware: Sync + Send + Debug {
|
||||||
&self,
|
&self,
|
||||||
block: BlockNumber,
|
block: BlockNumber,
|
||||||
trace_type: Vec<TraceType>,
|
trace_type: Vec<TraceType>,
|
||||||
) -> Result<Vec<BlockTrace>, ProviderError> {
|
) -> Result<Vec<BlockTrace>, Self::Error> {
|
||||||
self.inner()
|
self.inner()
|
||||||
.trace_replay_block_transactions(block, trace_type)
|
.trace_replay_block_transactions(block, trace_type)
|
||||||
.await
|
.await
|
||||||
|
@ -424,12 +424,12 @@ pub trait Middleware: Sync + Send + Debug {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns traces created at given block
|
/// Returns traces created at given block
|
||||||
async fn trace_block(&self, block: BlockNumber) -> Result<Vec<Trace>, ProviderError> {
|
async fn trace_block(&self, block: BlockNumber) -> Result<Vec<Trace>, Self::Error> {
|
||||||
self.inner().trace_block(block).await.map_err(FromErr::from)
|
self.inner().trace_block(block).await.map_err(FromErr::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return traces matching the given filter
|
/// Return traces matching the given filter
|
||||||
async fn trace_filter(&self, filter: TraceFilter) -> Result<Vec<Trace>, ProviderError> {
|
async fn trace_filter(&self, filter: TraceFilter) -> Result<Vec<Trace>, Self::Error> {
|
||||||
self.inner()
|
self.inner()
|
||||||
.trace_filter(filter)
|
.trace_filter(filter)
|
||||||
.await
|
.await
|
||||||
|
@ -441,7 +441,7 @@ pub trait Middleware: Sync + Send + Debug {
|
||||||
&self,
|
&self,
|
||||||
hash: H256,
|
hash: H256,
|
||||||
index: Vec<T>,
|
index: Vec<T>,
|
||||||
) -> Result<Trace, ProviderError> {
|
) -> Result<Trace, Self::Error> {
|
||||||
self.inner()
|
self.inner()
|
||||||
.trace_get(hash, index)
|
.trace_get(hash, index)
|
||||||
.await
|
.await
|
||||||
|
@ -449,7 +449,7 @@ pub trait Middleware: Sync + Send + Debug {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all traces of a given transaction
|
/// Returns all traces of a given transaction
|
||||||
async fn trace_transaction(&self, hash: H256) -> Result<Vec<Trace>, ProviderError> {
|
async fn trace_transaction(&self, hash: H256) -> Result<Vec<Trace>, Self::Error> {
|
||||||
self.inner()
|
self.inner()
|
||||||
.trace_transaction(hash)
|
.trace_transaction(hash)
|
||||||
.await
|
.await
|
||||||
|
|
Loading…
Reference in New Issue