Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

Misc Fixes #97

Merged
merged 2 commits into from
Nov 12, 2020
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
30 changes: 16 additions & 14 deletions ethers-contract/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub enum AbiError {
/// Thrown when detokenizing an argument
#[error(transparent)]
DetokenizationError(#[from] InvalidOutputType),

#[error("missing or wrong function selector")]
WrongSelector,
}

/// A reduced form of `Contract` which just takes the `abi` and produces
Expand All @@ -33,7 +36,7 @@ pub struct BaseContract {
/// functions in the contract ABI. This is used to avoid allocation when
/// searching for matching functions by signature.
// 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 {
Expand Down Expand Up @@ -68,10 +71,10 @@ impl BaseContract {
///
/// If the function exists multiple times and you want to use one of the overloaded
/// versions, consider using `decode_with_selector`
pub fn decode<D: Detokenize>(
pub fn decode<D: Detokenize, T: AsRef<[u8]>>(
&self,
name: &str,
bytes: impl AsRef<[u8]>,
bytes: T,
) -> Result<D, AbiError> {
let function = self.abi.function(name)?;
decode_fn(function, bytes, true)
Expand All @@ -90,10 +93,10 @@ impl BaseContract {
}

/// 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,
signature: Selector,
bytes: impl AsRef<[u8]>,
bytes: T,
) -> Result<D, AbiError> {
let function = self.get_from_signature(signature)?;
decode_fn(function, bytes, true)
Expand Down Expand Up @@ -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
pub(crate) fn decode_fn<D: Detokenize>(
pub fn decode_fn<D: Detokenize, T: AsRef<[u8]>>(
function: &Function,
bytes: impl AsRef<[u8]>,
bytes: T,
is_input: bool,
) -> Result<D, AbiError> {
let mut bytes = bytes.as_ref();
if bytes.starts_with(&function.selector()) {
bytes = &bytes[4..];
}

let bytes = bytes.as_ref();
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 {
function.decode_output(bytes.as_ref())?
function.decode_output(bytes)?
};

Ok(D::from_tokens(tokens)?)
Expand Down
2 changes: 1 addition & 1 deletion ethers-contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ mod contract;
pub use contract::Contract;

mod base;
pub use base::BaseContract;
pub use base::{decode_fn, BaseContract};

mod call;
pub use call::ContractError;
Expand Down
2 changes: 1 addition & 1 deletion ethers-core/src/types/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use serde::de::{Error, Unexpected};
use serde::{Deserialize, Deserializer, Serialize, Serializer};

/// 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(
#[serde(
serialize_with = "serialize_bytes",
Expand Down
16 changes: 8 additions & 8 deletions ethers-providers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ pub trait Middleware: Sync + Send + Debug {
req: TransactionRequest,
trace_type: Vec<TraceType>,
block: Option<BlockNumber>,
) -> Result<BlockTrace, ProviderError> {
) -> Result<BlockTrace, Self::Error> {
self.inner()
.trace_call(req, trace_type, block)
.await
Expand All @@ -392,7 +392,7 @@ pub trait Middleware: Sync + Send + Debug {
&self,
data: Bytes,
trace_type: Vec<TraceType>,
) -> Result<BlockTrace, ProviderError> {
) -> Result<BlockTrace, Self::Error> {
self.inner()
.trace_raw_transaction(data, trace_type)
.await
Expand All @@ -404,7 +404,7 @@ pub trait Middleware: Sync + Send + Debug {
&self,
hash: H256,
trace_type: Vec<TraceType>,
) -> Result<BlockTrace, ProviderError> {
) -> Result<BlockTrace, Self::Error> {
self.inner()
.trace_replay_transaction(hash, trace_type)
.await
Expand All @@ -416,20 +416,20 @@ pub trait Middleware: Sync + Send + Debug {
&self,
block: BlockNumber,
trace_type: Vec<TraceType>,
) -> Result<Vec<BlockTrace>, ProviderError> {
) -> Result<Vec<BlockTrace>, Self::Error> {
self.inner()
.trace_replay_block_transactions(block, trace_type)
.await
.map_err(FromErr::from)
}

/// 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)
}

/// 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()
.trace_filter(filter)
.await
Expand All @@ -441,15 +441,15 @@ pub trait Middleware: Sync + Send + Debug {
&self,
hash: H256,
index: Vec<T>,
) -> Result<Trace, ProviderError> {
) -> Result<Trace, Self::Error> {
self.inner()
.trace_get(hash, index)
.await
.map_err(FromErr::from)
}

/// 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()
.trace_transaction(hash)
.await
Expand Down