Update to the latest alloy

Also makes various tweaks as necessary.
This commit is contained in:
Luke Parker
2024-05-10 13:33:56 -04:00
parent 21123590bb
commit 5501de1f3a
9 changed files with 91 additions and 73 deletions

View File

@@ -31,7 +31,10 @@ pub fn address(point: &ProjectivePoint) -> [u8; 20] {
keccak256(&encoded_point.as_ref()[1 .. 65])[12 ..].try_into().unwrap()
}
pub(crate) fn deterministically_sign(tx: &TxLegacy) -> Signed<TxLegacy> {
/// Deterministically sign a transaction.
///
/// This function panics if passed a transaction with a non-None chain ID.
pub fn deterministically_sign(tx: &TxLegacy) -> Signed<TxLegacy> {
assert!(
tx.chain_id.is_none(),
"chain ID was Some when deterministically signing a TX (causing a non-deterministic signer)"

View File

@@ -4,7 +4,7 @@ use alloy_core::primitives::{Address, B256, U256};
use alloy_sol_types::{SolInterface, SolEvent};
use alloy_rpc_types::{BlockNumberOrTag, Filter};
use alloy_rpc_types::Filter;
use alloy_simple_request_transport::SimpleRequest;
use alloy_provider::{Provider, RootProvider};
@@ -25,22 +25,8 @@ pub struct TopLevelErc20Transfer {
pub struct Erc20(Arc<RootProvider<SimpleRequest>>, Address);
impl Erc20 {
/// Construct a new view of the specified ERC20 contract.
///
/// This checks a contract is deployed at that address yet does not check the contract is
/// actually an ERC20.
pub async fn new(
provider: Arc<RootProvider<SimpleRequest>>,
address: [u8; 20],
) -> Result<Option<Self>, Error> {
let code = provider
.get_code_at(address.into(), BlockNumberOrTag::Finalized.into())
.await
.map_err(|_| Error::ConnectionError)?;
// Contract has yet to be deployed
if code.is_empty() {
return Ok(None);
}
Ok(Some(Self(provider.clone(), Address::from(&address))))
pub fn new(provider: Arc<RootProvider<SimpleRequest>>, address: [u8; 20]) -> Self {
Self(provider, Address::from(&address))
}
pub async fn top_level_transfers(
@@ -65,7 +51,8 @@ impl Erc20 {
}
let tx_id = log.transaction_hash.ok_or(Error::ConnectionError)?;
let tx = self.0.get_transaction_by_hash(tx_id).await.map_err(|_| Error::ConnectionError)?;
let tx =
self.0.get_transaction_by_hash(tx_id).await.ok().flatten().ok_or(Error::ConnectionError)?;
// If this is a top-level call...
if tx.to == Some(self.1) {

View File

@@ -1,8 +1,10 @@
use thiserror::Error;
pub use alloy_core;
pub use alloy_consensus;
pub use alloy_sol_types;
pub use alloy_consensus;
pub use alloy_network;
pub use alloy_rpc_types;
pub use alloy_simple_request_transport;
pub use alloy_rpc_client;
@@ -18,8 +20,8 @@ pub mod router;
pub mod machine;
#[cfg(test)]
mod tests;
#[cfg(any(test, feature = "tests"))]
pub mod tests;
#[derive(Clone, Copy, PartialEq, Eq, Debug, Error)]
pub enum Error {

View File

@@ -159,11 +159,12 @@ impl Router {
#[cfg(test)]
pub async fn serai_key(&self, at: [u8; 32]) -> Result<PublicKey, Error> {
let call = TransactionRequest::default()
.to(Some(self.1))
.to(self.1)
.input(TransactionInput::new(abi::seraiKeyCall::new(()).abi_encode().into()));
let bytes = self
.0
.call(&call, Some(BlockId::Hash(B256::from(at).into())))
.call(&call)
.block(BlockId::Hash(B256::from(at).into()))
.await
.map_err(|_| Error::ConnectionError)?;
let res =
@@ -197,11 +198,12 @@ impl Router {
#[cfg(test)]
pub async fn nonce(&self, at: [u8; 32]) -> Result<U256, Error> {
let call = TransactionRequest::default()
.to(Some(self.1))
.to(self.1)
.input(TransactionInput::new(abi::nonceCall::new(()).abi_encode().into()));
let bytes = self
.0
.call(&call, Some(BlockId::Hash(B256::from(at).into())))
.call(&call)
.block(BlockId::Hash(B256::from(at).into()))
.await
.map_err(|_| Error::ConnectionError)?;
let res =
@@ -229,10 +231,13 @@ impl Router {
}
}
pub async fn key_at_end_of_block(&self, block: u64) -> Result<ProjectivePoint, Error> {
pub async fn key_at_end_of_block(&self, block: u64) -> Result<Option<ProjectivePoint>, Error> {
let filter = Filter::new().from_block(0).to_block(block).address(self.1);
let filter = filter.event_signature(SeraiKeyUpdated::SIGNATURE_HASH);
let all_keys = self.0.get_logs(&filter).await.map_err(|_| Error::ConnectionError)?;
if all_keys.is_empty() {
return Ok(None);
};
let last_key_x_coordinate_log = all_keys.last().ok_or(Error::ConnectionError)?;
let last_key_x_coordinate = last_key_x_coordinate_log
@@ -246,7 +251,9 @@ impl Router {
compressed_point[0] = u8::from(sec1::Tag::CompressedEvenY);
compressed_point[1 ..].copy_from_slice(last_key_x_coordinate.as_slice());
Option::from(ProjectivePoint::from_bytes(&compressed_point)).ok_or(Error::ConnectionError)
let key =
Option::from(ProjectivePoint::from_bytes(&compressed_point)).ok_or(Error::ConnectionError)?;
Ok(Some(key))
}
pub async fn in_instructions(
@@ -254,7 +261,9 @@ impl Router {
block: u64,
allowed_tokens: &HashSet<[u8; 20]>,
) -> Result<Vec<InInstruction>, Error> {
let key_at_end_of_block = self.key_at_end_of_block(block).await?;
let Some(key_at_end_of_block) = self.key_at_end_of_block(block).await? else {
return Ok(vec![]);
};
let filter = Filter::new().from_block(block).to_block(block).address(self.1);
let filter = filter.event_signature(InInstructionEvent::SIGNATURE_HASH);
@@ -274,7 +283,13 @@ impl Router {
);
let tx_hash = log.transaction_hash.ok_or(Error::ConnectionError)?;
let tx = self.0.get_transaction_by_hash(tx_hash).await.map_err(|_| Error::ConnectionError)?;
let tx = self
.0
.get_transaction_by_hash(tx_hash)
.await
.ok()
.flatten()
.ok_or(Error::ConnectionError)?;
let log =
log.log_decode::<InInstructionEvent>().map_err(|_| Error::ConnectionError)?.inner.data;

View File

@@ -11,16 +11,20 @@ use alloy_core::{
};
use alloy_consensus::{SignableTransaction, TxLegacy};
use alloy_rpc_types::TransactionReceipt;
use alloy_rpc_types::{BlockNumberOrTag, TransactionReceipt};
use alloy_simple_request_transport::SimpleRequest;
use alloy_provider::{Provider, RootProvider};
use crate::crypto::{address, deterministically_sign, PublicKey};
#[cfg(test)]
mod crypto;
#[cfg(test)]
mod abi;
#[cfg(test)]
mod schnorr;
#[cfg(test)]
mod router;
pub fn key_gen() -> (HashMap<Participant, ThresholdKeys<Secp256k1>>, PublicKey) {
@@ -53,14 +57,15 @@ pub async fn send(
// let chain_id = provider.get_chain_id().await.unwrap();
// tx.chain_id = Some(chain_id);
tx.chain_id = None;
tx.nonce = provider.get_transaction_count(address, None).await.unwrap();
tx.nonce =
provider.get_transaction_count(address, BlockNumberOrTag::Latest.into()).await.unwrap();
// 100 gwei
tx.gas_price = 100_000_000_000u128;
let sig = wallet.sign_prehash_recoverable(tx.signature_hash().as_ref()).unwrap();
assert_eq!(address, tx.clone().into_signed(sig.into()).recover_signer().unwrap());
assert!(
provider.get_balance(address, None).await.unwrap() >
provider.get_balance(address, BlockNumberOrTag::Latest.into()).await.unwrap() >
((U256::from(tx.gas_price) * U256::from(tx.gas_limit)) + tx.value)
);

View File

@@ -56,12 +56,12 @@ pub async fn call_verify(
let px: [u8; 32] = public_key.px.to_repr().into();
let c_bytes: [u8; 32] = signature.c.to_repr().into();
let s_bytes: [u8; 32] = signature.s.to_repr().into();
let call = TransactionRequest::default().to(Some(contract)).input(TransactionInput::new(
let call = TransactionRequest::default().to(contract).input(TransactionInput::new(
abi::verifyCall::new((px.into(), message.to_vec().into(), c_bytes.into(), s_bytes.into()))
.abi_encode()
.into(),
));
let bytes = provider.call(&call, None).await.map_err(|_| Error::ConnectionError)?;
let bytes = provider.call(&call).await.map_err(|_| Error::ConnectionError)?;
let res =
abi::verifyCall::abi_decode_returns(&bytes, true).map_err(|_| Error::ConnectionError)?;