Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(evmlib): Chunk->Data #2185

Draft
wants to merge 1 commit into
base: evm-dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <YOUR_ETHEREUM_ADDRESS> evm-custom --rpc-url <RPC_URL> --payment-token-address <TOKEN_ADDRESS> --chunk-payments-address <CONTRACT_ADDRESS>
cargo run --bin=safenode-manager --features=local-discovery -- local run --build --clean --rewards-address <YOUR_ETHEREUM_ADDRESS> evm-custom --rpc-url <RPC_URL> --payment-token-address <TOKEN_ADDRESS> --data-payments-address <CONTRACT_ADDRESS>
```

4. Verify node status: <br>
Expand Down
10 changes: 5 additions & 5 deletions autonomi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <ETHEREUM_ADDRESS> evm-custom --rpc-url <RPC_URL> --payment-token-address <TOKEN_ADDRESS> --chunk-payments-address <CONTRACT_ADDRESS>
cargo run --bin=safenode-manager --features=local-discovery -- local run --build --clean --rewards-address <ETHEREUM_ADDRESS> evm-custom --rpc-url <RPC_URL> --payment-token-address <TOKEN_ADDRESS> --data-payments-address <CONTRACT_ADDRESS>
```

4. Then run the tests with the `local` feature and pass the EVM params again:

```sh
$ RPC_URL=<RPC_URL> PAYMENT_TOKEN_ADDRESS=<TOKEN_ADDRESS> CHUNK_PAYMENTS_ADDRESS=<CONTRACT_ADDRESS> cargo test --package=autonomi --features=local
$ RPC_URL=<RPC_URL> PAYMENT_TOKEN_ADDRESS=<TOKEN_ADDRESS> DATA_PAYMENTS_ADDRESS=<CONTRACT_ADDRESS> cargo test --package=autonomi --features=local
# Or with logs
$ RUST_LOG=autonomi RPC_URL=<RPC_URL> PAYMENT_TOKEN_ADDRESS=<TOKEN_ADDRESS> CHUNK_PAYMENTS_ADDRESS=<CONTRACT_ADDRESS> cargo test --package=autonomi --features=local -- --nocapture
$ RUST_LOG=autonomi RPC_URL=<RPC_URL> PAYMENT_TOKEN_ADDRESS=<TOKEN_ADDRESS> DATA_PAYMENTS_ADDRESS=<CONTRACT_ADDRESS> cargo test --package=autonomi --features=local -- --nocapture
```

### Using a live testnet or mainnet
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion evm_testnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
```
5 changes: 1 addition & 4 deletions evm_testnet/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,7 @@ async fn print_testnet_details(testnet: &Testnet, genesis_wallet: Option<Address

println!("RPC URL: {}", network.rpc_url());
println!("Payment token address: {}", network.payment_token_address());
println!(
"Chunk payments address: {}",
network.chunk_payments_address()
);
println!("Data payments address: {}", network.data_payments_address());
println!(
"Deployer wallet private key: {}",
testnet.default_wallet_private_key()
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,76 +2,77 @@ pub mod error;

use crate::common;
use crate::common::{Address, TxHash};
use crate::contract::chunk_payments::error::Error;
use crate::contract::chunk_payments::ChunkPaymentsContract::ChunkPaymentsContractInstance;
use crate::contract::data_payments::error::Error;
use crate::contract::data_payments::DataPaymentsContract::DataPaymentsContractInstance;

use alloy::providers::{Network, Provider};
use alloy::sol;
use alloy::transports::Transport;

/// The max amount of transfers within one chunk payments transaction.
/// The max amount of transfers within one data payments transaction.
pub const MAX_TRANSFERS_PER_TRANSACTION: usize = 512;

sol!(
#[allow(clippy::too_many_arguments)]
#[allow(missing_docs)]
#[sol(rpc)]
ChunkPaymentsContract,
"artifacts/ChunkPayments.json"
DataPaymentsContract,
"artifacts/DataPayments.json"
);

pub struct ChunkPayments<T: Transport + Clone, P: Provider<T, N>, N: Network> {
pub contract: ChunkPaymentsContractInstance<T, P, N>,
pub struct DataPayments<T: Transport + Clone, P: Provider<T, N>, N: Network> {
pub contract: DataPaymentsContractInstance<T, P, N>,
}

impl<T, P, N> ChunkPayments<T, P, N>
impl<T, P, N> DataPayments<T, P, N>
where
T: Transport + Clone,
P: Provider<T, N>,
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<I: IntoIterator<Item = common::QuotePayment>>(
&self,
chunk_payments: I,
data_payments: I,
) -> Result<TxHash, Error> {
let chunk_payments: Vec<ChunkPaymentsContract::ChunkPayment> = chunk_payments
let data_payments: Vec<DataPaymentsContract::ChunkPayment> = 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()
Expand Down
2 changes: 1 addition & 1 deletion evmlib/src/contract/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pub mod chunk_payments;
pub mod data_payments;
pub mod network_token;
10 changes: 5 additions & 5 deletions evmlib/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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<Log> for ChunkPaymentEvent {
impl TryFrom<Log> for DataPaymentEvent {
type Error = Error;

fn try_from(log: Log) -> Result<Self, Self::Error> {
Expand All @@ -36,7 +36,7 @@ impl TryFrom<Log> 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);
}

Expand Down
22 changes: 11 additions & 11 deletions evmlib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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"),
}
}
}
Expand Down Expand Up @@ -74,22 +74,22 @@ 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,
reward_addr: Address,
amount: U256,
quote_expiration_timestamp_in_secs: u64,
) -> Result<(), transaction::Error> {
verify_chunk_payment(
verify_data_payment(
self,
tx_hash,
quote_hash,
Expand Down
20 changes: 10 additions & 10 deletions evmlib/src/testnet.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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(),
}
}

Expand All @@ -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,
})
}

Expand Down Expand Up @@ -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<Client>,
FillProvider<
JoinFill<RecommendedFiller, WalletFiller<EthereumWallet>>,
Expand All @@ -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
}
Loading
Loading