diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 45997738..a06e16e3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,7 +3,7 @@ name: tests on: push: - branches: [ main ] + branches: [main] pull_request: workflow_dispatch: @@ -11,19 +11,19 @@ jobs: fmt: name: cargo fmt runs-on: ubuntu-latest - container: - image: rust:1.74-bookworm + container: + image: rust:1.79-bookworm steps: - uses: actions/checkout@v3 - run: | rustup component add rustfmt cargo fmt --all -- --check - + clippy: name: cargo clippy runs-on: ubuntu-latest - container: - image: rust:1.74-bookworm + container: + image: rust:1.79-bookworm steps: - uses: actions/checkout@v3 - uses: actions/cache@v3 @@ -36,9 +36,9 @@ jobs: target/ key: ${{ runner.os }}-cargo-clippy - run: | - rustup component add clippy - cargo clippy --all-targets --all-features -- -D warnings - + rustup component add clippy + cargo clippy --all-targets --all-features -- -D warnings + test-and-coverage: name: cargo test and coverage runs-on: ubuntu-latest @@ -47,7 +47,7 @@ jobs: pull-requests: write actions: read container: - image: rust:1.74-bookworm + image: rust:1.79-bookworm steps: - uses: actions/checkout@v3 - uses: actions/cache@v3 @@ -62,7 +62,7 @@ jobs: - name: Install cargo-llvm-cov uses: taiki-e/install-action@cargo-llvm-cov - name: Run tests and generate coverage report - run: cargo llvm-cov test --all-features --workspace --lcov --output-path lcov.info + run: cargo llvm-cov test --all-features --workspace --lcov --output-path lcov.info - name: Upload coverage to Coveralls uses: coverallsapp/github-action@v2.2.0 with: @@ -72,7 +72,7 @@ jobs: name: cargo test docs runs-on: ubuntu-latest container: - image: rust:1.74-bookworm + image: rust:1.79-bookworm steps: - uses: actions/checkout@v3 - uses: actions/cache@v3 diff --git a/Dockerfile.tap_aggregator b/Dockerfile.tap_aggregator index 00e417ed..34ab1a00 100644 --- a/Dockerfile.tap_aggregator +++ b/Dockerfile.tap_aggregator @@ -1,4 +1,4 @@ -FROM rust:1.74-bookworm as build +FROM rust:1.79-bookworm as build WORKDIR /root COPY . . diff --git a/tap_aggregator/Cargo.toml b/tap_aggregator/Cargo.toml index fc595136..71208e0a 100644 --- a/tap_aggregator/Cargo.toml +++ b/tap_aggregator/Cargo.toml @@ -16,9 +16,7 @@ anyhow = "1.0.70" tokio = { version = "1.27.0", features = ["macros", "signal"] } tap_core = { version = "1.0.0", path = "../tap_core" } jsonrpsee = { version = "0.18.0", features = ["server", "macros"] } -ethers-signers = "2.0.3" clap = { version = "4.2.4", features = ["derive", "env"] } -ethers-core = "2.0.3" serde = { version = "1.0.163", features = ["derive"] } serde_json = { version = "1.0.96", features = ["raw_value"] } strum = { version = "0.24.1", features = ["strum_macros", "derive"] } @@ -28,9 +26,7 @@ prometheus = "0.13.3" axum = "0.6.18" futures-util = "0.3.28" lazy_static = "1.4.0" -alloy-sol-types = { version = "0.7.0", features = ["eip712-serde"] } -alloy-primitives = { version = "0.7.0", features = ["serde"] } -ethereum-types = "0.14.1" +alloy = { version = "0.2.0", features = ["full"] } ruint = "1.10.1" [dev-dependencies] diff --git a/tap_aggregator/src/aggregator.rs b/tap_aggregator/src/aggregator.rs index 1fc44305..a6e4cb6d 100644 --- a/tap_aggregator/src/aggregator.rs +++ b/tap_aggregator/src/aggregator.rs @@ -3,21 +3,23 @@ use std::collections::{hash_set, HashSet}; -use alloy_primitives::Address; -use alloy_sol_types::{Eip712Domain, SolStruct}; +use alloy::{ + dyn_abi::Eip712Domain, primitives::Address, signers::local::PrivateKeySigner, + sol_types::SolStruct, +}; use anyhow::{bail, Ok, Result}; -use ethers_core::types::Signature; -use ethers_signers::LocalWallet; use tap_core::{ - rav::ReceiptAggregateVoucher, receipt::Receipt, signed_message::EIP712SignedMessage, + rav::ReceiptAggregateVoucher, + receipt::Receipt, + signed_message::{EIP712SignedMessage, SignatureBytes, SignatureBytesExt}, }; pub fn check_and_aggregate_receipts( domain_separator: &Eip712Domain, receipts: &[EIP712SignedMessage], previous_rav: Option>, - wallet: &LocalWallet, + wallet: &PrivateKeySigner, accepted_addresses: &HashSet
, ) -> Result> { check_signatures_unique(receipts)?; @@ -99,11 +101,15 @@ fn check_allocation_id( } fn check_signatures_unique(receipts: &[EIP712SignedMessage]) -> Result<()> { - let mut receipt_signatures: hash_set::HashSet = hash_set::HashSet::new(); + let mut receipt_signatures: hash_set::HashSet = hash_set::HashSet::new(); for receipt in receipts.iter() { - let signature = receipt.signature; + let signature = receipt.signature.get_signature_bytes(); if !receipt_signatures.insert(signature) { - return Err(tap_core::Error::DuplicateReceiptSignature(signature.to_string()).into()); + return Err(tap_core::Error::DuplicateReceiptSignature(format!( + "{:?}", + receipt.signature + )) + .into()); } } Ok(()) @@ -133,22 +139,17 @@ fn check_receipt_timestamps( mod tests { use std::str::FromStr; - use alloy_primitives::Address; - use alloy_sol_types::Eip712Domain; - use ethers_signers::{LocalWallet, Signer}; + use alloy::{dyn_abi::Eip712Domain, primitives::Address, signers::local::PrivateKeySigner}; use rstest::*; use crate::aggregator; use tap_core::{receipt::Receipt, signed_message::EIP712SignedMessage, tap_eip712_domain}; #[fixture] - fn keys() -> (LocalWallet, Address) { - let wallet = LocalWallet::from_str( - "1ab42cc412b618bdea3a599e3c9bae199ebf030895b039e9db1e30dafb12b727", - ) - .unwrap(); - let address: [u8; 20] = wallet.address().into(); - (wallet, address.into()) + fn keys() -> (PrivateKeySigner, Address) { + let wallet = PrivateKeySigner::random(); + let address = wallet.address(); + (wallet, address) } #[fixture] @@ -169,7 +170,7 @@ mod tests { #[rstest] #[test] fn check_signatures_unique_fail( - keys: (LocalWallet, Address), + keys: (PrivateKeySigner, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, ) { @@ -191,7 +192,7 @@ mod tests { #[rstest] #[test] fn check_signatures_unique_ok( - keys: (LocalWallet, Address), + keys: (PrivateKeySigner, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, ) { @@ -219,7 +220,7 @@ mod tests { #[test] /// Test that a receipt with a timestamp greater then the rav timestamp passes fn check_receipt_timestamps( - keys: (LocalWallet, Address), + keys: (PrivateKeySigner, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, ) { @@ -289,7 +290,7 @@ mod tests { /// Test check_allocation_id with 2 receipts that have the correct allocation id /// and 1 receipt that has the wrong allocation id fn check_allocation_id_fail( - keys: (LocalWallet, Address), + keys: (PrivateKeySigner, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, ) { @@ -323,7 +324,7 @@ mod tests { #[test] /// Test check_allocation_id with 3 receipts that have the correct allocation id fn check_allocation_id_ok( - keys: (LocalWallet, Address), + keys: (PrivateKeySigner, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, ) { diff --git a/tap_aggregator/src/main.rs b/tap_aggregator/src/main.rs index 4ecf87ff..6550c33c 100644 --- a/tap_aggregator/src/main.rs +++ b/tap_aggregator/src/main.rs @@ -7,11 +7,13 @@ use std::borrow::Cow; use std::collections::HashSet; use std::str::FromStr; -use alloy_primitives::{Address, FixedBytes, U256}; -use alloy_sol_types::Eip712Domain; +use alloy::dyn_abi::Eip712Domain; +use alloy::primitives::Address; +use alloy::primitives::FixedBytes; +use alloy::signers::local::PrivateKeySigner; use anyhow::Result; use clap::Parser; -use ethers_signers::{LocalWallet, Signer}; +use ruint::aliases::U256; use tokio::signal::unix::{signal, SignalKind}; use log::{debug, info}; @@ -96,7 +98,7 @@ async fn main() -> Result<()> { tokio::spawn(metrics::run_server(args.metrics_port)); // Create a wallet from the mnemonic. - let wallet = LocalWallet::from_str(&args.private_key)?; + let wallet = PrivateKeySigner::from_str(&args.private_key)?; info!("Wallet address: {:#40x}", wallet.address()); diff --git a/tap_aggregator/src/server.rs b/tap_aggregator/src/server.rs index 5a9f7eb4..7565c630 100644 --- a/tap_aggregator/src/server.rs +++ b/tap_aggregator/src/server.rs @@ -3,10 +3,10 @@ use std::{collections::HashSet, str::FromStr}; -use alloy_primitives::Address; -use alloy_sol_types::Eip712Domain; +use alloy::dyn_abi::Eip712Domain; +use alloy::primitives::Address; +use alloy::signers::local::PrivateKeySigner; use anyhow::Result; -use ethers_signers::LocalWallet; use jsonrpsee::{proc_macros::rpc, server::ServerBuilder, server::ServerHandle}; use lazy_static::lazy_static; use prometheus::{register_counter, register_int_counter, Counter, IntCounter}; @@ -91,7 +91,7 @@ pub trait Rpc { } struct RpcImpl { - wallet: LocalWallet, + wallet: PrivateKeySigner, accepted_addresses: HashSet
, domain_separator: Eip712Domain, } @@ -128,7 +128,7 @@ fn check_api_version_deprecation(api_version: &TapRpcApiVersion) -> Option, domain_separator: &Eip712Domain, receipts: Vec>, @@ -210,7 +210,7 @@ impl RpcServer for RpcImpl { pub async fn run_server( port: u16, - wallet: LocalWallet, + wallet: PrivateKeySigner, accepted_addresses: HashSet
, domain_separator: Eip712Domain, max_request_body_size: u32, @@ -243,9 +243,7 @@ mod tests { use std::collections::HashSet; use std::str::FromStr; - use alloy_primitives::Address; - use alloy_sol_types::Eip712Domain; - use ethers_signers::{coins_bip39::English, LocalWallet, MnemonicBuilder, Signer}; + use alloy::{dyn_abi::Eip712Domain, primitives::Address, signers::local::PrivateKeySigner}; use jsonrpsee::{core::client::ClientT, http_client::HttpClientBuilder, rpc_params}; use rand::prelude::*; use rand::seq::SliceRandom; @@ -259,25 +257,14 @@ mod tests { #[derive(Clone)] struct Keys { - wallet: LocalWallet, + wallet: PrivateKeySigner, address: Address, } - fn keys(index: u32) -> Keys { - let wallet: LocalWallet = MnemonicBuilder::::default() - .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") - .index(index) - .unwrap() - .build() - .unwrap(); - // Alloy library does not have feature parity with ethers library (yet) This workaround is needed to get the address - // to convert to an alloy Address. This will not be needed when the alloy library has wallet support. - let address: [u8; 20] = wallet.address().into(); - - Keys { - wallet, - address: address.into(), - } + fn keys() -> Keys { + let wallet = PrivateKeySigner::random(); + let address = wallet.address(); + Keys { wallet, address } } #[fixture] @@ -319,7 +306,7 @@ mod tests { http_max_concurrent_connections: u32, ) { // The keys that will be used to sign the new RAVs - let keys_main = keys(0); + let keys_main = keys(); // Start the JSON-RPC server. let (handle, local_addr) = server::run_server( @@ -362,10 +349,10 @@ mod tests { #[values(0, 1, 2)] random_seed: u64, ) { // The keys that will be used to sign the new RAVs - let keys_main = keys(0); + let keys_main = keys(); // Extra keys to test the server's ability to accept multiple signers as input - let keys_0 = keys(1); - let keys_1 = keys(2); + let keys_0 = keys(); + let keys_1 = keys(); // Vector of all wallets to make it easier to select one randomly let all_wallets = vec![keys_main.clone(), keys_0.clone(), keys_1.clone()]; // PRNG for selecting a random wallet @@ -443,10 +430,10 @@ mod tests { #[values(0, 1, 2, 3, 4)] random_seed: u64, ) { // The keys that will be used to sign the new RAVs - let keys_main = keys(0); + let keys_main = keys(); // Extra keys to test the server's ability to accept multiple signers as input - let keys_0 = keys(1); - let keys_1 = keys(2); + let keys_0 = keys(); + let keys_1 = keys(); // Vector of all wallets to make it easier to select one randomly let all_wallets = vec![keys_main.clone(), keys_0.clone(), keys_1.clone()]; // PRNG for selecting a random wallet @@ -528,7 +515,7 @@ mod tests { allocation_ids: Vec
, ) { // The keys that will be used to sign the new RAVs - let keys_main = keys(0); + let keys_main = keys(); // Start the JSON-RPC server. let (handle, local_addr) = server::run_server( @@ -611,7 +598,7 @@ mod tests { #[values("0.0")] api_version: &str, ) { // The keys that will be used to sign the new RAVs - let keys_main = keys(0); + let keys_main = keys(); // Set the request byte size limit to a value that easily triggers the HTTP 413 // error. diff --git a/tap_core/Cargo.toml b/tap_core/Cargo.toml index c7da42d4..c5367604 100644 --- a/tap_core/Cargo.toml +++ b/tap_core/Cargo.toml @@ -12,15 +12,9 @@ rand_core = "0.6.4" serde = { version = "1.0", features = ["derive", "rc"] } rand = "0.8.5" thiserror = "1.0.38" -ethereum-types = { version = "0.14.1" } rstest = "0.17.0" -ethers = { version = "2.0.0", default-features = false } -ethers-core = "2.0.0" -ethers-contract = "2.0.0" -ethers-contract-derive = "2.0.0" anyhow = "1" -alloy-sol-types = { version = "0.7.0", features = ["eip712-serde"] } -alloy-primitives = { version = "0.7.0", features = ["serde"] } +alloy = { version = "0.2.0", features = ["full"] } strum = "0.24.1" strum_macros = "0.24.3" diff --git a/tap_core/benches/timeline_aggretion_protocol_benchmark.rs b/tap_core/benches/timeline_aggretion_protocol_benchmark.rs index 1bc94be0..ff00de2a 100644 --- a/tap_core/benches/timeline_aggretion_protocol_benchmark.rs +++ b/tap_core/benches/timeline_aggretion_protocol_benchmark.rs @@ -10,12 +10,10 @@ use std::str::FromStr; -use alloy_primitives::Address; -use alloy_sol_types::Eip712Domain; +use alloy::dyn_abi::Eip712Domain; +use alloy::primitives::Address; +use alloy::signers::local::PrivateKeySigner; use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use ethers::signers::{LocalWallet, Signer, Wallet}; -use ethers_core::k256::ecdsa::SigningKey; -use rand_core::OsRng; use tap_core::tap_eip712_domain; use tap_core::{ rav::ReceiptAggregateVoucher, receipt::Receipt, signed_message::EIP712SignedMessage, @@ -25,7 +23,7 @@ pub fn create_and_sign_receipt( domain_separator: &Eip712Domain, allocation_id: Address, value: u128, - wallet: &Wallet, + wallet: &PrivateKeySigner, ) -> EIP712SignedMessage { EIP712SignedMessage::new( domain_separator, @@ -38,9 +36,8 @@ pub fn create_and_sign_receipt( pub fn criterion_benchmark(c: &mut Criterion) { let domain_seperator = tap_eip712_domain(1, Address::from([0x11u8; 20])); - let wallet = LocalWallet::new(&mut OsRng); - let address: [u8; 20] = wallet.address().into(); - let address: Address = address.into(); + let wallet = PrivateKeySigner::random(); + let address = wallet.address(); // Arbitrary values wrapped in black box to avoid compiler optimizing them out let allocation_id = Address::from_str("0xabababababababababababababababababababab").unwrap(); diff --git a/tap_core/src/error.rs b/tap_core/src/error.rs index fcb881e9..b5d1c562 100644 --- a/tap_core/src/error.rs +++ b/tap_core/src/error.rs @@ -5,9 +5,7 @@ //! use crate::{rav::ReceiptAggregateVoucher, receipt::ReceiptError}; -use alloy_primitives::Address; -use ethers::signers::WalletError; -use ethers_core::types::SignatureError; +use alloy::primitives::{Address, SignatureError}; use std::result::Result as StdResult; use thiserror::Error as ThisError; @@ -20,13 +18,21 @@ pub enum Error { /// Error when Rust fails to get the current system time #[error("Failed to get current system time: {source_error_message} ")] InvalidSystemTime { source_error_message: String }, - /// `ethers` wallet error + /// `alloy` wallet error #[error(transparent)] - WalletError(#[from] WalletError), - /// Error when signature verification fails + WalletError(#[from] alloy::signers::Error), + + /// `alloy` wallet error #[error(transparent)] SignatureError(#[from] SignatureError), + /// Error when signature verification fails + #[error("Expected address {expected} but received {received}")] + VerificationFailed { + expected: Address, + received: Address, + }, + /// Error when the received RAV does not match the expected RAV #[error("Received RAV does not match expexted RAV")] InvalidReceivedRAV { diff --git a/tap_core/src/lib.rs b/tap_core/src/lib.rs index 2afa51f3..eb09fe67 100644 --- a/tap_core/src/lib.rs +++ b/tap_core/src/lib.rs @@ -8,7 +8,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; -use alloy_sol_types::eip712_domain; +use alloy::{dyn_abi::Eip712Domain, sol_types::eip712_domain}; use thiserror::Error; mod error; @@ -46,8 +46,8 @@ fn get_current_timestamp_u64_ns() -> Result { /// - `verifying_contract`: The address of the contract that is verifying the signature. pub fn tap_eip712_domain( chain_id: u64, - verifying_contract_address: alloy_primitives::Address, -) -> alloy_sol_types::Eip712Domain { + verifying_contract_address: alloy::primitives::Address, +) -> Eip712Domain { eip712_domain! { name: "TAP", version: "1", @@ -60,9 +60,7 @@ pub fn tap_eip712_domain( mod tap_tests { use std::str::FromStr; - use alloy_primitives::Address; - use alloy_sol_types::Eip712Domain; - use ethers::signers::{coins_bip39::English, LocalWallet, MnemonicBuilder, Signer}; + use alloy::{dyn_abi::Eip712Domain, primitives::Address, signers::local::PrivateKeySigner}; use rstest::*; use crate::{ @@ -71,16 +69,11 @@ mod tap_tests { }; #[fixture] - fn keys() -> (LocalWallet, Address) { - let wallet: LocalWallet = MnemonicBuilder::::default() - .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") - .build() - .unwrap(); - // Alloy library does not have feature parity with ethers library (yet) This workaround is needed to get the address - // to convert to an alloy Address. This will not be needed when the alloy library has wallet support. - let address: [u8; 20] = wallet.address().into(); - - (wallet, address.into()) + fn keys() -> (PrivateKeySigner, Address) { + let wallet = PrivateKeySigner::random(); + let address = wallet.address(); + + (wallet, address) } #[fixture] @@ -103,7 +96,7 @@ mod tap_tests { #[case::rav_from_zero_valued_receipts (vec![0,0,0,0])] #[test] fn signed_rav_is_valid_with_no_previous_rav( - keys: (LocalWallet, Address), + keys: (PrivateKeySigner, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, #[case] values: Vec, @@ -134,7 +127,7 @@ mod tap_tests { #[case::rav_from_zero_valued_receipts(vec![0,0,0,0])] #[test] fn signed_rav_is_valid_with_previous_rav( - keys: (LocalWallet, Address), + keys: (PrivateKeySigner, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, #[case] values: Vec, @@ -177,7 +170,7 @@ mod tap_tests { #[rstest] #[test] fn verify_signature( - keys: (LocalWallet, Address), + keys: (PrivateKeySigner, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, ) { diff --git a/tap_core/src/manager/adapters/escrow.rs b/tap_core/src/manager/adapters/escrow.rs index 16375af1..6570c513 100644 --- a/tap_core/src/manager/adapters/escrow.rs +++ b/tap_core/src/manager/adapters/escrow.rs @@ -1,8 +1,7 @@ // Copyright 2023-, Semiotic AI, Inc. // SPDX-License-Identifier: Apache-2.0 -use alloy_primitives::Address; -use alloy_sol_types::Eip712Domain; +use alloy::{dyn_abi::Eip712Domain, primitives::Address}; use async_trait::async_trait; use crate::{ diff --git a/tap_core/src/manager/context/memory.rs b/tap_core/src/manager/context/memory.rs index efee75d0..a475cca8 100644 --- a/tap_core/src/manager/context/memory.rs +++ b/tap_core/src/manager/context/memory.rs @@ -12,7 +12,7 @@ use crate::{ receipt::{checks::StatefulTimestampCheck, state::Checking, ReceiptWithState}, signed_message::MessageId, }; -use alloy_primitives::Address; +use alloy::primitives::Address; use async_trait::async_trait; use std::ops::RangeBounds; use std::sync::RwLock; @@ -267,8 +267,7 @@ pub mod checks { }, signed_message::MessageId, }; - use alloy_primitives::Address; - use alloy_sol_types::Eip712Domain; + use alloy::{dyn_abi::Eip712Domain, primitives::Address}; use std::{ collections::{HashMap, HashSet}, sync::{Arc, RwLock}, @@ -291,34 +290,6 @@ pub mod checks { ] } - struct ValueCheck { - query_appraisals: Arc>>, - } - - #[async_trait::async_trait] - impl Check for ValueCheck { - async fn check(&self, receipt: &ReceiptWithState) -> CheckResult { - let value = receipt.signed_receipt().message.value; - let query_appraisals = self.query_appraisals.read().unwrap(); - let hash = receipt.signed_receipt().unique_hash(); - let appraised_value = - query_appraisals - .get(&hash) - .ok_or(ReceiptError::CheckFailedToComplete( - "Could not find query_appraisals".into(), - ))?; - - if value != *appraised_value { - Err(ReceiptError::InvalidValue { - received_value: value, - } - .into()) - } else { - Ok(()) - } - } - } - struct AllocationIdCheck { allocation_ids: Arc>>, } diff --git a/tap_core/src/manager/mod.rs b/tap_core/src/manager/mod.rs index 91dd8ef9..ab439b5e 100644 --- a/tap_core/src/manager/mod.rs +++ b/tap_core/src/manager/mod.rs @@ -60,13 +60,11 @@ //! } //! # #[tokio::main] //! # async fn main() { -//! # use alloy_primitives::Address; -//! # use alloy_sol_types::Eip712Domain; -//! # use ethers::signers::LocalWallet; +//! # use alloy::{dyn_abi::Eip712Domain, primitives::Address, signers::local::PrivateKeySigner}; //! # use tap_core::receipt::{Receipt, SignedReceipt}; //! # use tap_core::signed_message::EIP712SignedMessage; //! # let domain_separator = Eip712Domain::default(); -//! # let wallet = LocalWallet::new(&mut rand::thread_rng()); +//! # let wallet = PrivateKeySigner::random(); //! # let message = Receipt::new(Address::from([0x11u8; 20]), 100).unwrap(); //! //! let receipt = EIP712SignedMessage::new(&domain_separator, message, &wallet).unwrap(); diff --git a/tap_core/src/manager/tap_manager.rs b/tap_core/src/manager/tap_manager.rs index e970922a..ffa69f53 100644 --- a/tap_core/src/manager/tap_manager.rs +++ b/tap_core/src/manager/tap_manager.rs @@ -1,7 +1,7 @@ // Copyright 2023-, Semiotic AI, Inc. // SPDX-License-Identifier: Apache-2.0 -use alloy_sol_types::Eip712Domain; +use alloy::dyn_abi::Eip712Domain; use super::adapters::{EscrowHandler, RAVRead, RAVStore, ReceiptDelete, ReceiptRead, ReceiptStore}; use crate::{ diff --git a/tap_core/src/rav.rs b/tap_core/src/rav.rs index 49847653..ad3149c4 100644 --- a/tap_core/src/rav.rs +++ b/tap_core/src/rav.rs @@ -41,8 +41,8 @@ mod request; use std::cmp; -use alloy_primitives::Address; -use alloy_sol_types::sol; +use alloy::primitives::Address; +use alloy::sol; use serde::{Deserialize, Serialize}; use crate::Error; diff --git a/tap_core/src/receipt/checks.rs b/tap_core/src/receipt/checks.rs index e1fe5c63..d61b4d9c 100644 --- a/tap_core/src/receipt/checks.rs +++ b/tap_core/src/receipt/checks.rs @@ -29,6 +29,8 @@ //! let my_check: ReceiptCheck = Arc::new(MyCheck); //! ``` +use crate::signed_message::{SignatureBytes, SignatureBytesExt}; + use super::{ state::{Checking, Failed}, ReceiptError, ReceiptWithState, @@ -168,11 +170,14 @@ impl CheckBatch for UniqueCheck { Vec>, Vec>, ) { - let mut signatures: HashSet = HashSet::new(); + let mut signatures: HashSet = HashSet::new(); let (mut checking, mut failed) = (vec![], vec![]); for received_receipt in receipts.into_iter() { - let signature = received_receipt.signed_receipt.signature; + let signature = received_receipt + .signed_receipt + .signature + .get_signature_bytes(); if signatures.insert(signature) { checking.push(received_receipt); } else { @@ -189,12 +194,10 @@ mod tests { use std::time::Duration; use std::time::SystemTime; - use alloy_primitives::Address; - use alloy_sol_types::eip712_domain; - use alloy_sol_types::Eip712Domain; - - use ethers::signers::coins_bip39::English; - use ethers::signers::{LocalWallet, MnemonicBuilder}; + use alloy::dyn_abi::Eip712Domain; + use alloy::primitives::Address; + use alloy::signers::local::PrivateKeySigner; + use alloy::sol_types::eip712_domain; use crate::receipt::Receipt; use crate::signed_message::EIP712SignedMessage; @@ -202,13 +205,7 @@ mod tests { use super::*; fn create_signed_receipt_with_custom_value(value: u128) -> ReceiptWithState { - let index: u32 = 0; - let wallet: LocalWallet = MnemonicBuilder::::default() - .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") - .index(index) - .unwrap() - .build() - .unwrap(); + let wallet: PrivateKeySigner = PrivateKeySigner::random(); let eip712_domain_separator: Eip712Domain = eip712_domain! { name: "TAP", version: "1", diff --git a/tap_core/src/receipt/error.rs b/tap_core/src/receipt/error.rs index a4b11fe7..d002c64d 100644 --- a/tap_core/src/receipt/error.rs +++ b/tap_core/src/receipt/error.rs @@ -1,7 +1,7 @@ // Copyright 2023-, Semiotic AI, Inc. // SPDX-License-Identifier: Apache-2.0 -use alloy_primitives::Address; +use alloy::primitives::Address; use serde::{Deserialize, Serialize}; /// Error type for receipts diff --git a/tap_core/src/receipt/receipt_sol.rs b/tap_core/src/receipt/receipt_sol.rs index 630d337b..c7670eba 100644 --- a/tap_core/src/receipt/receipt_sol.rs +++ b/tap_core/src/receipt/receipt_sol.rs @@ -8,8 +8,7 @@ //! The payment receiver would verify the received receipt and store it to be //! accumulated with other received receipts in the future. -use alloy_primitives::Address; -use alloy_sol_types::sol; +use alloy::{primitives::Address, sol}; use rand::{thread_rng, Rng}; use serde::{Deserialize, Serialize}; diff --git a/tap_core/src/receipt/received_receipt.rs b/tap_core/src/receipt/received_receipt.rs index dc32ef1c..82f439ad 100644 --- a/tap_core/src/receipt/received_receipt.rs +++ b/tap_core/src/receipt/received_receipt.rs @@ -13,7 +13,7 @@ //! This module is useful for managing and tracking the state of received receipts, as well as //! their progress through various checks and stages of inclusion in RAV requests and received RAVs. -use alloy_sol_types::Eip712Domain; +use alloy::dyn_abi::Eip712Domain; use super::{Receipt, ReceiptError, ReceiptResult, SignedReceipt}; use crate::receipt::state::{AwaitingReserve, Checking, Failed, ReceiptState, Reserved}; diff --git a/tap_core/src/signed_message.rs b/tap_core/src/signed_message.rs index 53edc3c5..05094bf7 100644 --- a/tap_core/src/signed_message.rs +++ b/tap_core/src/signed_message.rs @@ -8,19 +8,14 @@ //! //! # Example //! ```rust -//! # use alloy_sol_types::Eip712Domain; +//! # use alloy::{dyn_abi::Eip712Domain, primitives::Address, signers::local::PrivateKeySigner}; //! # let domain_separator = Eip712Domain::default(); -//! # use ethers::{ -//! # signers::LocalWallet, -//! # signers::Signer -//! # }; -//! # use alloy_primitives::Address; //! use tap_core::{ //! signed_message::EIP712SignedMessage, //! receipt::Receipt //! }; -//! # let wallet = LocalWallet::new(&mut rand::thread_rng()); -//! # let wallet_address = Address::from_slice(wallet.address().as_bytes()); +//! # let wallet = PrivateKeySigner::random(); +//! # let wallet_address = wallet.address(); //! # let message = Receipt::new(Address::from([0x11u8; 20]), 100).unwrap(); //! //! let signed_message = EIP712SignedMessage::new(&domain_separator, message, &wallet).unwrap(); @@ -30,9 +25,12 @@ //! ``` //! -use alloy_primitives::Address; -use alloy_sol_types::{Eip712Domain, SolStruct}; -use ethers::{signers::LocalWallet, types::Signature}; +use alloy::{ + dyn_abi::Eip712Domain, + primitives::Address, + signers::{local::PrivateKeySigner, Signature, SignerSync}, + sol_types::SolStruct, +}; use serde::{Deserialize, Serialize}; use crate::Result; @@ -46,6 +44,19 @@ pub struct EIP712SignedMessage { pub signature: Signature, } +#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct SignatureBytes([u8; 65]); + +pub trait SignatureBytesExt { + fn get_signature_bytes(&self) -> SignatureBytes; +} + +impl SignatureBytesExt for Signature { + fn get_signature_bytes(&self) -> SignatureBytes { + SignatureBytes(self.as_bytes()) + } +} + /// Unique identifier for a message /// /// This is equal to the hash of the contents of a message, excluding the signature. @@ -62,21 +73,22 @@ impl EIP712SignedMessage { pub fn new( domain_separator: &Eip712Domain, message: M, - signing_wallet: &LocalWallet, + signing_wallet: &PrivateKeySigner, ) -> Result { - let recovery_message_hash: [u8; 32] = message.eip712_signing_hash(domain_separator).into(); + let recovery_message_hash = message.eip712_signing_hash(domain_separator); - let signature = signing_wallet.sign_hash(recovery_message_hash.into())?; + let signature = signing_wallet.sign_hash_sync(&recovery_message_hash)?; Ok(Self { message, signature }) } /// Recovers and returns the signer of the message from the signature. pub fn recover_signer(&self, domain_separator: &Eip712Domain) -> Result
{ - let recovery_message_hash: [u8; 32] = - self.message.eip712_signing_hash(domain_separator).into(); - let recovered_address: [u8; 20] = self.signature.recover(recovery_message_hash)?.into(); - Ok(recovered_address.into()) + let recovery_message_hash = self.message.eip712_signing_hash(domain_separator); + let recovered_address = self + .signature + .recover_address_from_prehash(&recovery_message_hash)?; + Ok(recovered_address) } /// Checks that receipts signature is valid for given verifying key, returns `Ok` if it is valid. @@ -87,13 +99,15 @@ impl EIP712SignedMessage { /// signature is not equal to `expected_address` /// pub fn verify(&self, domain_separator: &Eip712Domain, expected_address: Address) -> Result<()> { - let recovery_message_hash: [u8; 32] = - self.message.eip712_signing_hash(domain_separator).into(); - let expected_address: [u8; 20] = expected_address.into(); - - self.signature - .verify(recovery_message_hash, expected_address)?; - Ok(()) + let recovered_address = self.recover_signer(domain_separator)?; + if recovered_address != expected_address { + Err(crate::Error::VerificationFailed { + expected: expected_address, + received: recovered_address, + }) + } else { + Ok(()) + } } /// Use this a simple key for testing diff --git a/tap_core/tests/escrow_test.rs b/tap_core/tests/escrow_test.rs index 782150a2..5bd0853b 100644 --- a/tap_core/tests/escrow_test.rs +++ b/tap_core/tests/escrow_test.rs @@ -6,7 +6,7 @@ use std::{ sync::{Arc, RwLock}, }; -use ethers::signers::{coins_bip39::English, LocalWallet, MnemonicBuilder, Signer}; +use alloy::signers::local::PrivateKeySigner; use rstest::*; use tap_core::{ @@ -32,19 +32,11 @@ fn context() -> InMemoryContext { #[rstest] #[tokio::test] async fn escrow_handler_test(mut context: InMemoryContext) { - let wallet: LocalWallet = MnemonicBuilder::::default() - .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") - .build() - .unwrap(); - let sender_id: [u8; 20] = wallet.address().into(); - let sender_id = sender_id.into(); + let wallet = PrivateKeySigner::random(); + let sender_id = wallet.address(); - let invalid_wallet: LocalWallet = MnemonicBuilder::::default() - .phrase("wrong century settle satisfy market forest title connect ten push alley depend") - .build() - .unwrap(); - let invalid_sender_id: [u8; 20] = invalid_wallet.address().into(); - let invalid_sender_id = invalid_sender_id.into(); + let invalid_wallet = PrivateKeySigner::random(); + let invalid_sender_id = invalid_wallet.address(); let initial_value = 500u128; diff --git a/tap_core/tests/manager_test.rs b/tap_core/tests/manager_test.rs index 27a7dde5..2ff95df4 100644 --- a/tap_core/tests/manager_test.rs +++ b/tap_core/tests/manager_test.rs @@ -7,9 +7,7 @@ use std::{ time::{SystemTime, UNIX_EPOCH}, }; -use alloy_primitives::Address; -use alloy_sol_types::Eip712Domain; -use ethers::signers::{coins_bip39::English, LocalWallet, MnemonicBuilder, Signer}; +use alloy::{dyn_abi::Eip712Domain, primitives::Address, signers::local::PrivateKeySigner}; use rstest::*; fn get_current_timestamp_u64_ns() -> anyhow::Result { @@ -34,16 +32,8 @@ use tap_core::{ }; #[fixture] -fn keys() -> (LocalWallet, Address) { - let wallet: LocalWallet = MnemonicBuilder::::default() - .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") - .build() - .unwrap(); - // Alloy library does not have feature parity with ethers library (yet) This workaround is needed to get the address - // to convert to an alloy Address. This will not be needed when the alloy library has wallet support. - let address: [u8; 20] = wallet.address().into(); - - (wallet, address.into()) +fn signer() -> PrivateKeySigner { + PrivateKeySigner::random() } #[fixture] @@ -57,13 +47,17 @@ fn allocation_ids() -> Vec
{ } #[fixture] -fn sender_ids() -> Vec
{ - vec![ - Address::from_str("0xfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb").unwrap(), - Address::from_str("0xfafafafafafafafafafafafafafafafafafafafa").unwrap(), - Address::from_str("0xadadadadadadadadadadadadadadadadadadadad").unwrap(), - keys().1, - ] +fn sender_ids(signer: PrivateKeySigner) -> (PrivateKeySigner, Vec
) { + let address = signer.address(); + ( + signer, + vec![ + Address::from_str("0xfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb").unwrap(), + Address::from_str("0xfafafafafafafafafafafafafafafafafafafafa").unwrap(), + Address::from_str("0xadadadadadadadadadadadadadadadadadadadad").unwrap(), + address, + ], + ) } #[fixture] @@ -76,15 +70,16 @@ struct ContextFixture { escrow_storage: EscrowStorage, query_appraisals: QueryAppraisals, checks: CheckList, + signer: PrivateKeySigner, } #[fixture] fn context( domain_separator: Eip712Domain, allocation_ids: Vec
, - sender_ids: Vec
, - keys: (LocalWallet, Address), + sender_ids: (PrivateKeySigner, Vec
), ) -> ContextFixture { + let (signer, sender_ids) = sender_ids; let escrow_storage = Arc::new(RwLock::new(HashMap::new())); let rav_storage = Arc::new(RwLock::new(None)); let query_appraisals = Arc::new(RwLock::new(HashMap::new())); @@ -96,7 +91,7 @@ fn context( escrow_storage.clone(), timestamp_check.clone(), ) - .with_sender_address(keys.1); + .with_sender_address(signer.address()); let mut checks = get_full_list_of_checks( domain_separator, @@ -108,6 +103,7 @@ fn context( let checks = CheckList::new(checks); ContextFixture { + signer, context, escrow_storage, query_appraisals, @@ -118,7 +114,6 @@ fn context( #[rstest] #[tokio::test] async fn manager_verify_and_store_varying_initial_checks( - keys: (LocalWallet, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, context: ContextFixture, @@ -128,6 +123,7 @@ async fn manager_verify_and_store_varying_initial_checks( checks, query_appraisals, escrow_storage, + signer, .. } = context; let manager = Manager::new(domain_separator.clone(), context, checks); @@ -136,12 +132,15 @@ async fn manager_verify_and_store_varying_initial_checks( let signed_receipt = EIP712SignedMessage::new( &domain_separator, Receipt::new(allocation_ids[0], value).unwrap(), - &keys.0, + &signer, ) .unwrap(); let query_id = signed_receipt.unique_hash(); query_appraisals.write().unwrap().insert(query_id, value); - escrow_storage.write().unwrap().insert(keys.1, 999999); + escrow_storage + .write() + .unwrap() + .insert(signer.address(), 999999); assert!(manager .verify_and_store_receipt(signed_receipt) @@ -152,7 +151,6 @@ async fn manager_verify_and_store_varying_initial_checks( #[rstest] #[tokio::test] async fn manager_create_rav_request_all_valid_receipts( - keys: (LocalWallet, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, context: ContextFixture, @@ -162,10 +160,14 @@ async fn manager_create_rav_request_all_valid_receipts( checks, query_appraisals, escrow_storage, + signer, .. } = context; let manager = Manager::new(domain_separator.clone(), context, checks); - escrow_storage.write().unwrap().insert(keys.1, 999999); + escrow_storage + .write() + .unwrap() + .insert(signer.address(), 999999); let mut stored_signed_receipts = Vec::new(); for _ in 0..10 { @@ -173,7 +175,7 @@ async fn manager_create_rav_request_all_valid_receipts( let signed_receipt = EIP712SignedMessage::new( &domain_separator, Receipt::new(allocation_ids[0], value).unwrap(), - &keys.0, + &signer, ) .unwrap(); let query_id = signed_receipt.unique_hash(); @@ -197,7 +199,7 @@ async fn manager_create_rav_request_all_valid_receipts( assert_eq!(rav_request.invalid_receipts.len(), 0); let signed_rav = - EIP712SignedMessage::new(&domain_separator, rav_request.expected_rav.clone(), &keys.0) + EIP712SignedMessage::new(&domain_separator, rav_request.expected_rav.clone(), &signer) .unwrap(); assert!(manager .verify_and_store_rav(rav_request.expected_rav, signed_rav) @@ -207,13 +209,12 @@ async fn manager_create_rav_request_all_valid_receipts( #[rstest] #[tokio::test] -async fn deny_rav_due_to_wrong_value( - keys: (LocalWallet, Address), - domain_separator: Eip712Domain, - context: ContextFixture, -) { +async fn deny_rav_due_to_wrong_value(domain_separator: Eip712Domain, context: ContextFixture) { let ContextFixture { - context, checks, .. + context, + checks, + signer, + .. } = context; let manager = Manager::new(domain_separator.clone(), context, checks); @@ -230,7 +231,7 @@ async fn deny_rav_due_to_wrong_value( }; let signed_rav_with_wrong_aggregate = - EIP712SignedMessage::new(&domain_separator, rav_wrong_value, &keys.0).unwrap(); + EIP712SignedMessage::new(&domain_separator, rav_wrong_value, &signer).unwrap(); assert!(manager .verify_and_store_rav(rav, signed_rav_with_wrong_aggregate) @@ -241,7 +242,6 @@ async fn deny_rav_due_to_wrong_value( #[rstest] #[tokio::test] async fn manager_create_multiple_rav_requests_all_valid_receipts( - keys: (LocalWallet, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, context: ContextFixture, @@ -251,12 +251,16 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts( checks, query_appraisals, escrow_storage, + signer, .. } = context; let manager = Manager::new(domain_separator.clone(), context, checks); - escrow_storage.write().unwrap().insert(keys.1, 999999); + escrow_storage + .write() + .unwrap() + .insert(signer.address(), 999999); let mut stored_signed_receipts = Vec::new(); let mut expected_accumulated_value = 0; @@ -265,7 +269,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts( let signed_receipt = EIP712SignedMessage::new( &domain_separator, Receipt::new(allocation_ids[0], value).unwrap(), - &keys.0, + &signer, ) .unwrap(); let query_id = signed_receipt.unique_hash(); @@ -297,7 +301,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts( assert!(rav_request.previous_rav.is_none()); let signed_rav = - EIP712SignedMessage::new(&domain_separator, rav_request.expected_rav.clone(), &keys.0) + EIP712SignedMessage::new(&domain_separator, rav_request.expected_rav.clone(), &signer) .unwrap(); assert!(manager .verify_and_store_rav(rav_request.expected_rav, signed_rav) @@ -310,7 +314,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts( let signed_receipt = EIP712SignedMessage::new( &domain_separator, Receipt::new(allocation_ids[0], value).unwrap(), - &keys.0, + &signer, ) .unwrap(); @@ -343,7 +347,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts( assert!(rav_request.previous_rav.is_some()); let signed_rav = - EIP712SignedMessage::new(&domain_separator, rav_request.expected_rav.clone(), &keys.0) + EIP712SignedMessage::new(&domain_separator, rav_request.expected_rav.clone(), &signer) .unwrap(); assert!(manager .verify_and_store_rav(rav_request.expected_rav, signed_rav) @@ -354,7 +358,6 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts( #[rstest] #[tokio::test] async fn manager_create_multiple_rav_requests_all_valid_receipts_consecutive_timestamps( - keys: (LocalWallet, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, #[values(true, false)] remove_old_receipts: bool, @@ -365,13 +368,17 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts_consecutive_tim checks, query_appraisals, escrow_storage, + signer, .. } = context; let starting_min_timestamp = get_current_timestamp_u64_ns().unwrap() - 500000000; let manager = Manager::new(domain_separator.clone(), context.clone(), checks); - escrow_storage.write().unwrap().insert(keys.1, 999999); + escrow_storage + .write() + .unwrap() + .insert(signer.address(), 999999); let mut stored_signed_receipts = Vec::new(); let mut expected_accumulated_value = 0; @@ -379,7 +386,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts_consecutive_tim let value = 20u128; let mut receipt = Receipt::new(allocation_ids[0], value).unwrap(); receipt.timestamp_ns = starting_min_timestamp + query_id + 1; - let signed_receipt = EIP712SignedMessage::new(&domain_separator, receipt, &keys.0).unwrap(); + let signed_receipt = EIP712SignedMessage::new(&domain_separator, receipt, &signer).unwrap(); let query_id = signed_receipt.unique_hash(); stored_signed_receipts.push(signed_receipt.clone()); @@ -419,7 +426,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts_consecutive_tim let signed_rav_1 = EIP712SignedMessage::new( &domain_separator, rav_request_1.expected_rav.clone(), - &keys.0, + &signer, ) .unwrap(); assert!(manager @@ -432,7 +439,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts_consecutive_tim let value = 20u128; let mut receipt = Receipt::new(allocation_ids[0], value).unwrap(); receipt.timestamp_ns = starting_min_timestamp + query_id + 1; - let signed_receipt = EIP712SignedMessage::new(&domain_separator, receipt, &keys.0).unwrap(); + let signed_receipt = EIP712SignedMessage::new(&domain_separator, receipt, &signer).unwrap(); let query_id = signed_receipt.unique_hash(); stored_signed_receipts.push(signed_receipt.clone()); query_appraisals.write().unwrap().insert(query_id, value); @@ -479,7 +486,7 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts_consecutive_tim let signed_rav_2 = EIP712SignedMessage::new( &domain_separator, rav_request_2.expected_rav.clone(), - &keys.0, + &signer, ) .unwrap(); assert!(manager @@ -491,7 +498,6 @@ async fn manager_create_multiple_rav_requests_all_valid_receipts_consecutive_tim #[rstest] #[tokio::test] async fn manager_create_rav_and_ignore_invalid_receipts( - keys: (LocalWallet, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, context: ContextFixture, @@ -500,12 +506,16 @@ async fn manager_create_rav_and_ignore_invalid_receipts( context, checks, escrow_storage, + signer, .. } = context; let manager = Manager::new(domain_separator.clone(), context.clone(), checks); - escrow_storage.write().unwrap().insert(keys.1, 999999); + escrow_storage + .write() + .unwrap() + .insert(signer.address(), 999999); let mut stored_signed_receipts = Vec::new(); //Forcing all receipts but one to be invalid by making all the same @@ -516,7 +526,7 @@ async fn manager_create_rav_and_ignore_invalid_receipts( nonce: 1, value: 20u128, }; - let signed_receipt = EIP712SignedMessage::new(&domain_separator, receipt, &keys.0).unwrap(); + let signed_receipt = EIP712SignedMessage::new(&domain_separator, receipt, &signer).unwrap(); stored_signed_receipts.push(signed_receipt.clone()); manager .verify_and_store_receipt(signed_receipt) diff --git a/tap_core/tests/rav_test.rs b/tap_core/tests/rav_test.rs index 4b440094..4be8d054 100644 --- a/tap_core/tests/rav_test.rs +++ b/tap_core/tests/rav_test.rs @@ -5,10 +5,9 @@ use std::collections::HashMap; use std::sync::RwLock; use std::{str::FromStr, sync::Arc}; -use alloy_primitives::Address; -use alloy_sol_types::Eip712Domain; -use ethers::signers::coins_bip39::English; -use ethers::signers::{LocalWallet, MnemonicBuilder}; +use alloy::dyn_abi::Eip712Domain; +use alloy::primitives::Address; +use alloy::signers::local::PrivateKeySigner; use rstest::*; use tap_core::manager::context::memory::InMemoryContext; @@ -43,15 +42,9 @@ fn context() -> InMemoryContext { #[rstest] #[tokio::test] async fn rav_storage_adapter_test(domain_separator: Eip712Domain, context: InMemoryContext) { - let wallet: LocalWallet = MnemonicBuilder::::default() - .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") - .build() - .unwrap(); - - let allocation_id: [u8; 20] = Address::from_str("0xabababababababababababababababababababab") - .unwrap() - .into(); - let allocation_id = allocation_id.into(); + let wallet = PrivateKeySigner::random(); + + let allocation_id = Address::from_str("0xabababababababababababababababababababab").unwrap(); // Create receipts let mut receipts = Vec::new(); diff --git a/tap_core/tests/receipt_test.rs b/tap_core/tests/receipt_test.rs index 04180496..a507bc7e 100644 --- a/tap_core/tests/receipt_test.rs +++ b/tap_core/tests/receipt_test.rs @@ -1,3 +1,6 @@ +use alloy::dyn_abi::Eip712Domain; +use alloy::primitives::Address; +use alloy::signers::local::PrivateKeySigner; // Copyright 2023-, Semiotic AI, Inc. // SPDX-License-Identifier: Apache-2.0 use rand::seq::SliceRandom; @@ -8,9 +11,6 @@ use std::sync::{Arc, RwLock}; use tap_core::manager::context::memory::InMemoryContext; use tap_core::receipt::{state::Checking, ReceiptWithState}; -use alloy_primitives::Address; -use alloy_sol_types::Eip712Domain; -use ethers::signers::{coins_bip39::English, LocalWallet, MnemonicBuilder}; use rstest::*; use tap_core::receipt::checks::StatefulTimestampCheck; use tap_core::{ @@ -41,10 +41,7 @@ fn context() -> InMemoryContext { #[rstest] #[tokio::test] async fn receipt_adapter_test(domain_separator: Eip712Domain, mut context: InMemoryContext) { - let wallet: LocalWallet = MnemonicBuilder::::default() - .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") - .build() - .unwrap(); + let wallet = PrivateKeySigner::random(); let allocation_id = Address::from_str("0xabababababababababababababababababababab").unwrap(); @@ -83,10 +80,7 @@ async fn receipt_adapter_test(domain_separator: Eip712Domain, mut context: InMem #[rstest] #[tokio::test] async fn multi_receipt_adapter_test(domain_separator: Eip712Domain, mut context: InMemoryContext) { - let wallet: LocalWallet = MnemonicBuilder::::default() - .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") - .build() - .unwrap(); + let wallet = PrivateKeySigner::random(); let allocation_id = Address::from_str("0xabababababababababababababababababababab").unwrap(); @@ -163,10 +157,7 @@ fn safe_truncate_receipts_test( #[case] limit: u64, #[case] expected: Vec, ) { - let wallet: LocalWallet = MnemonicBuilder::::default() - .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") - .build() - .unwrap(); + let wallet = PrivateKeySigner::random(); // Vec of (id, receipt) let mut receipts_orig: Vec> = Vec::new(); diff --git a/tap_core/tests/received_receipt_test.rs b/tap_core/tests/received_receipt_test.rs index 8e64b262..a3de5bd9 100644 --- a/tap_core/tests/received_receipt_test.rs +++ b/tap_core/tests/received_receipt_test.rs @@ -7,9 +7,7 @@ use std::{ sync::{Arc, RwLock}, }; -use alloy_primitives::Address; -use alloy_sol_types::Eip712Domain; -use ethers::signers::{coins_bip39::English, LocalWallet, MnemonicBuilder, Signer}; +use alloy::{dyn_abi::Eip712Domain, primitives::Address, signers::local::PrivateKeySigner}; use rstest::*; use tap_core::{ manager::context::memory::{ @@ -24,16 +22,8 @@ use tap_core::{ }; #[fixture] -fn keys() -> (LocalWallet, Address) { - let wallet: LocalWallet = MnemonicBuilder::::default() - .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") - .build() - .unwrap(); - // Alloy library does not have feature parity with ethers library (yet) This workaround is needed to get the address - // to convert to an alloy Address. This will not be needed when the alloy library has wallet support. - let address: [u8; 20] = wallet.address().into(); - - (wallet, address.into()) +fn signer() -> PrivateKeySigner { + PrivateKeySigner::random() } #[fixture] @@ -47,13 +37,17 @@ fn allocation_ids() -> Vec
{ } #[fixture] -fn sender_ids() -> Vec
{ - vec![ - Address::from_str("0xfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb").unwrap(), - Address::from_str("0xfafafafafafafafafafafafafafafafafafafafa").unwrap(), - Address::from_str("0xadadadadadadadadadadadadadadadadadadadad").unwrap(), - keys().1, - ] +fn sender_ids(signer: PrivateKeySigner) -> (PrivateKeySigner, Vec
) { + let address = signer.address(); + ( + signer, + vec![ + Address::from_str("0xfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb").unwrap(), + Address::from_str("0xfafafafafafafafafafafafafafafafafafafafa").unwrap(), + Address::from_str("0xadadadadadadadadadadadadadadadadadadadad").unwrap(), + address, + ], + ) } #[fixture] @@ -66,15 +60,16 @@ struct ContextFixture { escrow_storage: EscrowStorage, query_appraisals: QueryAppraisals, checks: Vec, + signer: PrivateKeySigner, } #[fixture] fn context( domain_separator: Eip712Domain, allocation_ids: Vec
, - sender_ids: Vec
, - keys: (LocalWallet, Address), + sender_ids: (PrivateKeySigner, Vec
), ) -> ContextFixture { + let (signer, sender_ids) = sender_ids; let escrow_storage = Arc::new(RwLock::new(HashMap::new())); let rav_storage = Arc::new(RwLock::new(None)); let receipt_storage = Arc::new(RwLock::new(HashMap::new())); @@ -87,7 +82,7 @@ fn context( escrow_storage.clone(), timestamp_check.clone(), ) - .with_sender_address(keys.1); + .with_sender_address(signer.address()); let mut checks = get_full_list_of_checks( domain_separator, sender_ids.iter().cloned().collect(), @@ -97,6 +92,7 @@ fn context( checks.push(timestamp_check); ContextFixture { + signer, context, escrow_storage, query_appraisals, @@ -107,7 +103,6 @@ fn context( #[rstest] #[tokio::test] async fn partial_then_full_check_valid_receipt( - keys: (LocalWallet, Address), domain_separator: Eip712Domain, allocation_ids: Vec
, context: ContextFixture, @@ -116,6 +111,7 @@ async fn partial_then_full_check_valid_receipt( checks, escrow_storage, query_appraisals, + signer, .. } = context; @@ -123,7 +119,7 @@ async fn partial_then_full_check_valid_receipt( let signed_receipt = EIP712SignedMessage::new( &domain_separator, Receipt::new(allocation_ids[0], query_value).unwrap(), - &keys.0, + &signer, ) .unwrap(); @@ -133,7 +129,7 @@ async fn partial_then_full_check_valid_receipt( escrow_storage .write() .unwrap() - .insert(keys.1, query_value + 500); + .insert(signer.address(), query_value + 500); // appraise query query_appraisals .write() @@ -149,7 +145,6 @@ async fn partial_then_full_check_valid_receipt( #[rstest] #[tokio::test] async fn partial_then_finalize_valid_receipt( - keys: (LocalWallet, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, context: ContextFixture, @@ -159,6 +154,7 @@ async fn partial_then_finalize_valid_receipt( context, escrow_storage, query_appraisals, + signer, .. } = context; @@ -166,7 +162,7 @@ async fn partial_then_finalize_valid_receipt( let signed_receipt = EIP712SignedMessage::new( &domain_separator, Receipt::new(allocation_ids[0], query_value).unwrap(), - &keys.0, + &signer, ) .unwrap(); let query_id = signed_receipt.unique_hash(); @@ -175,7 +171,7 @@ async fn partial_then_finalize_valid_receipt( escrow_storage .write() .unwrap() - .insert(keys.1, query_value + 500); + .insert(signer.address(), query_value + 500); // appraise query query_appraisals .write() @@ -197,7 +193,6 @@ async fn partial_then_finalize_valid_receipt( #[rstest] #[tokio::test] async fn standard_lifetime_valid_receipt( - keys: (LocalWallet, Address), allocation_ids: Vec
, domain_separator: Eip712Domain, context: ContextFixture, @@ -207,6 +202,7 @@ async fn standard_lifetime_valid_receipt( context, escrow_storage, query_appraisals, + signer, .. } = context; @@ -214,7 +210,7 @@ async fn standard_lifetime_valid_receipt( let signed_receipt = EIP712SignedMessage::new( &domain_separator, Receipt::new(allocation_ids[0], query_value).unwrap(), - &keys.0, + &signer, ) .unwrap(); @@ -224,7 +220,7 @@ async fn standard_lifetime_valid_receipt( escrow_storage .write() .unwrap() - .insert(keys.1, query_value + 500); + .insert(signer.address(), query_value + 500); // appraise query query_appraisals .write() diff --git a/tap_integration_tests/Cargo.toml b/tap_integration_tests/Cargo.toml index 6e909311..16674883 100644 --- a/tap_integration_tests/Cargo.toml +++ b/tap_integration_tests/Cargo.toml @@ -10,9 +10,8 @@ publish = false [dependencies] tap_aggregator = { version = "0.3.1", path = "../tap_aggregator" } -tap_core = { version = "1.0.0", path = "../tap_core", features = ["in_memory"]} +tap_core = { version = "1.0.0", path = "../tap_core", features = ["in_memory"] } jsonrpsee = { version = "0.18.0", features = ["http-client", "server"] } -ethers = "2.0.0" clap = { version = "4.2.4", features = ["derive", "env"] } rstest = "0.17.0" rand = "0.8.5" @@ -20,8 +19,7 @@ futures = "0.3.28" anyhow = "1.0.71" tokio = "1.28.2" prometheus = "0.13.3" -alloy-sol-types = { version = "0.7.0", features = ["eip712-serde"] } -alloy-primitives = { version = "0.7.0", features = ["serde"] } +alloy = { version = "0.2.0", features = ["full", "signer-mnemonic"] } [[test]] name = "integration_tests" diff --git a/tap_integration_tests/tests/indexer_mock.rs b/tap_integration_tests/tests/indexer_mock.rs index 5857ac6f..a383f80f 100644 --- a/tap_integration_tests/tests/indexer_mock.rs +++ b/tap_integration_tests/tests/indexer_mock.rs @@ -5,7 +5,7 @@ use std::sync::{ Arc, }; -use alloy_sol_types::Eip712Domain; +use alloy::dyn_abi::Eip712Domain; use anyhow::{Error, Result}; use jsonrpsee::{ core::{async_trait, client::ClientT}, diff --git a/tap_integration_tests/tests/showcase.rs b/tap_integration_tests/tests/showcase.rs index 21f6954b..444e5d5d 100644 --- a/tap_integration_tests/tests/showcase.rs +++ b/tap_integration_tests/tests/showcase.rs @@ -12,10 +12,12 @@ use std::{ sync::{Arc, RwLock}, }; -use alloy_primitives::Address; -use alloy_sol_types::Eip712Domain; +use alloy::{ + dyn_abi::Eip712Domain, + primitives::Address, + signers::local::{coins_bip39::English, MnemonicBuilder, PrivateKeySigner}, +}; use anyhow::{Error, Result}; -use ethers::signers::{coins_bip39::English, LocalWallet, MnemonicBuilder, Signer}; use jsonrpsee::{ core::client::ClientT, http_client::HttpClientBuilder, rpc_params, server::ServerHandle, }; @@ -84,30 +86,20 @@ fn receipt_threshold_2(num_queries: u64, num_batches: u64) -> u64 { // The private key (LocalWallet) and public key (Address) of a Sender #[fixture] -fn keys_sender() -> (LocalWallet, Address) { - let wallet: LocalWallet = MnemonicBuilder::::default() +fn keys_sender() -> PrivateKeySigner { + MnemonicBuilder::::default() .phrase("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") .build() - .unwrap(); - // Alloy library does not have feature parity with ethers library (yet) This workaround is needed to get the address - // to convert to an alloy Address. This will not be needed when the alloy library has wallet support. - let address: [u8; 20] = wallet.address().into(); - - (wallet, address.into()) + .unwrap() } // The private key (LocalWallet) and public key (Address) of a Sender. This key is used to test when the Sender's key differs from the Indexer's expectation. #[fixture] -fn wrong_keys_sender() -> (LocalWallet, Address) { - let wallet: LocalWallet = MnemonicBuilder::::default() +fn wrong_keys_sender() -> PrivateKeySigner { + MnemonicBuilder::::default() .phrase("devote force reopen galaxy humor virtual hobby chief grit nothing bag pulse") .build() - .unwrap(); - // Alloy library does not have feature parity with ethers library (yet) This workaround is needed to get the address - // to convert to an alloy Address. This will not be needed when the alloy library has wallet support. - let address: [u8; 20] = wallet.address().into(); - - (wallet, address.into()) + .unwrap() } // Allocation IDs are used to ensure receipts cannot be double-counted @@ -125,7 +117,7 @@ fn sender_ids() -> Vec
{ Address::from_str("0xfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb").unwrap(), Address::from_str("0xfafafafafafafafafafafafafafafafafafafafa").unwrap(), Address::from_str("0xadadadadadadadadadadadadadadadadadadadad").unwrap(), - keys_sender().1, + keys_sender().address(), ] } @@ -215,18 +207,17 @@ fn indexer_2_context(context: ContextFixture) -> ContextFixture { // Messages are formatted according to TAP spec and signed according to EIP-712. #[fixture] fn requests_1( - keys_sender: (LocalWallet, Address), + keys_sender: PrivateKeySigner, query_price: &[u128], num_batches: u64, allocation_ids: Vec
, domain_separator: Eip712Domain, ) -> Vec> { - let (sender_key, _) = keys_sender; // Create your Receipt here generate_requests( query_price, num_batches, - &sender_key, + &keys_sender, allocation_ids[0], &domain_separator, ) @@ -234,18 +225,17 @@ fn requests_1( #[fixture] fn requests_2( - keys_sender: (LocalWallet, Address), + keys_sender: PrivateKeySigner, query_price: &[u128], num_batches: u64, allocation_ids: Vec
, domain_separator: Eip712Domain, ) -> Vec> { - let (sender_key, _) = keys_sender; // Create your Receipt here generate_requests( query_price, num_batches, - &sender_key, + &keys_sender, allocation_ids[1], &domain_separator, ) @@ -253,20 +243,18 @@ fn requests_2( #[fixture] fn repeated_timestamp_request( - keys_sender: (LocalWallet, Address), + keys_sender: PrivateKeySigner, query_price: &[u128], allocation_ids: Vec
, domain_separator: Eip712Domain, num_batches: u64, receipt_threshold_1: u64, ) -> Vec> { - let (sender_key, _) = keys_sender; - // Create signed receipts let mut requests = generate_requests( query_price, num_batches, - &sender_key, + &keys_sender, allocation_ids[0], &domain_separator, ); @@ -285,25 +273,24 @@ fn repeated_timestamp_request( // Sign the new receipt and insert it in the second batch requests[receipt_threshold_1 as usize] = - EIP712SignedMessage::new(&domain_separator, repeat_receipt, &sender_key).unwrap(); + EIP712SignedMessage::new(&domain_separator, repeat_receipt, &keys_sender).unwrap(); requests } #[fixture] fn repeated_timestamp_incremented_by_one_request( - keys_sender: (LocalWallet, Address), + keys_sender: PrivateKeySigner, query_price: &[u128], allocation_ids: Vec
, domain_separator: Eip712Domain, num_batches: u64, receipt_threshold_1: u64, ) -> Vec> { - let (sender_key, _) = keys_sender; // Create your Receipt here let mut requests = generate_requests( query_price, num_batches, - &sender_key, + &keys_sender, allocation_ids[0], &domain_separator, ); @@ -323,26 +310,25 @@ fn repeated_timestamp_incremented_by_one_request( // Sign the new receipt and insert it in the second batch requests[receipt_threshold_1 as usize] = - EIP712SignedMessage::new(&domain_separator, repeat_receipt, &sender_key).unwrap(); + EIP712SignedMessage::new(&domain_separator, repeat_receipt, &keys_sender).unwrap(); requests } #[fixture] fn wrong_requests( - wrong_keys_sender: (LocalWallet, Address), + wrong_keys_sender: PrivateKeySigner, query_price: &[u128], num_batches: u64, allocation_ids: Vec
, domain_separator: Eip712Domain, ) -> Vec> { - let (sender_key, _) = wrong_keys_sender; // Create your Receipt here // Create your Receipt here generate_requests( query_price, num_batches, - &sender_key, + &wrong_keys_sender, allocation_ids[0], &domain_separator, ) @@ -351,7 +337,7 @@ fn wrong_requests( // Helper fixtures to start servers for tests #[fixture] async fn single_indexer_test_server( - keys_sender: (LocalWallet, Address), + keys_sender: PrivateKeySigner, domain_separator: Eip712Domain, http_request_size_limit: u32, http_response_size_limit: u32, @@ -360,7 +346,7 @@ async fn single_indexer_test_server( available_escrow: u128, receipt_threshold_1: u64, ) -> Result<(ServerHandle, SocketAddr, ServerHandle, SocketAddr)> { - let sender_id = keys_sender.1; + let sender_id = keys_sender.address(); let (sender_aggregator_handle, sender_aggregator_addr) = start_sender_aggregator( keys_sender, domain_separator.clone(), @@ -390,7 +376,7 @@ async fn single_indexer_test_server( #[fixture] async fn two_indexers_test_servers( - keys_sender: (LocalWallet, Address), + keys_sender: PrivateKeySigner, domain_separator: Eip712Domain, http_request_size_limit: u32, http_response_size_limit: u32, @@ -407,7 +393,7 @@ async fn two_indexers_test_servers( ServerHandle, SocketAddr, )> { - let sender_id = keys_sender.1; + let sender_id = keys_sender.address(); let (sender_aggregator_handle, sender_aggregator_addr) = start_sender_aggregator( keys_sender, domain_separator.clone(), @@ -460,7 +446,7 @@ async fn two_indexers_test_servers( #[fixture] async fn single_indexer_wrong_sender_test_server( - wrong_keys_sender: (LocalWallet, Address), + wrong_keys_sender: PrivateKeySigner, domain_separator: Eip712Domain, http_request_size_limit: u32, http_response_size_limit: u32, @@ -469,7 +455,7 @@ async fn single_indexer_wrong_sender_test_server( available_escrow: u128, receipt_threshold_1: u64, ) -> Result<(ServerHandle, SocketAddr, ServerHandle, SocketAddr)> { - let sender_id = wrong_keys_sender.1; + let sender_id = wrong_keys_sender.address(); let (sender_aggregator_handle, sender_aggregator_addr) = start_sender_aggregator( wrong_keys_sender, domain_separator.clone(), @@ -707,7 +693,7 @@ async fn test_tap_manager_rav_timestamp_cuttoff( #[rstest] #[tokio::test] async fn test_tap_aggregator_rav_timestamp_cuttoff( - keys_sender: (LocalWallet, Address), + keys_sender: PrivateKeySigner, domain_separator: Eip712Domain, http_request_size_limit: u32, http_response_size_limit: u32, @@ -786,7 +772,7 @@ async fn test_tap_aggregator_rav_timestamp_cuttoff( fn generate_requests( query_price: &[u128], num_batches: u64, - sender_key: &LocalWallet, + sender_key: &PrivateKeySigner, allocation_id: Address, domain_separator: &Eip712Domain, ) -> Vec> { @@ -842,7 +828,7 @@ async fn start_indexer_server( // Start-up a Sender Aggregator. async fn start_sender_aggregator( - keys: (LocalWallet, Address), + keys: PrivateKeySigner, domain_separator: Eip712Domain, http_request_size_limit: u32, http_response_size_limit: u32, @@ -853,11 +839,11 @@ async fn start_sender_aggregator( listener.local_addr()?.port() }; - let accepted_addresses = HashSet::from([keys.1]); + let accepted_addresses = HashSet::from([keys.address()]); let (server_handle, socket_addr) = agg_server::run_server( http_port, - keys.0, + keys, accepted_addresses, domain_separator, http_request_size_limit,