Skip to content

Commit

Permalink
feat: configure anvil to listen on non-local address
Browse files Browse the repository at this point in the history
  • Loading branch information
jacderida committed Oct 8, 2024
1 parent cbb89f9 commit a18c942
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 25 deletions.
46 changes: 30 additions & 16 deletions evmlib/src/testnet.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::common::Address;
use crate::contract::data_payments::DataPaymentsHandler;
use crate::contract::network_token::NetworkToken;
use crate::reqwest::Url;
use crate::{CustomNetwork, Network};
use alloy::hex::ToHexExt;
use alloy::network::{Ethereum, EthereumWallet};
Expand All @@ -21,11 +22,12 @@ pub struct Testnet {
impl Testnet {
/// Starts an Anvil node and automatically deploys the network token and chunk payments smart contracts.
pub async fn new() -> Self {
let anvil = start_node();
let (anvil, rpc_url) = start_node();

let network_token = deploy_network_token_contract(&anvil).await;
let network_token = deploy_network_token_contract(&rpc_url, &anvil).await;
let data_payments =
deploy_data_payments_contract(&anvil, *network_token.contract.address()).await;
deploy_data_payments_contract(&rpc_url, &anvil, *network_token.contract.address())
.await;

Testnet {
anvil,
Expand All @@ -40,6 +42,7 @@ impl Testnet {
.endpoint()
.parse()
.expect("Could not parse RPC URL");
println!("RPC URL: {}", rpc_url);

Network::Custom(CustomNetwork {
rpc_url_http: rpc_url,
Expand All @@ -55,17 +58,31 @@ impl Testnet {
}
}

/// Runs a local Anvil node.
pub fn start_node() -> AnvilInstance {
// Spin up a local Anvil node.
// Requires you to have Foundry installed: https://book.getfoundry.sh/getting-started/installation
Anvil::new()
.port(4343_u16)
/// Runs a local Anvil node bound to a specified IP address.
///
/// The `AnvilInstance` `endpoint` function is hardcoded to return "localhost", so we must also
/// return the RPC URL if we want to listen on something other than `localhost`.
///
/// The `anvil` binary respects the `ANVIL_IP_ADDR` environment variable, but defaults to "localhost".
pub fn start_node() -> (AnvilInstance, Url) {
let host = std::env::var("ANVIL_IP_ADDR").unwrap_or_else(|_| "localhost".to_string());
let port = std::env::var("ANVIL_PORT")
.unwrap_or_else(|_| "4343".to_string())
.parse::<u16>()
.expect("Invalid port number");

let anvil = Anvil::new()
.port(port)
.try_spawn()
.expect("Could not spawn Anvil node")
.expect("Could not spawn Anvil node");

let url = Url::parse(&format!("http://{}:{}", host, port)).expect("Failed to parse URL");

(anvil, url)
}

pub async fn deploy_network_token_contract(
rpc_url: &Url,
anvil: &AnvilInstance,
) -> NetworkToken<
Http<Client>,
Expand All @@ -87,18 +104,17 @@ pub async fn deploy_network_token_contract(
let signer: PrivateKeySigner = anvil.keys()[0].clone().into();
let wallet = EthereumWallet::from(signer);

let rpc_url = anvil.endpoint().parse().expect("Could not parse RPC URL");

let provider = ProviderBuilder::new()
.with_recommended_fillers()
.wallet(wallet)
.on_http(rpc_url);
.on_http(rpc_url.clone());

// Deploy the contract.
NetworkToken::deploy(provider).await
}

pub async fn deploy_data_payments_contract(
rpc_url: &Url,
anvil: &AnvilInstance,
token_address: Address,
) -> DataPaymentsHandler<
Expand All @@ -121,12 +137,10 @@ pub async fn deploy_data_payments_contract(
let signer: PrivateKeySigner = anvil.keys()[1].clone().into();
let wallet = EthereumWallet::from(signer);

let rpc_url = anvil.endpoint().parse().expect("Could not parse RPC URL");

let provider = ProviderBuilder::new()
.with_recommended_fillers()
.wallet(wallet)
.on_http(rpc_url);
.on_http(rpc_url.clone());

// Deploy the contract.
DataPaymentsHandler::deploy(provider, token_address).await
Expand Down
6 changes: 3 additions & 3 deletions evmlib/tests/data_payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ async fn setup() -> (
Ethereum,
>,
) {
let anvil = start_node();
let (anvil, rpc_url) = start_node();

let network_token = deploy_network_token_contract(&anvil).await;
let network_token = deploy_network_token_contract(&rpc_url, &anvil).await;

let data_payments =
deploy_data_payments_contract(&anvil, *network_token.contract.address()).await;
deploy_data_payments_contract(&rpc_url, &anvil, *network_token.contract.address()).await;

(anvil, network_token, data_payments)
}
Expand Down
4 changes: 2 additions & 2 deletions evmlib/tests/network_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ async fn setup() -> (
Ethereum,
>,
) {
let anvil = start_node();
let (anvil, rpc_url) = start_node();

let network_token = deploy_network_token_contract(&anvil).await;
let network_token = deploy_network_token_contract(&rpc_url, &anvil).await;

(anvil, network_token)
}
Expand Down
8 changes: 4 additions & 4 deletions evmlib/tests/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ use std::collections::HashSet;

#[allow(clippy::unwrap_used)]
async fn local_testnet() -> (AnvilInstance, Network, EthereumWallet) {
let anvil = start_node();
let rpc_url = anvil.endpoint().parse().unwrap();
let network_token = deploy_network_token_contract(&anvil).await;
let (anvil, rpc_url) = start_node();
let network_token = deploy_network_token_contract(&rpc_url, &anvil).await;
let payment_token_address = *network_token.contract.address();
let data_payments = deploy_data_payments_contract(&anvil, payment_token_address).await;
let data_payments =
deploy_data_payments_contract(&rpc_url, &anvil, payment_token_address).await;

(
anvil,
Expand Down

0 comments on commit a18c942

Please sign in to comment.