From 596d16c1f5778068cdded63577031c798348cb75 Mon Sep 17 00:00:00 2001 From: Josh Wilson Date: Thu, 3 Oct 2024 15:22:43 +0900 Subject: [PATCH] feat(evmlib): Chunk->Data --- README.md | 2 +- autonomi/README.md | 10 +- evm_testnet/README.md | 2 +- evm_testnet/src/main.rs | 5 +- .../{ChunkPayments.json => DataPayments.json} | 0 .../error.rs | 0 .../{chunk_payments => data_payments}/mod.rs | 41 +++---- evmlib/src/contract/mod.rs | 2 +- evmlib/src/event.rs | 10 +- evmlib/src/lib.rs | 22 ++-- evmlib/src/testnet.rs | 20 ++-- evmlib/src/transaction.rs | 28 ++--- evmlib/src/utils.rs | 2 +- evmlib/src/wallet.rs | 24 ++-- evmlib/tests/chunk_payments.rs | 20 ++-- evmlib/tests/data_payments.rs | 111 ++++++++++++++++++ evmlib/tests/wallet.rs | 14 +-- sn_evm/CHANGELOG.md | 16 +-- sn_node/src/bin/safenode/subcommands.rs | 6 +- sn_node/src/put_validation.rs | 2 +- .../src/bin/cli/subcommands/evm_network.rs | 8 +- sn_node_manager/src/local.rs | 4 +- test_utils/src/evm.rs | 8 +- 23 files changed, 233 insertions(+), 124 deletions(-) rename evmlib/artifacts/{ChunkPayments.json => DataPayments.json} (100%) rename evmlib/src/contract/{chunk_payments => data_payments}/error.rs (100%) rename evmlib/src/contract/{chunk_payments => data_payments}/mod.rs (53%) create mode 100644 evmlib/tests/data_payments.rs diff --git a/README.md b/README.md index 52a485c16a..54f69bd62a 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ Take note of the console output for the next step (`RPC URL`, `Payment token add `--rewards-address` _is the address where you will receive your node earnings on._ ```bash -cargo run --bin=safenode-manager --features=local-discovery -- local run --build --clean --rewards-address evm-custom --rpc-url --payment-token-address --chunk-payments-address +cargo run --bin=safenode-manager --features=local-discovery -- local run --build --clean --rewards-address evm-custom --rpc-url --payment-token-address --data-payments-address ``` 4. Verify node status:
diff --git a/autonomi/README.md b/autonomi/README.md index 2603768aea..275f973331 100644 --- a/autonomi/README.md +++ b/autonomi/README.md @@ -31,15 +31,15 @@ Take note of the console output for the next step (`RPC URL`, `Payment token add 3. Run a local network with the `local-discovery` feature and pass the EVM params: ```sh -cargo run --bin=safenode-manager --features=local-discovery -- local run --build --clean --rewards-address evm-custom --rpc-url --payment-token-address --chunk-payments-address +cargo run --bin=safenode-manager --features=local-discovery -- local run --build --clean --rewards-address evm-custom --rpc-url --payment-token-address --data-payments-address ``` 4. Then run the tests with the `local` feature and pass the EVM params again: ```sh -$ RPC_URL= PAYMENT_TOKEN_ADDRESS= CHUNK_PAYMENTS_ADDRESS= cargo test --package=autonomi --features=local +$ RPC_URL= PAYMENT_TOKEN_ADDRESS= DATA_PAYMENTS_ADDRESS= cargo test --package=autonomi --features=local # Or with logs -$ RUST_LOG=autonomi RPC_URL= PAYMENT_TOKEN_ADDRESS= CHUNK_PAYMENTS_ADDRESS= cargo test --package=autonomi --features=local -- --nocapture +$ RUST_LOG=autonomi RPC_URL= PAYMENT_TOKEN_ADDRESS= DATA_PAYMENTS_ADDRESS= cargo test --package=autonomi --features=local -- --nocapture ``` ### Using a live testnet or mainnet @@ -70,13 +70,13 @@ initialise a wallet from with almost infinite gas and payment tokens. Example: ```rust let rpc_url = "http://localhost:54370/"; let payment_token_address = "0x5FbDB2315678afecb367f032d93F642f64180aa3"; -let chunk_payments_address = "0x8464135c8F25Da09e49BC8782676a84730C318bC"; +let data_payments_address = "0x8464135c8F25Da09e49BC8782676a84730C318bC"; let private_key = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; let network = Network::Custom(CustomNetwork::new( rpc_url, payment_token_address, -chunk_payments_address, +data_payments_address, )); let deployer_wallet = Wallet::new_from_private_key(network, private_key).unwrap(); diff --git a/evm_testnet/README.md b/evm_testnet/README.md index c6b2b20820..d18d58dfe8 100644 --- a/evm_testnet/README.md +++ b/evm_testnet/README.md @@ -20,7 +20,7 @@ Example output: ************************* RPC URL: http://localhost:60093/ Payment token address: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -Chunk payments address: 0x8464135c8F25Da09e49BC8782676a84730C318bC +Data payments address: 0x8464135c8F25Da09e49BC8782676a84730C318bC Deployer wallet private key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 Genesis wallet balance: (tokens: 20000000000000000000000000, gas: 9998998011366954730202) ``` diff --git a/evm_testnet/src/main.rs b/evm_testnet/src/main.rs index 8cef9ceb98..807bc0c40f 100644 --- a/evm_testnet/src/main.rs +++ b/evm_testnet/src/main.rs @@ -76,10 +76,7 @@ async fn print_testnet_details(testnet: &Testnet, genesis_wallet: Option
, N: Network> { - pub contract: ChunkPaymentsContractInstance, +pub struct DataPayments, N: Network> { + pub contract: DataPaymentsContractInstance, } -impl ChunkPayments +impl DataPayments where T: Transport + Clone, P: Provider, N: Network, { - /// Create a new ChunkPayments contract instance. + /// Create a new DataPayments contract instance. pub fn new(contract_address: Address, provider: P) -> Self { - let contract = ChunkPaymentsContract::new(contract_address, provider); - ChunkPayments { contract } + let contract = DataPaymentsContract::new(contract_address, provider); + DataPayments { contract } } - /// Deploys the ChunkPayments smart contract to the network of the provider. + /// Deploys the DataPayments smart contract to the network of the provider. /// ONLY DO THIS IF YOU KNOW WHAT YOU ARE DOING! pub async fn deploy(provider: P, payment_token_address: Address) -> Self { - let contract = ChunkPaymentsContract::deploy(provider, payment_token_address) + let contract = DataPaymentsContract::deploy(provider, payment_token_address) .await .expect("Could not deploy contract"); - ChunkPayments { contract } + DataPayments { contract } } pub fn set_provider(&mut self, provider: P) { let address = *self.contract.address(); - self.contract = ChunkPaymentsContract::new(address, provider); + self.contract = DataPaymentsContract::new(address, provider); } /// Pay for quotes. /// Input: (quote_id, reward_address, amount). pub async fn pay_for_quotes>( &self, - chunk_payments: I, + data_payments: I, ) -> Result { - let chunk_payments: Vec = chunk_payments + let data_payments: Vec = data_payments .into_iter() - .map(|(hash, addr, amount)| ChunkPaymentsContract::ChunkPayment { + .map(|(hash, addr, amount)| DataPaymentsContract::ChunkPayment { rewardAddress: addr, amount, quoteHash: hash, }) .collect(); - if chunk_payments.len() > MAX_TRANSFERS_PER_TRANSACTION { + if data_payments.len() > MAX_TRANSFERS_PER_TRANSACTION { return Err(Error::TransferLimitExceeded); } let tx_hash = self .contract - .submitChunkPayments(chunk_payments) + .submitChunkPayments(data_payments) .send() .await? .watch() diff --git a/evmlib/src/contract/mod.rs b/evmlib/src/contract/mod.rs index 5afb41f09b..1a4e070efd 100644 --- a/evmlib/src/contract/mod.rs +++ b/evmlib/src/contract/mod.rs @@ -1,2 +1,2 @@ -pub mod chunk_payments; +pub mod data_payments; pub mod network_token; diff --git a/evmlib/src/event.rs b/evmlib/src/event.rs index 9327eb98cd..023f0ee087 100644 --- a/evmlib/src/event.rs +++ b/evmlib/src/event.rs @@ -3,7 +3,7 @@ use alloy::primitives::{b256, FixedBytes}; use alloy::rpc::types::Log; // Should be updated when the smart contract changes! -pub(crate) const CHUNK_PAYMENT_EVENT_SIGNATURE: FixedBytes<32> = +pub(crate) const DATA_PAYMENT_EVENT_SIGNATURE: FixedBytes<32> = b256!("a6df5ca64d2adbcdd26949b97238efc4e97dc7e5d23012ea53f92a24f005f958"); // DevSkim: ignore DS173237 #[derive(thiserror::Error, Debug)] @@ -16,15 +16,15 @@ pub enum Error { EventSignatureDoesNotMatch, } -/// Struct for the ChunkPaymentEvent emitted by the ChunkPayments smart contract. +/// Struct for the DataPaymentEvent emitted by the DataPayments smart contract. #[derive(Debug)] -pub(crate) struct ChunkPaymentEvent { +pub(crate) struct DataPaymentEvent { pub reward_address: Address, pub amount: U256, pub quote_hash: Hash, } -impl TryFrom for ChunkPaymentEvent { +impl TryFrom for DataPaymentEvent { type Error = Error; fn try_from(log: Log) -> Result { @@ -36,7 +36,7 @@ impl TryFrom for ChunkPaymentEvent { let topic0 = log.topics().first().ok_or(Error::EventSignatureMissing)?; // Verify the event signature - if topic0 != &CHUNK_PAYMENT_EVENT_SIGNATURE { + if topic0 != &DATA_PAYMENT_EVENT_SIGNATURE { return Err(Error::EventSignatureDoesNotMatch); } diff --git a/evmlib/src/lib.rs b/evmlib/src/lib.rs index cd853bbb96..cdb1f6c072 100644 --- a/evmlib/src/lib.rs +++ b/evmlib/src/lib.rs @@ -1,5 +1,5 @@ use crate::common::{Address, QuoteHash, TxHash, U256}; -use crate::transaction::verify_chunk_payment; +use crate::transaction::verify_data_payment; use alloy::primitives::address; use alloy::transports::http::reqwest; use std::str::FromStr; @@ -24,24 +24,24 @@ const ARBITRUM_ONE_PAYMENT_TOKEN_ADDRESS: Address = address!("4bc1aCE0E66170375462cB4E6Af42Ad4D5EC689C"); // Should be updated when the smart contract changes! -const ARBITRUM_ONE_CHUNK_PAYMENTS_ADDRESS: Address = +const ARBITRUM_ONE_DATA_PAYMENTS_ADDRESS: Address = address!("708353783756C62818aCdbce914d90E0245F7319"); #[derive(Clone, Debug, PartialEq)] pub struct CustomNetwork { pub rpc_url_http: reqwest::Url, pub payment_token_address: Address, - pub chunk_payments_address: Address, + pub data_payments_address: Address, } impl CustomNetwork { - pub fn new(rpc_url: &str, payment_token_addr: &str, chunk_payments_addr: &str) -> Self { + pub fn new(rpc_url: &str, payment_token_addr: &str, data_payments_addr: &str) -> Self { Self { rpc_url_http: reqwest::Url::parse(rpc_url).expect("Invalid RPC URL"), payment_token_address: Address::from_str(payment_token_addr) .expect("Invalid payment token address"), - chunk_payments_address: Address::from_str(chunk_payments_addr) - .expect("Invalid chunk payments address"), + data_payments_address: Address::from_str(data_payments_addr) + .expect("Invalid data payments address"), } } } @@ -74,14 +74,14 @@ impl Network { } } - pub fn chunk_payments_address(&self) -> &Address { + pub fn data_payments_address(&self) -> &Address { match self { - Network::ArbitrumOne => &ARBITRUM_ONE_CHUNK_PAYMENTS_ADDRESS, - Network::Custom(custom) => &custom.chunk_payments_address, + Network::ArbitrumOne => &ARBITRUM_ONE_DATA_PAYMENTS_ADDRESS, + Network::Custom(custom) => &custom.data_payments_address, } } - pub async fn verify_chunk_payment( + pub async fn verify_data_payment( &self, tx_hash: TxHash, quote_hash: QuoteHash, @@ -89,7 +89,7 @@ impl Network { amount: U256, quote_expiration_timestamp_in_secs: u64, ) -> Result<(), transaction::Error> { - verify_chunk_payment( + verify_data_payment( self, tx_hash, quote_hash, diff --git a/evmlib/src/testnet.rs b/evmlib/src/testnet.rs index 015ee035c1..8464725a7b 100644 --- a/evmlib/src/testnet.rs +++ b/evmlib/src/testnet.rs @@ -1,5 +1,5 @@ use crate::common::Address; -use crate::contract::chunk_payments::ChunkPayments; +use crate::contract::data_payments::DataPayments; use crate::contract::network_token::NetworkToken; use crate::{CustomNetwork, Network}; use alloy::hex::ToHexExt; @@ -13,22 +13,22 @@ use alloy::transports::http::{Client, Http}; pub struct Testnet { anvil: AnvilInstance, network_token_address: Address, - chunk_payments_address: Address, + data_payments_address: Address, } impl Testnet { - /// Starts an Anvil node and automatically deploys the network token and chunk payments smart contracts. + /// Starts an Anvil node and automatically deploys the network token and data payments smart contracts. pub async fn new() -> Self { let anvil = start_node(); let network_token = deploy_network_token_contract(&anvil).await; - let chunk_payments = - deploy_chunk_payments_contract(&anvil, *network_token.contract.address()).await; + let data_payments = + deploy_data_payments_contract(&anvil, *network_token.contract.address()).await; Testnet { anvil, network_token_address: *network_token.contract.address(), - chunk_payments_address: *chunk_payments.contract.address(), + data_payments_address: *data_payments.contract.address(), } } @@ -42,7 +42,7 @@ impl Testnet { Network::Custom(CustomNetwork { rpc_url_http: rpc_url, payment_token_address: self.network_token_address, - chunk_payments_address: self.chunk_payments_address, + data_payments_address: self.data_payments_address, }) } @@ -89,10 +89,10 @@ pub async fn deploy_network_token_contract( NetworkToken::deploy(provider).await } -pub async fn deploy_chunk_payments_contract( +pub async fn deploy_data_payments_contract( anvil: &AnvilInstance, token_address: Address, -) -> ChunkPayments< +) -> DataPayments< Http, FillProvider< JoinFill>, @@ -114,5 +114,5 @@ pub async fn deploy_chunk_payments_contract( .on_http(rpc_url); // Deploy the contract. - ChunkPayments::deploy(provider, token_address).await + DataPayments::deploy(provider, token_address).await } diff --git a/evmlib/src/transaction.rs b/evmlib/src/transaction.rs index b74c268450..f0f1aa76a2 100644 --- a/evmlib/src/transaction.rs +++ b/evmlib/src/transaction.rs @@ -1,5 +1,5 @@ use crate::common::{Address, QuoteHash, TxHash, U256}; -use crate::event::{ChunkPaymentEvent, CHUNK_PAYMENT_EVENT_SIGNATURE}; +use crate::event::{DataPaymentEvent, DATA_PAYMENT_EVENT_SIGNATURE}; use crate::Network; use alloy::eips::BlockNumberOrTag; use alloy::primitives::FixedBytes; @@ -57,9 +57,9 @@ async fn get_transaction_logs(network: &Network, filter: Filter) -> Result = FixedBytes::left_padding_from(reward_addr.as_slice()); let filter = Filter::new() - .event_signature(CHUNK_PAYMENT_EVENT_SIGNATURE) + .event_signature(DATA_PAYMENT_EVENT_SIGNATURE) .topic1(topic1) .topic2(amount) .topic3(quote_hash) @@ -79,8 +79,8 @@ async fn get_chunk_payment_event( get_transaction_logs(network, filter).await } -/// Verify if a chunk payment is confirmed. -pub async fn verify_chunk_payment( +/// Verify if a data payment is confirmed. +pub async fn verify_data_payment( network: &Network, tx_hash: TxHash, quote_hash: QuoteHash, @@ -111,7 +111,7 @@ pub async fn verify_chunk_payment( } let logs = - get_chunk_payment_event(network, block_number, quote_hash, reward_addr, amount).await?; + get_data_payment_event(network, block_number, quote_hash, reward_addr, amount).await?; for log in logs { if log.transaction_hash != Some(tx_hash) { @@ -119,7 +119,7 @@ pub async fn verify_chunk_payment( continue; } - if let Ok(event) = ChunkPaymentEvent::try_from(log) { + if let Ok(event) = DataPaymentEvent::try_from(log) { // Check if the event matches what we expect. if event.quote_hash == quote_hash && event.reward_address == reward_addr @@ -137,7 +137,7 @@ pub async fn verify_chunk_payment( mod tests { use crate::common::{Address, U256}; use crate::transaction::{ - get_chunk_payment_event, get_transaction_receipt_by_hash, verify_chunk_payment, + get_data_payment_event, get_transaction_receipt_by_hash, verify_data_payment, }; use crate::Network; use alloy::hex::FromHex; @@ -156,7 +156,7 @@ mod tests { } #[tokio::test] - async fn test_get_chunk_payment_event() { + async fn test_get_data_payment_event() { let network = Network::ArbitrumOne; let block_number: u64 = 250043261; @@ -165,7 +165,7 @@ mod tests { let quote_hash = b256!("477a32ca129183ebaa7e0a082813f8f9b121a1f9ba5dd83104bae44b6e32658c"); // DevSkim: ignore DS173237 let logs = - get_chunk_payment_event(&network, block_number, quote_hash, reward_address, amount) + get_data_payment_event(&network, block_number, quote_hash, reward_address, amount) .await .unwrap(); @@ -173,7 +173,7 @@ mod tests { } #[tokio::test] - async fn test_verify_chunk_payment() { + async fn test_verify_data_payment() { let network = Network::ArbitrumOne; let tx_hash = b256!("462ff33b01d7930b05dc87826b485f6f19884f1cf1c15694477be68ff7dda066"); // DevSkim: ignore DS173237 @@ -181,7 +181,7 @@ mod tests { let reward_address = Address::from_hex("fdd33ec6f2325b742c1f32ed5b1da19547cb2f30").unwrap(); // DevSkim: ignore DS173237 let amount = U256::from(200); - let result = verify_chunk_payment( + let result = verify_data_payment( &network, tx_hash, quote_hash, diff --git a/evmlib/src/utils.rs b/evmlib/src/utils.rs index 8fde529508..f49f609c20 100644 --- a/evmlib/src/utils.rs +++ b/evmlib/src/utils.rs @@ -16,7 +16,7 @@ pub fn dummy_hash() -> Hash { /// Get the `Network` from environment variables pub fn evm_network_from_env() -> Result { - const EVM_VARS: [&str; 3] = ["RPC_URL", "PAYMENT_TOKEN_ADDRESS", "CHUNK_PAYMENTS_ADDRESS"]; + const EVM_VARS: [&str; 3] = ["RPC_URL", "PAYMENT_TOKEN_ADDRESS", "DATA_PAYMENTS_ADDRESS"]; let custom_vars_exist = EVM_VARS.iter().all(|var| env::var(var).is_ok()); if custom_vars_exist { diff --git a/evmlib/src/wallet.rs b/evmlib/src/wallet.rs index 498eb3afc2..41c486d05f 100644 --- a/evmlib/src/wallet.rs +++ b/evmlib/src/wallet.rs @@ -1,9 +1,9 @@ use std::collections::BTreeMap; use crate::common::{Address, QuoteHash, QuotePayment, TxHash, U256}; -use crate::contract::chunk_payments::{ChunkPayments, MAX_TRANSFERS_PER_TRANSACTION}; +use crate::contract::data_payments::{DataPayments, MAX_TRANSFERS_PER_TRANSACTION}; use crate::contract::network_token::NetworkToken; -use crate::contract::{chunk_payments, network_token}; +use crate::contract::{data_payments, network_token}; use crate::Network; use alloy::network::{Ethereum, EthereumWallet, NetworkWallet, TransactionBuilder}; use alloy::providers::fillers::{ @@ -23,8 +23,8 @@ pub enum Error { RpcError(#[from] RpcError), #[error("Network token contract error: {0}")] NetworkTokenContract(#[from] network_token::Error), - #[error("Chunk payments contract error: {0}")] - ChunkPaymentsContract(#[from] chunk_payments::error::Error), + #[error("Data payments contract error: {0}")] + DataPaymentsContract(#[from] data_payments::error::Error), } pub struct Wallet { @@ -99,9 +99,9 @@ impl Wallet { /// transaction hashes of the payments by quotes. pub async fn pay_for_quotes>( &self, - chunk_payments: I, + data_payments: I, ) -> Result, PayForQuotesError> { - pay_for_quotes(self.wallet.clone(), &self.network, chunk_payments).await + pay_for_quotes(self.wallet.clone(), &self.network, data_payments).await } } @@ -218,7 +218,7 @@ pub async fn transfer_gas_tokens( #[derive(Debug)] pub struct PayForQuotesError(pub Error, pub BTreeMap); -/// Use this wallet to pay for chunks in batched transfer transactions. +/// Use this wallet to pay for datas in batched transfer transactions. /// If the amount of transfers is more than one transaction can contain, the transfers will be split up over multiple transactions. pub async fn pay_for_quotes>( wallet: EthereumWallet, @@ -234,22 +234,22 @@ pub async fn pay_for_quotes>( approve_to_spend_tokens( wallet.clone(), network, - *network.chunk_payments_address(), + *network.data_payments_address(), total_amount, ) .await .map_err(|err| PayForQuotesError(Error::from(err), tx_hashes_by_quote.clone()))?; let provider = http_provider_with_wallet(network.rpc_url().clone(), wallet); - let chunk_payments = ChunkPayments::new(*network.chunk_payments_address(), provider); + let data_payments = DataPayments::new(*network.data_payments_address(), provider); // Divide transfers over multiple transactions if they exceed the max per transaction. - let chunks = payments.chunks(MAX_TRANSFERS_PER_TRANSACTION); + let data_batches = payments.chunks(MAX_TRANSFERS_PER_TRANSACTION); - for batch in chunks { + for batch in data_batches { let batch: Vec = batch.to_vec(); - let tx_hash = chunk_payments + let tx_hash = data_payments .pay_for_quotes(batch.clone()) .await .map_err(|err| PayForQuotesError(Error::from(err), tx_hashes_by_quote.clone()))?; diff --git a/evmlib/tests/chunk_payments.rs b/evmlib/tests/chunk_payments.rs index 244cceab43..63ca77a050 100644 --- a/evmlib/tests/chunk_payments.rs +++ b/evmlib/tests/chunk_payments.rs @@ -10,9 +10,9 @@ use alloy::providers::{ProviderBuilder, ReqwestProvider, WalletProvider}; use alloy::signers::local::{LocalSigner, PrivateKeySigner}; use alloy::transports::http::{Client, Http}; use evmlib::common::U256; -use evmlib::contract::chunk_payments::{ChunkPayments, MAX_TRANSFERS_PER_TRANSACTION}; +use evmlib::contract::data_payments::{DataPayments, MAX_TRANSFERS_PER_TRANSACTION}; use evmlib::contract::network_token::NetworkToken; -use evmlib::testnet::{deploy_chunk_payments_contract, deploy_network_token_contract, start_node}; +use evmlib::testnet::{deploy_data_payments_contract, deploy_network_token_contract, start_node}; use evmlib::wallet::wallet_address; async fn setup() -> ( @@ -27,7 +27,7 @@ async fn setup() -> ( >, Ethereum, >, - ChunkPayments< + DataPayments< Http, FillProvider< JoinFill>, @@ -42,10 +42,10 @@ async fn setup() -> ( let network_token = deploy_network_token_contract(&anvil).await; - let chunk_payments = - deploy_chunk_payments_contract(&anvil, *network_token.contract.address()).await; + let data_payments = + deploy_data_payments_contract(&anvil, *network_token.contract.address()).await; - (anvil, network_token, chunk_payments) + (anvil, network_token, data_payments) } #[allow(clippy::unwrap_used)] @@ -87,7 +87,7 @@ async fn test_deploy() { #[tokio::test] async fn test_pay_for_quotes() { - let (_anvil, network_token, mut chunk_payments) = setup().await; + let (_anvil, network_token, mut data_payments) = setup().await; let mut quote_payments = vec![]; @@ -97,15 +97,15 @@ async fn test_pay_for_quotes() { } let _ = network_token - .approve(*chunk_payments.contract.address(), U256::MAX) + .approve(*data_payments.contract.address(), U256::MAX) .await .unwrap(); // Contract provider has a different account coupled to it, // so we set it to the same as the network token contract - chunk_payments.set_provider(network_token.contract.provider().clone()); + data_payments.set_provider(network_token.contract.provider().clone()); - let result = chunk_payments.pay_for_quotes(quote_payments).await; + let result = data_payments.pay_for_quotes(quote_payments).await; assert!(result.is_ok(), "Failed with error: {:?}", result.err()); } diff --git a/evmlib/tests/data_payments.rs b/evmlib/tests/data_payments.rs new file mode 100644 index 0000000000..63ca77a050 --- /dev/null +++ b/evmlib/tests/data_payments.rs @@ -0,0 +1,111 @@ +mod common; + +use crate::common::quote::random_quote_payment; +use alloy::network::{Ethereum, EthereumWallet}; +use alloy::node_bindings::AnvilInstance; +use alloy::primitives::utils::parse_ether; +use alloy::providers::ext::AnvilApi; +use alloy::providers::fillers::{FillProvider, JoinFill, RecommendedFiller, WalletFiller}; +use alloy::providers::{ProviderBuilder, ReqwestProvider, WalletProvider}; +use alloy::signers::local::{LocalSigner, PrivateKeySigner}; +use alloy::transports::http::{Client, Http}; +use evmlib::common::U256; +use evmlib::contract::data_payments::{DataPayments, MAX_TRANSFERS_PER_TRANSACTION}; +use evmlib::contract::network_token::NetworkToken; +use evmlib::testnet::{deploy_data_payments_contract, deploy_network_token_contract, start_node}; +use evmlib::wallet::wallet_address; + +async fn setup() -> ( + AnvilInstance, + NetworkToken< + Http, + FillProvider< + JoinFill>, + ReqwestProvider, + Http, + Ethereum, + >, + Ethereum, + >, + DataPayments< + Http, + FillProvider< + JoinFill>, + ReqwestProvider, + Http, + Ethereum, + >, + Ethereum, + >, +) { + let anvil = start_node(); + + let network_token = deploy_network_token_contract(&anvil).await; + + let data_payments = + deploy_data_payments_contract(&anvil, *network_token.contract.address()).await; + + (anvil, network_token, data_payments) +} + +#[allow(clippy::unwrap_used)] +#[allow(clippy::type_complexity)] +#[allow(dead_code)] +async fn provider_with_gas_funded_wallet( + anvil: &AnvilInstance, +) -> FillProvider< + JoinFill>, + ReqwestProvider, + Http, + Ethereum, +> { + let signer: PrivateKeySigner = LocalSigner::random(); + let wallet = EthereumWallet::from(signer); + + let rpc_url = anvil.endpoint().parse().unwrap(); + + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .wallet(wallet) + .on_http(rpc_url); + + let account = wallet_address(provider.wallet()); + + // Fund the wallet with plenty of gas tokens + provider + .anvil_set_balance(account, parse_ether("1000").expect("")) + .await + .unwrap(); + + provider +} + +#[tokio::test] +async fn test_deploy() { + setup().await; +} + +#[tokio::test] +async fn test_pay_for_quotes() { + let (_anvil, network_token, mut data_payments) = setup().await; + + let mut quote_payments = vec![]; + + for _ in 0..MAX_TRANSFERS_PER_TRANSACTION { + let quote_payment = random_quote_payment(); + quote_payments.push(quote_payment); + } + + let _ = network_token + .approve(*data_payments.contract.address(), U256::MAX) + .await + .unwrap(); + + // Contract provider has a different account coupled to it, + // so we set it to the same as the network token contract + data_payments.set_provider(network_token.contract.provider().clone()); + + let result = data_payments.pay_for_quotes(quote_payments).await; + + assert!(result.is_ok(), "Failed with error: {:?}", result.err()); +} diff --git a/evmlib/tests/wallet.rs b/evmlib/tests/wallet.rs index 97531859b6..a95ee34eca 100644 --- a/evmlib/tests/wallet.rs +++ b/evmlib/tests/wallet.rs @@ -8,9 +8,9 @@ use alloy::providers::ext::AnvilApi; use alloy::providers::{ProviderBuilder, WalletProvider}; use alloy::signers::local::{LocalSigner, PrivateKeySigner}; use evmlib::common::{Amount, TxHash}; -use evmlib::contract::chunk_payments::MAX_TRANSFERS_PER_TRANSACTION; -use evmlib::testnet::{deploy_chunk_payments_contract, deploy_network_token_contract, start_node}; -use evmlib::transaction::verify_chunk_payment; +use evmlib::contract::data_payments::MAX_TRANSFERS_PER_TRANSACTION; +use evmlib::testnet::{deploy_data_payments_contract, deploy_network_token_contract, start_node}; +use evmlib::transaction::verify_data_payment; use evmlib::wallet::{transfer_tokens, wallet_address, Wallet}; use evmlib::{CustomNetwork, Network}; use std::collections::HashSet; @@ -21,14 +21,14 @@ async fn local_testnet() -> (AnvilInstance, Network, EthereumWallet) { let rpc_url = anvil.endpoint().parse().unwrap(); let network_token = deploy_network_token_contract(&anvil).await; let payment_token_address = *network_token.contract.address(); - let chunk_payments = deploy_chunk_payments_contract(&anvil, payment_token_address).await; + let data_payments = deploy_data_payments_contract(&anvil, payment_token_address).await; ( anvil, Network::Custom(CustomNetwork { rpc_url_http: rpc_url, payment_token_address, - chunk_payments_address: *chunk_payments.contract.address(), + data_payments_address: *data_payments.contract.address(), }), network_token.contract.provider().wallet().clone(), ) @@ -65,7 +65,7 @@ async fn funded_wallet(network: &Network, genesis_wallet: EthereumWallet) -> Wal } #[tokio::test] -async fn test_pay_for_quotes_and_chunk_payment_verification() { +async fn test_pay_for_quotes_and_data_payment_verification() { const TRANSFERS: usize = 600; const EXPIRATION_TIMESTAMP_IN_SECS: u64 = 4102441200; // The year 2100 @@ -91,7 +91,7 @@ async fn test_pay_for_quotes_and_chunk_payment_verification() { for quote_payment in quote_payments.iter() { let tx_hash = *tx_hashes.get("e_payment.0).unwrap(); - let result = verify_chunk_payment( + let result = verify_data_payment( &network, tx_hash, quote_payment.0, diff --git a/sn_evm/CHANGELOG.md b/sn_evm/CHANGELOG.md index ec4c00a34f..25619a4440 100644 --- a/sn_evm/CHANGELOG.md +++ b/sn_evm/CHANGELOG.md @@ -55,7 +55,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - correct genesis_pk naming - genesis_cn public fields generated from hard coded value -- invalid spend reason in data payments +- invalid spend reason in chunk payments ### Other - *(transfers)* comment and naming updates for clarity @@ -266,7 +266,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.14.35](https://github.com/maidsafe/safe_network/compare/sn_transfers-v0.14.34...sn_transfers-v0.14.35) - 2024-01-09 ### Added -- *(client)* extra sleep between chunk verification +- *(client)* extra sleep between data verification ## [0.14.34](https://github.com/maidsafe/safe_network/compare/sn_transfers-v0.14.33...sn_transfers-v0.14.34) - 2024-01-09 @@ -637,7 +637,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - add tx and parent spends verification -- chunk payments using UTXOs instead of DBCs +- data payments using UTXOs instead of DBCs ### Other - use updated sn_dbc @@ -650,7 +650,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.11.8](https://github.com/maidsafe/safe_network/compare/sn_transfers-v0.11.7...sn_transfers-v0.11.8) - 2023-09-08 ### Added -- *(client)* repay for chunks if they cannot be validated +- *(client)* repay for datas if they cannot be validated ## [0.11.7](https://github.com/maidsafe/safe_network/compare/sn_transfers-v0.11.6...sn_transfers-v0.11.7) - 2023-09-05 @@ -698,10 +698,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - one transfer per data set, mapped dbcs to content addrs -- [**breaking**] pay each chunk holder direct +- [**breaking**] pay each data holder direct - feat!(protocol): gets keys with GetStoreCost -- feat!(protocol): get price and pay for each chunk individually -- feat!(protocol): remove chunk merkletree to simplify payment +- feat!(protocol): get price and pay for each data individually +- feat!(protocol): remove data merkletree to simplify payment ### Fixed - *(tokio)* remove tokio fs @@ -904,7 +904,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.9.3](https://github.com/maidsafe/safe_network/compare/sn_transfers-v0.9.2...sn_transfers-v0.9.3) - 2023-06-14 ### Added -- include output DBC within payment proof for Chunks storage +- include output DBC within payment proof for Datas storage ## [0.9.2](https://github.com/maidsafe/safe_network/compare/sn_transfers-v0.9.1...sn_transfers-v0.9.2) - 2023-06-12 diff --git a/sn_node/src/bin/safenode/subcommands.rs b/sn_node/src/bin/safenode/subcommands.rs index 3faada3562..8c3c87bf77 100644 --- a/sn_node/src/bin/safenode/subcommands.rs +++ b/sn_node/src/bin/safenode/subcommands.rs @@ -18,7 +18,7 @@ pub(crate) enum EvmNetworkCommand { /// The chunk payments contract address #[arg(long, short)] - chunk_payments_address: String, + data_payments_address: String, }, } @@ -30,11 +30,11 @@ impl Into for EvmNetworkCommand { Self::EvmCustom { rpc_url, payment_token_address, - chunk_payments_address, + data_payments_address, } => EvmNetwork::Custom(EvmNetworkCustom::new( &rpc_url, &payment_token_address, - &chunk_payments_address, + &data_payments_address, )), } } diff --git a/sn_node/src/put_validation.rs b/sn_node/src/put_validation.rs index 149e6991e0..a93158a18f 100644 --- a/sn_node/src/put_validation.rs +++ b/sn_node/src/put_validation.rs @@ -608,7 +608,7 @@ impl Node { // check if payment is valid on chain debug!("Verifying payment for record {pretty_key}"); self.evm_network() - .verify_chunk_payment( + .verify_data_payment( payment.tx_hash, payment.quote.hash(), *self.reward_address(), diff --git a/sn_node_manager/src/bin/cli/subcommands/evm_network.rs b/sn_node_manager/src/bin/cli/subcommands/evm_network.rs index 89c39a16f6..0360dea97b 100644 --- a/sn_node_manager/src/bin/cli/subcommands/evm_network.rs +++ b/sn_node_manager/src/bin/cli/subcommands/evm_network.rs @@ -16,9 +16,9 @@ pub enum EvmNetworkCommand { #[arg(long, short)] payment_token_address: String, - /// The chunk payments contract address + /// The data payments contract address #[arg(long, short)] - chunk_payments_address: String, + data_payments_address: String, }, } @@ -30,11 +30,11 @@ impl Into for EvmNetworkCommand { Self::EvmCustom { rpc_url, payment_token_address, - chunk_payments_address, + data_payments_address, } => EvmNetwork::Custom(EvmNetworkCustom::new( &rpc_url, &payment_token_address, - &chunk_payments_address, + &data_payments_address, )), } } diff --git a/sn_node_manager/src/local.rs b/sn_node_manager/src/local.rs index e729022d69..8812bc1bbf 100644 --- a/sn_node_manager/src/local.rs +++ b/sn_node_manager/src/local.rs @@ -150,8 +150,8 @@ impl Launcher for LocalSafeLauncher { args.push(custom.rpc_url_http.to_string()); args.push("--payment-token-address".to_string()); args.push(custom.payment_token_address.to_string()); - args.push("--chunk-payments-address".to_string()); - args.push(custom.chunk_payments_address.to_string()); + args.push("--data-payments-address".to_string()); + args.push(custom.data_payments_address.to_string()); } } diff --git a/test_utils/src/evm.rs b/test_utils/src/evm.rs index 4ec41ca5d2..2c1d85eb4a 100644 --- a/test_utils/src/evm.rs +++ b/test_utils/src/evm.rs @@ -18,28 +18,28 @@ pub fn evm_network_from_env() -> evmlib::Network { let evm_network = env::var("EVM_NETWORK").ok(); let arbitrum_flag = evm_network.as_deref() == Some("arbitrum-one"); - let (rpc_url, payment_token_address, chunk_payments_address) = if arbitrum_flag { + let (rpc_url, payment_token_address, data_payments_address) = if arbitrum_flag { ( evmlib::Network::ArbitrumOne.rpc_url().to_string(), evmlib::Network::ArbitrumOne .payment_token_address() .encode_hex_with_prefix(), evmlib::Network::ArbitrumOne - .chunk_payments_address() + .data_payments_address() .encode_hex_with_prefix(), ) } else { ( get_var_or_panic("RPC_URL"), get_var_or_panic("PAYMENT_TOKEN_ADDRESS"), - get_var_or_panic("CHUNK_PAYMENTS_ADDRESS"), + get_var_or_panic("DATA_PAYMENTS_ADDRESS"), ) }; evmlib::Network::Custom(CustomNetwork::new( &rpc_url, &payment_token_address, - &chunk_payments_address, + &data_payments_address, )) }