Skip to content

Commit

Permalink
[CLI] Restructure local testnet code
Browse files Browse the repository at this point in the history
  • Loading branch information
banool committed Sep 29, 2023
1 parent ba8b1b2 commit 12597d6
Show file tree
Hide file tree
Showing 13 changed files with 575 additions and 317 deletions.
8 changes: 5 additions & 3 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ dirs = "5.0.1"
ed25519-dalek = { version = "1.0.1", features = ["std", "serde"] }
ed25519-dalek-bip32 = "0.2.0"
either = "1.6.1"
enum_dispatch = "0.3.8"
enum_dispatch = "0.3.12"
env_logger = "0.10.0"
erased-serde = "0.3.13"
event-listener = "2.5.3"
Expand Down
2 changes: 2 additions & 0 deletions crates/aptos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ dirs = { workspace = true }
futures = { workspace = true }
hex = { workspace = true }
itertools = { workspace = true }
maplit = { workspace = true }
move-binary-format = { workspace = true }
move-bytecode-source-map = { workspace = true }
move-cli = { workspace = true }
Expand Down Expand Up @@ -86,6 +87,7 @@ thiserror = { workspace = true }
tokio = { workspace = true }
toml = { workspace = true }
tonic = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
walkdir = { workspace = true }

Expand Down
7 changes: 4 additions & 3 deletions crates/aptos/e2e/cases/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ def test_account_create_and_transfer(run_helper: RunHelper, test_name=None):
raise TestError(
f"Account {OTHER_ACCOUNT_ONE.account_address} has balance {balance}, expected 0"
)

transfer_amount = 1000

run_helper.run_command(
test_name,
[
Expand All @@ -87,7 +87,7 @@ def test_account_create_and_transfer(run_helper: RunHelper, test_name=None):
raise TestError(
f"Account {OTHER_ACCOUNT_ONE.account_address} has balance {balance}, expected {transfer_amount}"
)


@test_case
def test_account_list(run_helper: RunHelper, test_name=None):
Expand Down Expand Up @@ -116,6 +116,7 @@ def test_account_list(run_helper: RunHelper, test_name=None):
"Cannot find the account in the account list after account creation"
)


@test_case
def test_account_lookup_address(run_helper: RunHelper, test_name=None):
# Create the new account.
Expand Down
48 changes: 27 additions & 21 deletions crates/aptos/e2e/local_testnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

# Run a local testnet in a docker container. We choose to detach here and we'll
# stop running it later using the container name.
def run_node(network: Network, image_repo_with_project: str):
def run_node(network: Network, image_repo_with_project: str, pull=True):
image_name = build_image_name(image_repo_with_project, network)
container_name = f"aptos-tools-{network}"
LOG.info(f"Trying to run aptos CLI local testnet from image: {image_name}")
Expand Down Expand Up @@ -43,28 +43,34 @@ def run_node(network: Network, image_repo_with_project: str):
if LOG.getEffectiveLevel() > 10:
kwargs = {**kwargs, **{"stdout": subprocess.PIPE, "stderr": subprocess.PIPE}}

args = [
"docker",
"run",
]

if pull:
args += ["--pull", "always"]

args += [
"--detach",
"--name",
container_name,
"-p",
f"{NODE_PORT}:{NODE_PORT}",
"-p",
f"{METRICS_PORT}:{METRICS_PORT}",
"-p",
f"{FAUCET_PORT}:{FAUCET_PORT}",
image_name,
"aptos",
"node",
"run-local-testnet",
"--with-faucet",
]

# Run the container.
subprocess.run(
[
"docker",
"run",
"--pull",
"always",
"--detach",
"--name",
container_name,
"-p",
f"{NODE_PORT}:{NODE_PORT}",
"-p",
f"{METRICS_PORT}:{METRICS_PORT}",
"-p",
f"{FAUCET_PORT}:{FAUCET_PORT}",
image_name,
"aptos",
"node",
"run-local-testnet",
"--with-faucet",
],
args,
**kwargs,
)

Expand Down
9 changes: 8 additions & 1 deletion crates/aptos/e2e/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ def parse_args():
default="/tmp/aptos-cli-tests",
help="Where we'll run CLI commands from (in the host system). Default: %(default)s",
)
parser.add_argument(
"--no-pull-always",
action="store_true",
help='If set, do not set "--pull always" when running the local testnet. Necessary for using local images.',
)
args = parser.parse_args()
return args

Expand Down Expand Up @@ -189,7 +194,9 @@ def main():
pathlib.Path(args.working_directory).mkdir(parents=True, exist_ok=True)

# Run a node + faucet and wait for them to start up.
container_name = run_node(args.base_network, args.image_repo_with_project)
container_name = run_node(
args.base_network, args.image_repo_with_project, not args.no_pull_always
)

# We run these in a try finally so that if something goes wrong, such as the
# local testnet not starting up correctly or some unexpected error in the
Expand Down
87 changes: 87 additions & 0 deletions crates/aptos/src/node/local_testnet/faucet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright © Aptos Foundation
// SPDX-License-Identifier: Apache-2.0

use super::{health_checker::HealthChecker, traits::ServiceManager, RunLocalTestnet};
use anyhow::Result;
use aptos_faucet_core::server::{FunderKeyEnum, RunConfig};
use async_trait::async_trait;
use clap::Parser;
use maplit::hashset;
use reqwest::Url;
use std::{collections::HashSet, path::PathBuf};

/// Args related to running a faucet in the local testnet.
#[derive(Debug, Parser)]
pub struct FaucetArgs {
/// Do not run a faucet alongside the node.
///
/// Running a faucet alongside the node allows you to create and fund accounts
/// for testing.
#[clap(long)]
pub no_faucet: bool,

/// This does nothing, we already run a faucet by default. We only keep this here
/// for backwards compatibility with tests. We will remove this once the commit
/// that added --no-faucet makes its way to the testnet branch.
#[clap(long, hide = true)]
pub with_faucet: bool,

/// Port to run the faucet on.
///
/// When running, you'll be able to use the faucet at `http://127.0.0.1:<port>/mint` e.g.
/// `http//127.0.0.1:8081/mint`
#[clap(long, default_value_t = 8081)]
pub faucet_port: u16,

/// Disable the delegation of faucet minting to a dedicated account.
#[clap(long)]
pub do_not_delegate: bool,
}

#[derive(Clone, Debug)]
pub struct FaucetManager {
config: RunConfig,
prerequisite_health_checkers: HashSet<HealthChecker>,
}

impl FaucetManager {
pub fn new(
args: &RunLocalTestnet,
prerequisite_health_checkers: HashSet<HealthChecker>,
test_dir: PathBuf,
node_api_url: Url,
) -> Result<Self> {
Ok(Self {
config: RunConfig::build_for_cli(
node_api_url.clone(),
args.faucet_args.faucet_port,
FunderKeyEnum::KeyFile(test_dir.join("mint.key")),
args.faucet_args.do_not_delegate,
None,
),
prerequisite_health_checkers,
})
}
}

#[async_trait]
impl ServiceManager for FaucetManager {
fn get_name(&self) -> String {
"Faucet".to_string()
}

fn get_healthchecks(&self) -> HashSet<HealthChecker> {
hashset! {HealthChecker::http_checker_from_port(
self.config.server_config.listen_port,
self.get_name(),
)}
}

fn get_prerequisite_health_checkers(&self) -> HashSet<&HealthChecker> {
self.prerequisite_health_checkers.iter().collect()
}

async fn run_service(self: Box<Self>) -> Result<()> {
self.config.run().await
}
}
28 changes: 23 additions & 5 deletions crates/aptos/src/node/local_testnet/health_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ const MAX_WAIT_S: u64 = 35;
const WAIT_INTERVAL_MS: u64 = 150;

/// This provides a single place to define a variety of different healthchecks.
#[derive(Clone, Debug, Serialize)]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize)]
pub enum HealthChecker {
/// Check that an HTTP API is up. The second param is the name of the HTTP service.
Http(Url, &'static str),
Http(Url, String),
/// Check that the node API is up. This is just a specific case of Http for extra
/// guarantees around liveliness.
NodeApi(Url),
Expand Down Expand Up @@ -100,6 +100,14 @@ impl HealthChecker {
HealthChecker::DataServiceGrpc(url) => url.as_str(),
}
}

/// Given a port, make an instance of HealthChecker::Http targeting 127.0.0.1.
pub fn http_checker_from_port(port: u16, name: String) -> Self {
Self::Http(
Url::parse(&format!("http://127.0.0.1:{}", port,)).unwrap(),
name,
)
}
}

impl std::fmt::Display for HealthChecker {
Expand All @@ -123,15 +131,25 @@ where
let start = Instant::now();
let mut started_successfully = false;

let mut last_error_message = None;
while start.elapsed() < max_wait {
if check_fn().await.is_ok() {
started_successfully = true;
break;
match check_fn().await {
Ok(_) => {
started_successfully = true;
break;
},
Err(err) => {
last_error_message = Some(format!("{:#}", err));
},
}
tokio::time::sleep(wait_interval).await
}

if !started_successfully {
let error_message = match last_error_message {
Some(last_error_message) => format!("{}: {}", error_message, last_error_message),
None => error_message,
};
return Err(CliError::UnexpectedError(error_message));
}

Expand Down

0 comments on commit 12597d6

Please sign in to comment.