Skip to content

Commit

Permalink
Merge pull request #2235 from jacderida/feat-evm_testnet_non_local
Browse files Browse the repository at this point in the history
feat: adapt node manager `add` command for evm network
  • Loading branch information
jacderida authored Oct 15, 2024
2 parents 2a91e86 + eaee023 commit 00ad51d
Show file tree
Hide file tree
Showing 21 changed files with 1,764 additions and 60 deletions.
35 changes: 35 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions evm_testnet/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,11 @@ impl TestnetData {
}

let csv = format!(
"{},{},{}",
self.rpc_url, self.payment_token_address, self.data_payments_address
"{},{},{},{}",
self.rpc_url,
self.payment_token_address,
self.data_payments_address,
self.deployer_wallet_private_key
);
std::fs::write(&csv_path, csv).expect("Could not write to evm_testnet_data.csv file");
println!("EVM testnet data saved to: {csv_path:?}");
Expand Down
1 change: 1 addition & 0 deletions evmlib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ local = []
alloy = { version = "0.4.2", default-features = false, features = ["std", "reqwest-rustls-tls", "provider-anvil-node", "sol-types", "json", "signers", "contract", "signer-local", "network"] }
dirs-next = "~2.0.0"
serde = "1.0"
serde_with = { version = "3.11.0", features = ["macros"] }
thiserror = "1.0"
tracing = { version = "~0.1.26" }
tokio = "1.38.0"
Expand Down
17 changes: 15 additions & 2 deletions evmlib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use crate::common::{Address, QuoteHash, TxHash, U256};
use crate::transaction::verify_data_payment;
use alloy::primitives::address;
use alloy::transports::http::reqwest;
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DisplayFromStr};
use std::str::FromStr;
use std::sync::LazyLock;

Expand Down Expand Up @@ -38,8 +40,10 @@ const ARBITRUM_ONE_PAYMENT_TOKEN_ADDRESS: Address =
const ARBITRUM_ONE_DATA_PAYMENTS_ADDRESS: Address =
address!("887930F30EDEb1B255Cd2273C3F4400919df2EFe");

#[derive(Clone, Debug, PartialEq)]
#[serde_as]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct CustomNetwork {
#[serde_as(as = "DisplayFromStr")]
pub rpc_url_http: reqwest::Url,
pub payment_token_address: Address,
pub data_payments_address: Address,
Expand All @@ -57,12 +61,21 @@ impl CustomNetwork {
}
}

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Network {
ArbitrumOne,
Custom(CustomNetwork),
}

impl std::fmt::Display for Network {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Network::ArbitrumOne => write!(f, "evm-arbitrum-one"),
Network::Custom(_) => write!(f, "evm-custom"),
}
}
}

impl Network {
pub fn new_custom(rpc_url: &str, payment_token_addr: &str, chunk_payments_addr: &str) -> Self {
Self::Custom(CustomNetwork::new(
Expand Down
55 changes: 32 additions & 23 deletions evmlib/src/testnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,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 @@ -22,35 +23,32 @@ use alloy::transports::http::{Client, Http};

pub struct Testnet {
anvil: AnvilInstance,
rpc_url: Url,
network_token_address: Address,
data_payments_address: Address,
}

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,
rpc_url,
network_token_address: *network_token.contract.address(),
data_payments_address: *data_payments.contract.address(),
}
}

pub fn to_network(&self) -> Network {
let rpc_url = self
.anvil
.endpoint()
.parse()
.expect("Could not parse RPC URL");

Network::Custom(CustomNetwork {
rpc_url_http: rpc_url,
rpc_url_http: self.rpc_url.clone(),
payment_token_address: self.network_token_address,
data_payments_address: self.data_payments_address,
})
Expand All @@ -63,17 +61,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 a different address.
///
/// 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 @@ -95,18 +107,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 @@ -129,12 +140,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
2 changes: 1 addition & 1 deletion evmlib/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ fn local_evm_network_from_csv() -> Result<Network, Error> {
})?;
let parts: Vec<&str> = csv.split(',').collect();
match parts.as_slice() {
[rpc_url, payment_token_address, chunk_payments_address] => Ok(Network::Custom(
[rpc_url, payment_token_address, chunk_payments_address, _] => Ok(Network::Custom(
CustomNetwork::new(rpc_url, payment_token_address, chunk_payments_address),
)),
_ => {
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
1 change: 1 addition & 0 deletions node-launchpad/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.107"
signal-hook = "0.3.17"
sn_build_info = { path = "../sn_build_info", version = "0.1.15" }
sn_evm = { path = "../sn_evm", version = "0.1" }
sn-node-manager = { version = "0.10.6", path = "../sn_node_manager" }
sn_peers_acquisition = { version = "0.5.3", path = "../sn_peers_acquisition" }
sn_protocol = { path = "../sn_protocol", version = "0.17.11" }
Expand Down
15 changes: 7 additions & 8 deletions node-launchpad/src/node_mgmt.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
use std::path::PathBuf;

use crate::action::{Action, StatusActions};
use crate::connection_mode::ConnectionMode;
use color_eyre::eyre::{eyre, Error};
use sn_evm::RewardsAddress;
use sn_node_manager::{
add_services::config::PortRange, config::get_node_registry_path, VerbosityLevel,
};
use sn_peers_acquisition::PeersArgs;
use sn_releases::{self, ReleaseType, SafeReleaseRepoActions};
use sn_service_management::NodeRegistry;
use std::{path::PathBuf, str::FromStr};
use tokio::sync::mpsc::UnboundedSender;

use crate::action::{Action, StatusActions};

use crate::connection_mode::ConnectionMode;

use sn_releases::{self, ReleaseType, SafeReleaseRepoActions};

pub const PORT_MAX: u32 = 65535;
pub const PORT_MIN: u32 = 1024;

Expand Down Expand Up @@ -302,6 +299,7 @@ async fn scale_down_nodes(config: &NodeConfig, count: u16) {
None, // We don't care about the port, as we are scaling down
config.owner.clone(),
config.peers_args.clone(),
RewardsAddress::from_str("0x1111111111111111111111111111111111111111").unwrap(),
None,
None,
config.safenode_path.clone(),
Expand Down Expand Up @@ -375,6 +373,7 @@ async fn add_nodes(
port_range,
config.owner.clone(),
config.peers_args.clone(),
RewardsAddress::from_str("0x1111111111111111111111111111111111111111").unwrap(),
None,
None,
config.safenode_path.clone(),
Expand Down
1 change: 1 addition & 0 deletions sn_evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub use evmlib::utils::get_evm_network_from_env;
pub use evmlib::utils::{DATA_PAYMENTS_ADDRESS, PAYMENT_TOKEN_ADDRESS, RPC_URL};
pub use evmlib::wallet::Error as EvmWalletError;
pub use evmlib::wallet::Wallet as EvmWallet;
pub use evmlib::CustomNetwork;
pub use evmlib::Network as EvmNetwork;

mod amount;
Expand Down
Loading

0 comments on commit 00ad51d

Please sign in to comment.