mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 01:05:47 +00:00
Migrate the deposit_contract crate to alloy (#8139)
https://github.com/sigp/lighthouse/issues/6022 Switches the `deposit_contract` crate to use the `alloy` ecosystem and removes the dependency on `ethabi` Co-Authored-By: Mac L <mjladson@pm.me>
This commit is contained in:
@@ -1,23 +1,44 @@
|
||||
use ethabi::{Contract, Token};
|
||||
use alloy_dyn_abi::{DynSolValue, JsonAbiExt};
|
||||
use alloy_json_abi::JsonAbi;
|
||||
use alloy_primitives::FixedBytes;
|
||||
use ssz::{Decode, DecodeError as SszDecodeError, Encode};
|
||||
use tree_hash::TreeHash;
|
||||
use types::{DepositData, Hash256, PublicKeyBytes, SignatureBytes};
|
||||
|
||||
pub use ethabi::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DecodeError {
|
||||
EthabiError(ethabi::Error),
|
||||
pub enum Error {
|
||||
AlloyCoreError(alloy_json_abi::Error),
|
||||
SerdeJsonError(serde_json::Error),
|
||||
DynAbiError(alloy_dyn_abi::Error),
|
||||
SszDecodeError(SszDecodeError),
|
||||
FunctionNotFound,
|
||||
MissingField,
|
||||
UnableToGetBytes,
|
||||
MissingToken,
|
||||
InadequateBytes,
|
||||
}
|
||||
|
||||
impl From<ethabi::Error> for DecodeError {
|
||||
fn from(e: ethabi::Error) -> DecodeError {
|
||||
DecodeError::EthabiError(e)
|
||||
impl From<alloy_json_abi::Error> for Error {
|
||||
fn from(e: alloy_json_abi::Error) -> Error {
|
||||
Error::AlloyCoreError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for Error {
|
||||
fn from(e: serde_json::Error) -> Error {
|
||||
Error::SerdeJsonError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<alloy_dyn_abi::Error> for Error {
|
||||
fn from(e: alloy_dyn_abi::Error) -> Error {
|
||||
Error::DynAbiError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SszDecodeError> for Error {
|
||||
fn from(e: SszDecodeError) -> Error {
|
||||
Error::SszDecodeError(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,47 +57,57 @@ pub mod testnet {
|
||||
|
||||
pub fn encode_eth1_tx_data(deposit_data: &DepositData) -> Result<Vec<u8>, Error> {
|
||||
let params = vec![
|
||||
Token::Bytes(deposit_data.pubkey.as_ssz_bytes()),
|
||||
Token::Bytes(deposit_data.withdrawal_credentials.as_ssz_bytes()),
|
||||
Token::Bytes(deposit_data.signature.as_ssz_bytes()),
|
||||
Token::FixedBytes(deposit_data.tree_hash_root().as_ssz_bytes()),
|
||||
DynSolValue::Bytes(deposit_data.pubkey.as_ssz_bytes()),
|
||||
DynSolValue::Bytes(deposit_data.withdrawal_credentials.as_ssz_bytes()),
|
||||
DynSolValue::Bytes(deposit_data.signature.as_ssz_bytes()),
|
||||
DynSolValue::FixedBytes(
|
||||
FixedBytes::<32>::from_slice(&deposit_data.tree_hash_root().as_ssz_bytes()),
|
||||
32,
|
||||
),
|
||||
];
|
||||
|
||||
// Here we make an assumption that the `crate::testnet::ABI` has a superset of the features of
|
||||
// the crate::ABI`.
|
||||
let abi = Contract::load(ABI)?;
|
||||
let function = abi.function("deposit")?;
|
||||
function.encode_input(¶ms)
|
||||
let abi: JsonAbi = serde_json::from_slice(ABI)?;
|
||||
let function = abi
|
||||
.function("deposit")
|
||||
.and_then(|functions| functions.first())
|
||||
.ok_or(Error::FunctionNotFound)?;
|
||||
|
||||
function
|
||||
.abi_encode_input(¶ms)
|
||||
.map_err(Error::DynAbiError)
|
||||
}
|
||||
|
||||
pub fn decode_eth1_tx_data(
|
||||
bytes: &[u8],
|
||||
amount: u64,
|
||||
) -> Result<(DepositData, Hash256), DecodeError> {
|
||||
let abi = Contract::load(ABI)?;
|
||||
let function = abi.function("deposit")?;
|
||||
let mut tokens = function.decode_input(bytes.get(4..).ok_or(DecodeError::InadequateBytes)?)?;
|
||||
pub fn decode_eth1_tx_data(bytes: &[u8], amount: u64) -> Result<(DepositData, Hash256), Error> {
|
||||
let abi: JsonAbi = serde_json::from_slice(ABI)?;
|
||||
let function = abi
|
||||
.function("deposit")
|
||||
.and_then(|functions| functions.first())
|
||||
.ok_or(Error::FunctionNotFound)?;
|
||||
|
||||
let input_data = bytes.get(4..).ok_or(Error::InadequateBytes)?;
|
||||
let mut tokens = function.abi_decode_input(input_data)?;
|
||||
|
||||
macro_rules! decode_token {
|
||||
($type: ty, $to_fn: ident) => {
|
||||
<$type>::from_ssz_bytes(
|
||||
&tokens
|
||||
.pop()
|
||||
.ok_or_else(|| DecodeError::MissingToken)?
|
||||
.$to_fn()
|
||||
.ok_or_else(|| DecodeError::UnableToGetBytes)?,
|
||||
)
|
||||
.map_err(DecodeError::SszDecodeError)?
|
||||
};
|
||||
($type: ty) => {{
|
||||
let token = tokens.pop().ok_or(Error::MissingToken)?;
|
||||
let bytes_data = match token {
|
||||
DynSolValue::Bytes(b) => b,
|
||||
DynSolValue::FixedBytes(b, _) => b.to_vec(),
|
||||
_ => return Err(Error::UnableToGetBytes),
|
||||
};
|
||||
<$type>::from_ssz_bytes(&bytes_data)?
|
||||
}};
|
||||
}
|
||||
|
||||
let root = decode_token!(Hash256, into_fixed_bytes);
|
||||
let root = decode_token!(Hash256);
|
||||
|
||||
let deposit_data = DepositData {
|
||||
amount,
|
||||
signature: decode_token!(SignatureBytes, into_bytes),
|
||||
withdrawal_credentials: decode_token!(Hash256, into_bytes),
|
||||
pubkey: decode_token!(PublicKeyBytes, into_bytes),
|
||||
signature: decode_token!(SignatureBytes),
|
||||
withdrawal_credentials: decode_token!(Hash256),
|
||||
pubkey: decode_token!(PublicKeyBytes),
|
||||
};
|
||||
|
||||
Ok((deposit_data, root))
|
||||
|
||||
Reference in New Issue
Block a user