From 7fdfc1658369f4f6400f0bfcccab05e8aff15884 Mon Sep 17 00:00:00 2001 From: Nurullah Giray Kuru Date: Mon, 7 Aug 2023 15:25:15 -0700 Subject: [PATCH] [api] Add individual step timing to api tester (#9502) This commit builds individual step timing on top of the consistent API testing introduced here. See proposal for more high level information. This addition allows us to dive deeper on what the issue is should we detect any flow is consistently slower. Changes: Add timer macro in macros.rs. Add helpers for emitting metrics and refactor process_result. Put publish_module in its own thread by creating a tokio runtime. Add sleeps between persistent checks. Reduce API client sleep time to 100ms from 500ms. Make test setups persistent. --- .dockerignore | 2 +- Cargo.lock | 3 +- crates/aptos-api-tester/Cargo.toml | 2 + crates/aptos-api-tester/src/consts.rs | 59 ++++ crates/aptos-api-tester/src/counters.rs | 19 ++ crates/aptos-api-tester/src/fail_message.rs | 27 -- crates/aptos-api-tester/src/macros.rs | 18 ++ crates/aptos-api-tester/src/main.rs | 135 +++----- .../aptos-api-tester/src/persistent_check.rs | 72 ++++- crates/aptos-api-tester/src/strings.rs | 55 ++++ .../src/tests/coin_transfer.rs | 148 ++++++--- crates/aptos-api-tester/src/tests/mod.rs | 2 +- .../aptos-api-tester/src/tests/new_account.rs | 116 +++---- .../src/tests/publish_module.rs | 169 +++++++--- .../{nft_transfer.rs => tokenv1_transfer.rs} | 270 +++++++++++----- .../aptos-api-tester/src/tokenv1_client.rs | 16 +- crates/aptos-api-tester/src/utils.rs | 300 +++++++++++++----- crates/aptos-rest-client/src/lib.rs | 1 + docker/builder/tools.Dockerfile | 5 +- sdk/Cargo.toml | 1 - sdk/src/lib.rs | 2 - 21 files changed, 965 insertions(+), 457 deletions(-) create mode 100644 crates/aptos-api-tester/src/consts.rs delete mode 100644 crates/aptos-api-tester/src/fail_message.rs create mode 100644 crates/aptos-api-tester/src/macros.rs create mode 100644 crates/aptos-api-tester/src/strings.rs rename crates/aptos-api-tester/src/tests/{nft_transfer.rs => tokenv1_transfer.rs} (65%) rename sdk/src/token_client.rs => crates/aptos-api-tester/src/tokenv1_client.rs (98%) diff --git a/.dockerignore b/.dockerignore index fdeaf611a8411..9cd118c7665ab 100644 --- a/.dockerignore +++ b/.dockerignore @@ -19,10 +19,10 @@ !**/*.mrb !**/*.errmap !config/src/config/test_data -!aptos-move/ !aptos-move/aptos-release-builder/data/release.yaml !aptos-move/aptos-release-builder/data/proposals/* !aptos-move/framework/ +!aptos-move/move-examples/hello_blockchain/ !crates/aptos/src/move_tool/*.bpl !crates/aptos-faucet/doc/ !api/doc/ diff --git a/Cargo.lock b/Cargo.lock index 68732be4d8744..23f528cbcca42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -430,6 +430,8 @@ dependencies = [ "once_cell", "prometheus", "rand 0.7.3", + "serde 1.0.149", + "serde_json", "tokio", "url", ] @@ -3115,7 +3117,6 @@ dependencies = [ "rand 0.7.3", "rand_core 0.5.1", "serde 1.0.149", - "serde_json", "tiny-bip39", "tokio", "url", diff --git a/crates/aptos-api-tester/Cargo.toml b/crates/aptos-api-tester/Cargo.toml index 01db4237b1caa..33177e2f18daa 100644 --- a/crates/aptos-api-tester/Cargo.toml +++ b/crates/aptos-api-tester/Cargo.toml @@ -28,5 +28,7 @@ move-core-types = { workspace = true } once_cell = { workspace = true } prometheus = { workspace = true } rand = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } tokio = { workspace = true } url = { workspace = true } diff --git a/crates/aptos-api-tester/src/consts.rs b/crates/aptos-api-tester/src/consts.rs new file mode 100644 index 0000000000000..1a6def38cc4d5 --- /dev/null +++ b/crates/aptos-api-tester/src/consts.rs @@ -0,0 +1,59 @@ +// Copyright © Aptos Foundation + +use once_cell::sync::Lazy; +use std::{env, time::Duration}; +use url::Url; + +// Node and faucet constants + +pub static DEVNET_NODE_URL: Lazy = + Lazy::new(|| Url::parse("https://fullnode.devnet.aptoslabs.com").unwrap()); + +pub static DEVNET_FAUCET_URL: Lazy = + Lazy::new(|| Url::parse("https://faucet.devnet.aptoslabs.com").unwrap()); + +pub static TESTNET_NODE_URL: Lazy = + Lazy::new(|| Url::parse("https://fullnode.testnet.aptoslabs.com").unwrap()); + +pub static TESTNET_FAUCET_URL: Lazy = + Lazy::new(|| Url::parse("https://faucet.testnet.aptoslabs.com").unwrap()); + +pub const FUND_AMOUNT: u64 = 100_000_000; + +// Persistency check constants + +// How long a persistent check runs for. +pub static PERSISTENCY_TIMEOUT: Lazy = Lazy::new(|| { + env::var("PERSISTENCY_TIMEOUT") + .ok() + .and_then(|s| s.parse().ok()) + .map(Duration::from_secs) + .unwrap_or(Duration::from_secs(30)) +}); + +// Wait time between tries during a persistent check. +pub static SLEEP_PER_CYCLE: Lazy = Lazy::new(|| { + env::var("SLEEP_PER_CYCLE") + .ok() + .and_then(|s| s.parse().ok()) + .map(Duration::from_millis) + .unwrap_or(Duration::from_millis(100)) +}); + +// Runtime constants + +// The number of threads to use for running tests. +pub static NUM_THREADS: Lazy = Lazy::new(|| { + env::var("NUM_THREADS") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(4) +}); + +// The size of the stack for each thread. +pub static STACK_SIZE: Lazy = Lazy::new(|| { + env::var("STACK_SIZE") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(4 * 1024 * 1024) +}); diff --git a/crates/aptos-api-tester/src/counters.rs b/crates/aptos-api-tester/src/counters.rs index 62441749d83a9..1f6305dd644b6 100644 --- a/crates/aptos-api-tester/src/counters.rs +++ b/crates/aptos-api-tester/src/counters.rs @@ -54,3 +54,22 @@ pub static API_TEST_LATENCY: Lazy = Lazy::new(|| { pub fn test_latency(test_name: &str, network_name: &str, run_id: &str, result: &str) -> Histogram { API_TEST_LATENCY.with_label_values(&[test_name, network_name, run_id, result]) } + +pub static API_TEST_STEP_LATENCY: Lazy = Lazy::new(|| { + register_histogram_vec!( + "api_test_step_latency", + "Time it takes to complete a user flow step", + &["test_name", "step_name", "network_name", "run_id", "result"], + ) + .unwrap() +}); + +pub fn test_step_latency( + test_name: &str, + step_name: &str, + network_name: &str, + run_id: &str, + result: &str, +) -> Histogram { + API_TEST_STEP_LATENCY.with_label_values(&[test_name, step_name, network_name, run_id, result]) +} diff --git a/crates/aptos-api-tester/src/fail_message.rs b/crates/aptos-api-tester/src/fail_message.rs deleted file mode 100644 index 5e271cc2147ca..0000000000000 --- a/crates/aptos-api-tester/src/fail_message.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright © Aptos Foundation - -pub static FAIL_WRONG_ACCOUNT_DATA: &str = "wrong account data"; -pub static FAIL_WRONG_BALANCE: &str = "wrong balance"; -pub static FAIL_WRONG_BALANCE_AT_VERSION: &str = "wrong balance at version"; -pub static FAIL_WRONG_COLLECTION_DATA: &str = "wrong collection data"; -pub static FAIL_WRONG_MESSAGE: &str = "wrong message"; -pub static FAIL_WRONG_MODULE: &str = "wrong module"; -pub static FAIL_WRONG_TOKEN_BALANCE: &str = "wrong token balance"; -pub static FAIL_WRONG_TOKEN_DATA: &str = "wrong token data"; -pub static ERROR_COULD_NOT_BUILD_PACKAGE: &str = "failed to build package"; -pub static ERROR_COULD_NOT_CHECK: &str = "persistency check never started"; -pub static ERROR_COULD_NOT_CREATE_ACCOUNT: &str = "failed to create account"; -pub static ERROR_COULD_NOT_CREATE_TRANSACTION: &str = "failed to create transaction"; -pub static ERROR_COULD_NOT_FINISH_TRANSACTION: &str = "failed to finish transaction"; -pub static ERROR_COULD_NOT_FUND_ACCOUNT: &str = "failed to fund account"; -pub static ERROR_COULD_NOT_SERIALIZE: &str = "failed to serialize"; -pub static ERROR_NO_ACCOUNT_DATA: &str = "can't find account data"; -pub static ERROR_NO_BALANCE: &str = "can't find account balance"; -pub static ERROR_NO_BYTECODE: &str = "can't find bytecode"; -pub static ERROR_NO_COLLECTION_DATA: &str = "can't find collection data"; -pub static ERROR_NO_MESSAGE: &str = "can't find message"; -pub static ERROR_NO_METADATA: &str = "can't find metadata"; -pub static ERROR_NO_MODULE: &str = "can't find module"; -pub static ERROR_NO_TOKEN_BALANCE: &str = "can't find token balance"; -pub static ERROR_NO_TOKEN_DATA: &str = "can't find token data"; -pub static ERROR_NO_VERSION: &str = "can't find transaction version"; diff --git a/crates/aptos-api-tester/src/macros.rs b/crates/aptos-api-tester/src/macros.rs new file mode 100644 index 0000000000000..f40d2fd093b58 --- /dev/null +++ b/crates/aptos-api-tester/src/macros.rs @@ -0,0 +1,18 @@ +// Copyright © Aptos Foundation + +#[macro_export] +macro_rules! time_fn { + ($func:expr, $($arg:expr), *) => {{ + // start timer + let start = tokio::time::Instant::now(); + + // call the flow + let result = $func($($arg),+).await; + + // end timer + let time = (tokio::time::Instant::now() - start).as_micros() as f64; + + // return + (result, time) + }}; +} diff --git a/crates/aptos-api-tester/src/main.rs b/crates/aptos-api-tester/src/main.rs index 8a555f112d916..5565476786576 100644 --- a/crates/aptos-api-tester/src/main.rs +++ b/crates/aptos-api-tester/src/main.rs @@ -3,135 +3,90 @@ #![forbid(unsafe_code)] +mod consts; mod counters; -mod fail_message; mod persistent_check; +mod strings; mod tests; +mod tokenv1_client; mod utils; +#[macro_use] +mod macros; -use crate::{ - tests::{coin_transfer, new_account, nft_transfer, publish_module}, - utils::{set_metrics, NetworkName, TestFailure, TestName, TestResult}, -}; +use crate::utils::{NetworkName, TestName}; use anyhow::Result; use aptos_logger::{info, Level, Logger}; use aptos_push_metrics::MetricsPusher; +use consts::{NUM_THREADS, STACK_SIZE}; use futures::future::join_all; -use std::{ - future::Future, - time::{Instant, SystemTime, UNIX_EPOCH}, -}; +use std::time::{SystemTime, UNIX_EPOCH}; +use tokio::runtime::{Builder, Runtime}; -// Processes a test result. -async fn process_result>>( - test_name: TestName, - network_name: NetworkName, - run_id: &str, - fut: Fut, -) { - // start timer - let start = Instant::now(); - - // call the flow - let result = fut.await; - - // end timer - let time = (Instant::now() - start).as_micros() as f64; - - // process the result - let output = match result { - Ok(_) => TestResult::Success, - Err(failure) => TestResult::from(failure), - }; - - // set metrics and log - set_metrics( - &output, - &test_name.to_string(), - &network_name.to_string(), - run_id, - time, - ); - info!( - "{} {} result:{:?} in time:{:?}", - network_name.to_string(), - test_name.to_string(), - output, - time, - ); -} - -async fn test_flows(network_name: NetworkName) -> Result<()> { +async fn test_flows(runtime: &Runtime, network_name: NetworkName) -> Result<()> { let run_id = SystemTime::now() .duration_since(UNIX_EPOCH)? .as_secs() .to_string(); - info!("testing {} at {}", network_name.to_string(), run_id); + info!( + "----- STARTING TESTS FOR {} WITH RUN ID {} -----", + network_name.to_string(), + run_id + ); - // Test new account creation and funding + // Flow 1: New account let test_time = run_id.clone(); - let handle_newaccount = tokio::spawn(async move { - process_result( - TestName::NewAccount, - network_name, - &test_time, - new_account::test(network_name), - ) - .await; + let handle_newaccount = runtime.spawn(async move { + TestName::NewAccount.run(network_name, &test_time).await; }); - // Flow 1: Coin transfer + // Flow 2: Coin transfer let test_time = run_id.clone(); - let handle_cointransfer = tokio::spawn(async move { - process_result( - TestName::CoinTransfer, - network_name, - &test_time, - coin_transfer::test(network_name), - ) - .await; + let handle_cointransfer = runtime.spawn(async move { + TestName::CoinTransfer.run(network_name, &test_time).await; }); - // Flow 2: NFT transfer + // Flow 3: NFT transfer let test_time = run_id.clone(); - let handle_nfttransfer = tokio::spawn(async move { - process_result( - TestName::NftTransfer, - network_name, - &test_time, - nft_transfer::test(network_name), - ) - .await; + let handle_nfttransfer = runtime.spawn(async move { + TestName::TokenV1Transfer + .run(network_name, &test_time) + .await; }); - // Flow 3: Publishing module + // Flow 4: Publishing module let test_time = run_id.clone(); - process_result( - TestName::PublishModule, - network_name, - &test_time, - publish_module::test(network_name), - ) - .await; + let handle_publishmodule = runtime.spawn(async move { + TestName::PublishModule.run(network_name, &test_time).await; + }); join_all(vec![ handle_newaccount, handle_cointransfer, handle_nfttransfer, + handle_publishmodule, ]) .await; Ok(()) } -#[tokio::main] -async fn main() -> Result<()> { +fn main() -> Result<()> { + // create runtime + let runtime = Builder::new_multi_thread() + .worker_threads(*NUM_THREADS) + .enable_all() + .thread_stack_size(*STACK_SIZE) + .build()?; + // log metrics Logger::builder().level(Level::Info).build(); let _mp = MetricsPusher::start_for_local_run("api-tester"); - // test flows - let _ = test_flows(NetworkName::Testnet).await; - let _ = test_flows(NetworkName::Devnet).await; + // run tests + // TODO: separate the running of the two networks + runtime.block_on(async { + let _ = test_flows(&runtime, NetworkName::Testnet).await; + let _ = test_flows(&runtime, NetworkName::Devnet).await; + }); Ok(()) } diff --git a/crates/aptos-api-tester/src/persistent_check.rs b/crates/aptos-api-tester/src/persistent_check.rs index 9e1873af2cc27..5a000c125ceee 100644 --- a/crates/aptos-api-tester/src/persistent_check.rs +++ b/crates/aptos-api-tester/src/persistent_check.rs @@ -1,16 +1,30 @@ // Copyright © Aptos Foundation -use crate::{fail_message::ERROR_COULD_NOT_CHECK, utils::TestFailure}; +// Persistent checking is a mechanism to increase tolerancy to eventual consistency issues. In our +// earlier tests we have observed that parallel runs of the flows returned higher failure rates +// than serial runs, and these extra failures displayed the following pattern: 1) the flow submits +// a transaction to the API (such as account creation), 2) the flow reads the state from the API, +// and gets a result that does not include the transaction. We attribute this to the second call +// ending up on a different node which is not yet up to sync. Therefore, for state checks, we +// repeat the whole check for a period of time until it is successful, and throw a failure only if +// it fails to succeed. Note that every time a check fails we will still get a failure log. + +// TODO: The need for having a different persistent check wrapper for each function signature is +// due to a lack of overloading in Rust. Consider using macros to reduce code duplication. + +use crate::{ + consts::{PERSISTENCY_TIMEOUT, SLEEP_PER_CYCLE}, + strings::ERROR_COULD_NOT_CHECK, + tokenv1_client::TokenClient, + utils::TestFailure, +}; use anyhow::anyhow; use aptos_api_types::HexEncodedBytes; use aptos_rest_client::Client; -use aptos_sdk::{token_client::TokenClient, types::LocalAccount}; +use aptos_sdk::types::LocalAccount; use aptos_types::account_address::AccountAddress; use futures::Future; -use std::time::Duration; -use tokio::time::Instant; - -static PERSISTENCY_TIMEOUT: Duration = Duration::from_secs(30); +use tokio::time::{sleep, Instant}; pub async fn account<'a, 'b, F, Fut>( step: &str, @@ -27,11 +41,12 @@ where let timer = Instant::now(); // try to get a good result - while Instant::now().duration_since(timer) < PERSISTENCY_TIMEOUT { + while Instant::now().duration_since(timer) < *PERSISTENCY_TIMEOUT { result = f(client, account).await; if result.is_ok() { break; } + sleep(*SLEEP_PER_CYCLE).await; } // return last failure if no good result occurs @@ -53,11 +68,40 @@ where let timer = Instant::now(); // try to get a good result - while Instant::now().duration_since(timer) < PERSISTENCY_TIMEOUT { + while Instant::now().duration_since(timer) < *PERSISTENCY_TIMEOUT { result = f(client, address).await; if result.is_ok() { break; } + sleep(*SLEEP_PER_CYCLE).await; + } + + // return last failure if no good result occurs + result +} + +pub async fn address_address<'a, F, Fut>( + step: &str, + f: F, + client: &'a Client, + address: AccountAddress, + address2: AccountAddress, +) -> Result<(), TestFailure> +where + F: Fn(&'a Client, AccountAddress, AccountAddress) -> Fut, + Fut: Future>, +{ + // set a default error in case checks never start + let mut result: Result<(), TestFailure> = Err(could_not_check(step)); + let timer = Instant::now(); + + // try to get a good result + while Instant::now().duration_since(timer) < *PERSISTENCY_TIMEOUT { + result = f(client, address, address2).await; + if result.is_ok() { + break; + } + sleep(*SLEEP_PER_CYCLE).await; } // return last failure if no good result occurs @@ -80,11 +124,12 @@ where let timer = Instant::now(); // try to get a good result - while Instant::now().duration_since(timer) < PERSISTENCY_TIMEOUT { + while Instant::now().duration_since(timer) < *PERSISTENCY_TIMEOUT { result = f(client, address, bytes).await; if result.is_ok() { break; } + sleep(*SLEEP_PER_CYCLE).await; } // return last failure if no good result occurs @@ -107,11 +152,12 @@ where let timer = Instant::now(); // try to get a good result - while Instant::now().duration_since(timer) < PERSISTENCY_TIMEOUT { + while Instant::now().duration_since(timer) < *PERSISTENCY_TIMEOUT { result = f(client, address, version).await; if result.is_ok() { break; } + sleep(*SLEEP_PER_CYCLE).await; } // return last failure if no good result occurs @@ -133,11 +179,12 @@ where let timer = Instant::now(); // try to get a good result - while Instant::now().duration_since(timer) < PERSISTENCY_TIMEOUT { + while Instant::now().duration_since(timer) < *PERSISTENCY_TIMEOUT { result = f(token_client, address).await; if result.is_ok() { break; } + sleep(*SLEEP_PER_CYCLE).await; } // return last failure if no good result occurs @@ -160,11 +207,12 @@ where let timer = Instant::now(); // try to get a good result - while Instant::now().duration_since(timer) < PERSISTENCY_TIMEOUT { + while Instant::now().duration_since(timer) < *PERSISTENCY_TIMEOUT { result = f(token_client, address, address2).await; if result.is_ok() { break; } + sleep(*SLEEP_PER_CYCLE).await; } // return last failure if no good result occurs diff --git a/crates/aptos-api-tester/src/strings.rs b/crates/aptos-api-tester/src/strings.rs new file mode 100644 index 0000000000000..998435cc06de6 --- /dev/null +++ b/crates/aptos-api-tester/src/strings.rs @@ -0,0 +1,55 @@ +// Copyright © Aptos Foundation + +// Fail messages + +pub const FAIL_WRONG_ACCOUNT_DATA: &str = "wrong account data"; +pub const FAIL_WRONG_BALANCE: &str = "wrong balance"; +pub const FAIL_WRONG_BALANCE_AT_VERSION: &str = "wrong balance at version"; +pub const FAIL_WRONG_COLLECTION_DATA: &str = "wrong collection data"; +pub const FAIL_WRONG_MESSAGE: &str = "wrong message"; +pub const FAIL_WRONG_MODULE: &str = "wrong module"; +pub const FAIL_WRONG_TOKEN_BALANCE: &str = "wrong token balance"; +pub const FAIL_WRONG_TOKEN_DATA: &str = "wrong token data"; + +// Error messages + +pub const ERROR_COULD_NOT_BUILD_PACKAGE: &str = "failed to build package"; +pub const ERROR_COULD_NOT_CHECK: &str = "persistency check never started"; +pub const ERROR_COULD_NOT_CREATE_ACCOUNT: &str = "failed to create account"; +pub const ERROR_COULD_NOT_CREATE_AND_SUBMIT_TRANSACTION: &str = + "failed to create and submit transaction"; +pub const ERROR_COULD_NOT_FINISH_TRANSACTION: &str = "failed to finish transaction"; +pub const ERROR_COULD_NOT_FUND_ACCOUNT: &str = "failed to fund account"; +pub const ERROR_COULD_NOT_SERIALIZE: &str = "failed to serialize"; +pub const ERROR_NO_ACCOUNT_DATA: &str = "can't find account data"; +pub const ERROR_NO_BALANCE: &str = "can't find account balance"; +pub const ERROR_NO_BYTECODE: &str = "can't find bytecode"; +pub const ERROR_NO_COLLECTION_DATA: &str = "can't find collection data"; +pub const ERROR_NO_MESSAGE: &str = "can't find message"; +pub const ERROR_NO_METADATA: &str = "can't find metadata"; +pub const ERROR_NO_MODULE: &str = "can't find module"; +pub const ERROR_NO_TOKEN_BALANCE: &str = "can't find token balance"; +pub const ERROR_NO_TOKEN_DATA: &str = "can't find token data"; +pub const ERROR_NO_VERSION: &str = "can't find transaction version"; + +// Step names + +pub const SETUP: &str = "setup"; +pub const CHECK_ACCOUNT_DATA: &str = "check_account_data"; +pub const FUND: &str = "fund"; +pub const CHECK_ACCOUNT_BALANCE: &str = "check_account_balance"; +pub const TRANSFER_COINS: &str = "transfer_coins"; +pub const CHECK_ACCOUNT_BALANCE_AT_VERSION: &str = "check_account_balance_at_version"; +pub const CREATE_COLLECTION: &str = "create_collection"; +pub const CHECK_COLLECTION_METADATA: &str = "check_collection_metadata"; +pub const CREATE_TOKEN: &str = "create_token"; +pub const CHECK_TOKEN_METADATA: &str = "check_token_metadata"; +pub const CHECK_SENDER_BALANCE: &str = "check_sender_balance"; +pub const OFFER_TOKEN: &str = "offer_token"; +pub const CLAIM_TOKEN: &str = "claim_token"; +pub const CHECK_RECEIVER_BALANCE: &str = "check_receiver_balance"; +pub const BUILD_MODULE: &str = "build_module"; +pub const PUBLISH_MODULE: &str = "publish_module"; +pub const CHECK_MODULE_DATA: &str = "check_module_data"; +pub const SET_MESSAGE: &str = "set_message"; +pub const CHECK_MESSAGE: &str = "check_message"; diff --git a/crates/aptos-api-tester/src/tests/coin_transfer.rs b/crates/aptos-api-tester/src/tests/coin_transfer.rs index 4a23fa331215b..3496a59ff662f 100644 --- a/crates/aptos-api-tester/src/tests/coin_transfer.rs +++ b/crates/aptos-api-tester/src/tests/coin_transfer.rs @@ -1,55 +1,104 @@ // Copyright © Aptos Foundation use crate::{ - fail_message::{ - ERROR_COULD_NOT_CREATE_ACCOUNT, ERROR_COULD_NOT_CREATE_TRANSACTION, + consts::FUND_AMOUNT, + persistent_check, + strings::{ + CHECK_ACCOUNT_BALANCE, CHECK_ACCOUNT_BALANCE_AT_VERSION, CHECK_ACCOUNT_DATA, + ERROR_COULD_NOT_CREATE_ACCOUNT, ERROR_COULD_NOT_CREATE_AND_SUBMIT_TRANSACTION, ERROR_COULD_NOT_FINISH_TRANSACTION, ERROR_COULD_NOT_FUND_ACCOUNT, ERROR_NO_BALANCE, - ERROR_NO_VERSION, FAIL_WRONG_BALANCE, FAIL_WRONG_BALANCE_AT_VERSION, + ERROR_NO_VERSION, FAIL_WRONG_BALANCE, FAIL_WRONG_BALANCE_AT_VERSION, SETUP, TRANSFER_COINS, }, - persistent_check, + time_fn, utils::{ - create_account, create_and_fund_account, get_client, get_faucet_client, NetworkName, - TestFailure, + check_balance, create_account, create_and_fund_account, emit_step_metrics, NetworkName, + TestFailure, TestName, }, }; use anyhow::{anyhow, Result}; use aptos_api_types::U64; -use aptos_logger::info; +use aptos_logger::error; use aptos_rest_client::Client; use aptos_sdk::{coin_client::CoinClient, types::LocalAccount}; use aptos_types::account_address::AccountAddress; -static TRANSFER_AMOUNT: u64 = 1_000; +const TRANSFER_AMOUNT: u64 = 1_000; /// Tests coin transfer. Checks that: /// - receiver balance reflects transferred amount /// - receiver balance shows correct amount at the previous version -pub async fn test(network_name: NetworkName) -> Result<(), TestFailure> { +pub async fn test(network_name: NetworkName, run_id: &str) -> Result<(), TestFailure> { // setup - let (client, mut account, receiver) = setup(network_name).await?; + let (client, mut account, receiver) = emit_step_metrics( + time_fn!(setup, network_name), + TestName::CoinTransfer, + SETUP, + network_name, + run_id, + )?; let coin_client = CoinClient::new(&client); + // persistently check that API returns correct account data (auth key and sequence number) + emit_step_metrics( + time_fn!( + persistent_check::address_address, + CHECK_ACCOUNT_DATA, + check_account_data, + &client, + account.address(), + receiver + ), + TestName::CoinTransfer, + CHECK_ACCOUNT_DATA, + network_name, + run_id, + )?; + // transfer coins to the receiver - let version = transfer_coins(&client, &coin_client, &mut account, receiver).await?; - - // check receiver balance persistently - persistent_check::address( - "check_account_balance", - check_account_balance, - &client, - receiver, - ) - .await?; - - // check receiver balance at previous version persistently - persistent_check::address_version( - "check_account_balance_at_version", - check_account_balance_at_version, - &client, - receiver, - version, - ) - .await?; + let version = emit_step_metrics( + time_fn!( + transfer_coins, + &client, + &coin_client, + &mut account, + receiver + ), + TestName::CoinTransfer, + TRANSFER_COINS, + network_name, + run_id, + )?; + + // persistently check that receiver balance is correct + emit_step_metrics( + time_fn!( + persistent_check::address, + CHECK_ACCOUNT_BALANCE, + check_account_balance, + &client, + receiver + ), + TestName::CoinTransfer, + CHECK_ACCOUNT_BALANCE, + network_name, + run_id, + )?; + + // persistently check that account balance is correct at previoud version + emit_step_metrics( + time_fn!( + persistent_check::address_version, + CHECK_ACCOUNT_BALANCE_AT_VERSION, + check_account_balance_at_version, + &client, + receiver, + version + ), + TestName::CoinTransfer, + CHECK_ACCOUNT_BALANCE_AT_VERSION, + network_name, + run_id, + )?; Ok(()) } @@ -60,14 +109,14 @@ async fn setup( network_name: NetworkName, ) -> Result<(Client, LocalAccount, AccountAddress), TestFailure> { // spin up clients - let client = get_client(network_name); - let faucet_client = get_faucet_client(network_name); + let client = network_name.get_client(); + let faucet_client = network_name.get_faucet_client(); // create account - let account = match create_and_fund_account(&faucet_client).await { + let account = match create_and_fund_account(&faucet_client, TestName::CoinTransfer).await { Ok(account) => account, Err(e) => { - info!( + error!( "test: coin_transfer part: setup ERROR: {}, with error {:?}", ERROR_COULD_NOT_FUND_ACCOUNT, e ); @@ -76,10 +125,10 @@ async fn setup( }; // create receiver - let receiver = match create_account(&faucet_client).await { + let receiver = match create_account(&faucet_client, TestName::CoinTransfer).await { Ok(account) => account.address(), Err(e) => { - info!( + error!( "test: coin_transfer part: setup ERROR: {}, with error {:?}", ERROR_COULD_NOT_CREATE_ACCOUNT, e ); @@ -90,6 +139,17 @@ async fn setup( Ok((client, account, receiver)) } +async fn check_account_data( + client: &Client, + account: AccountAddress, + receiver: AccountAddress, +) -> Result<(), TestFailure> { + check_balance(TestName::CoinTransfer, client, account, U64(FUND_AMOUNT)).await?; + check_balance(TestName::CoinTransfer, client, receiver, U64(0)).await?; + + Ok(()) +} + async fn transfer_coins( client: &Client, coin_client: &CoinClient<'_>, @@ -103,9 +163,9 @@ async fn transfer_coins( { Ok(pending_txn) => pending_txn, Err(e) => { - info!( + error!( "test: coin_transfer part: transfer_coins ERROR: {}, with error {:?}", - ERROR_COULD_NOT_CREATE_TRANSACTION, e + ERROR_COULD_NOT_CREATE_AND_SUBMIT_TRANSACTION, e ); return Err(e.into()); }, @@ -115,7 +175,7 @@ async fn transfer_coins( let response = match client.wait_for_transaction(&pending_txn).await { Ok(response) => response, Err(e) => { - info!( + error!( "test: coin_transfer part: transfer_coins ERROR: {}, with error {:?}", ERROR_COULD_NOT_FINISH_TRANSACTION, e ); @@ -126,7 +186,7 @@ async fn transfer_coins( let version = match response.inner().version() { Some(version) => version, None => { - info!( + error!( "test: coin_transfer part: transfer_coins ERROR: {}", ERROR_NO_VERSION ); @@ -149,7 +209,7 @@ async fn check_account_balance( let actual = match client.get_account_balance(address).await { Ok(response) => response.into_inner().coin.value, Err(e) => { - info!( + error!( "test: coin_transfer part: check_account_balance ERROR: {}, with error {:?}", ERROR_NO_BALANCE, e ); @@ -159,7 +219,7 @@ async fn check_account_balance( // compare if expected != actual { - info!( + error!( "test: coin_transfer part: check_account_balance FAIL: {}, expected {:?}, got {:?}", FAIL_WRONG_BALANCE, expected, actual ); @@ -184,7 +244,7 @@ async fn check_account_balance_at_version( { Ok(response) => response.into_inner().coin.value, Err(e) => { - info!( + error!( "test: coin_transfer part: check_account_balance_at_version ERROR: {}, with error {:?}", ERROR_NO_BALANCE, e ); @@ -194,7 +254,7 @@ async fn check_account_balance_at_version( // compare if expected != actual { - info!( + error!( "test: coin_transfer part: check_account_balance_at_version FAIL: {}, expected {:?}, got {:?}", FAIL_WRONG_BALANCE_AT_VERSION, expected, actual ); diff --git a/crates/aptos-api-tester/src/tests/mod.rs b/crates/aptos-api-tester/src/tests/mod.rs index e3251b0aeda8c..b82beb1942321 100644 --- a/crates/aptos-api-tester/src/tests/mod.rs +++ b/crates/aptos-api-tester/src/tests/mod.rs @@ -2,5 +2,5 @@ pub mod coin_transfer; pub mod new_account; -pub mod nft_transfer; pub mod publish_module; +pub mod tokenv1_transfer; diff --git a/crates/aptos-api-tester/src/tests/new_account.rs b/crates/aptos-api-tester/src/tests/new_account.rs index 4c1a557f00b4d..feff0153c74c1 100644 --- a/crates/aptos-api-tester/src/tests/new_account.rs +++ b/crates/aptos-api-tester/src/tests/new_account.rs @@ -1,42 +1,72 @@ // Copyright © Aptos Foundation use crate::{ - fail_message::{ - ERROR_COULD_NOT_CREATE_ACCOUNT, ERROR_COULD_NOT_FUND_ACCOUNT, ERROR_NO_ACCOUNT_DATA, - ERROR_NO_BALANCE, FAIL_WRONG_ACCOUNT_DATA, FAIL_WRONG_BALANCE, - }, + consts::FUND_AMOUNT, persistent_check, - utils::{create_account, get_client, get_faucet_client, NetworkName, TestFailure}, + strings::{ + CHECK_ACCOUNT_BALANCE, CHECK_ACCOUNT_DATA, ERROR_COULD_NOT_CREATE_ACCOUNT, + ERROR_COULD_NOT_FUND_ACCOUNT, ERROR_NO_ACCOUNT_DATA, FAIL_WRONG_ACCOUNT_DATA, FUND, SETUP, + }, + time_fn, + utils::{check_balance, create_account, emit_step_metrics, NetworkName, TestFailure, TestName}, }; use aptos_api_types::U64; -use aptos_logger::info; +use aptos_logger::error; use aptos_rest_client::{Account, Client, FaucetClient}; use aptos_sdk::types::LocalAccount; use aptos_types::account_address::AccountAddress; -static FUND_AMOUNT: u64 = 1_000_000; - /// Tests new account creation. Checks that: /// - account data exists /// - account balance reflects funded amount -pub async fn test(network_name: NetworkName) -> Result<(), TestFailure> { +pub async fn test(network_name: NetworkName, run_id: &str) -> Result<(), TestFailure> { // setup - let (client, faucet_client, account) = setup(network_name).await?; - - // check account data persistently - persistent_check::account("check_account_data", check_account_data, &client, &account).await?; + let (client, faucet_client, account) = emit_step_metrics( + time_fn!(setup, network_name), + TestName::NewAccount, + SETUP, + network_name, + run_id, + )?; + + // persistently check that API returns correct account data (auth key and sequence number) + emit_step_metrics( + time_fn!( + persistent_check::account, + CHECK_ACCOUNT_DATA, + check_account_data, + &client, + &account + ), + TestName::NewAccount, + CHECK_ACCOUNT_DATA, + network_name, + run_id, + )?; // fund account - fund(&faucet_client, account.address()).await?; - - // check account balance persistently - persistent_check::address( - "check_account_balance", - check_account_balance, - &client, - account.address(), - ) - .await?; + emit_step_metrics( + time_fn!(fund, &faucet_client, account.address()), + TestName::NewAccount, + FUND, + network_name, + run_id, + )?; + + // persistently check that account balance is correct + emit_step_metrics( + time_fn!( + persistent_check::address, + CHECK_ACCOUNT_BALANCE, + check_account_balance, + &client, + account.address() + ), + TestName::NewAccount, + CHECK_ACCOUNT_BALANCE, + network_name, + run_id, + )?; Ok(()) } @@ -47,14 +77,14 @@ async fn setup( network_name: NetworkName, ) -> Result<(Client, FaucetClient, LocalAccount), TestFailure> { // spin up clients - let client = get_client(network_name); - let faucet_client = get_faucet_client(network_name); + let client = network_name.get_client(); + let faucet_client = network_name.get_faucet_client(); // create account - let account = match create_account(&faucet_client).await { + let account = match create_account(&faucet_client, TestName::NewAccount).await { Ok(account) => account, Err(e) => { - info!( + error!( "test: new_account part: setup ERROR: {}, with error {:?}", ERROR_COULD_NOT_CREATE_ACCOUNT, e ); @@ -68,7 +98,7 @@ async fn setup( async fn fund(faucet_client: &FaucetClient, address: AccountAddress) -> Result<(), TestFailure> { // fund account if let Err(e) = faucet_client.fund(address, FUND_AMOUNT).await { - info!( + error!( "test: new_account part: fund ERROR: {}, with error {:?}", ERROR_COULD_NOT_FUND_ACCOUNT, e ); @@ -89,7 +119,7 @@ async fn check_account_data(client: &Client, account: &LocalAccount) -> Result<( let actual = match client.get_account(account.address()).await { Ok(response) => response.into_inner(), Err(e) => { - info!( + error!( "test: new_account part: check_account_data ERROR: {}, with error {:?}", ERROR_NO_ACCOUNT_DATA, e ); @@ -99,7 +129,7 @@ async fn check_account_data(client: &Client, account: &LocalAccount) -> Result<( // compare if expected != actual { - info!( + error!( "test: new_account part: check_account_data FAIL: {}, expected {:?}, got {:?}", FAIL_WRONG_ACCOUNT_DATA, expected, actual ); @@ -113,29 +143,5 @@ async fn check_account_balance( client: &Client, address: AccountAddress, ) -> Result<(), TestFailure> { - // expected - let expected = U64(FUND_AMOUNT); - - // actual - let actual = match client.get_account_balance(address).await { - Ok(response) => response.into_inner().coin.value, - Err(e) => { - info!( - "test: new_account part: check_account_balance ERROR: {}, with error {:?}", - ERROR_NO_BALANCE, e - ); - return Err(e.into()); - }, - }; - - // compare - if expected != actual { - info!( - "test: new_account part: check_account_balance FAIL: {}, expected {:?}, got {:?}", - FAIL_WRONG_BALANCE, expected, actual - ); - return Err(TestFailure::Fail(FAIL_WRONG_BALANCE)); - } - - Ok(()) + check_balance(TestName::NewAccount, client, address, U64(FUND_AMOUNT)).await } diff --git a/crates/aptos-api-tester/src/tests/publish_module.rs b/crates/aptos-api-tester/src/tests/publish_module.rs index 08e4653e357e7..68d96d0d0bf5a 100644 --- a/crates/aptos-api-tester/src/tests/publish_module.rs +++ b/crates/aptos-api-tester/src/tests/publish_module.rs @@ -1,26 +1,29 @@ // Copyright © Aptos Foundation use crate::{ - fail_message::{ - ERROR_COULD_NOT_BUILD_PACKAGE, ERROR_COULD_NOT_CREATE_TRANSACTION, + consts::FUND_AMOUNT, + persistent_check, + strings::{ + BUILD_MODULE, CHECK_ACCOUNT_DATA, CHECK_MESSAGE, CHECK_MODULE_DATA, + ERROR_COULD_NOT_BUILD_PACKAGE, ERROR_COULD_NOT_CREATE_AND_SUBMIT_TRANSACTION, ERROR_COULD_NOT_FINISH_TRANSACTION, ERROR_COULD_NOT_FUND_ACCOUNT, ERROR_COULD_NOT_SERIALIZE, ERROR_NO_BYTECODE, ERROR_NO_MESSAGE, ERROR_NO_METADATA, - ERROR_NO_MODULE, FAIL_WRONG_MESSAGE, FAIL_WRONG_MODULE, + ERROR_NO_MODULE, FAIL_WRONG_MESSAGE, FAIL_WRONG_MODULE, PUBLISH_MODULE, SETUP, SET_MESSAGE, + }, + time_fn, + tokenv1_client::{build_and_submit_transaction, TransactionOptions}, + utils::{ + check_balance, create_and_fund_account, emit_step_metrics, NetworkName, TestFailure, + TestName, }, - persistent_check, - utils::{create_and_fund_account, get_client, get_faucet_client, NetworkName, TestFailure}, }; use anyhow::{anyhow, Result}; -use aptos_api_types::HexEncodedBytes; +use aptos_api_types::{HexEncodedBytes, U64}; use aptos_cached_packages::aptos_stdlib::EntryFunctionCall; use aptos_framework::{BuildOptions, BuiltPackage}; -use aptos_logger::info; +use aptos_logger::error; use aptos_rest_client::Client; -use aptos_sdk::{ - bcs, - token_client::{build_and_submit_transaction, TransactionOptions}, - types::LocalAccount, -}; +use aptos_sdk::{bcs, types::LocalAccount}; use aptos_types::{ account_address::AccountAddress, transaction::{EntryFunction, TransactionPayload}, @@ -31,31 +34,93 @@ use std::{collections::BTreeMap, path::PathBuf}; static MODULE_NAME: &str = "message"; static MESSAGE: &str = "test message"; -pub async fn test(network_name: NetworkName) -> Result<(), TestFailure> { +/// Tests module publishing and interaction. Checks that: +/// - can publish module +/// - module data exists +/// - can interact with module +/// - interaction is reflected correctly +pub async fn test(network_name: NetworkName, run_id: &str) -> Result<(), TestFailure> { // setup - let (client, mut account) = setup(network_name).await?; + let (client, mut account) = emit_step_metrics( + time_fn!(setup, network_name), + TestName::PublishModule, + SETUP, + network_name, + run_id, + )?; + + // persistently check that API returns correct account data (auth key and sequence number) + emit_step_metrics( + time_fn!( + persistent_check::address, + CHECK_ACCOUNT_DATA, + check_account_data, + &client, + account.address() + ), + TestName::PublishModule, + CHECK_ACCOUNT_DATA, + network_name, + run_id, + )?; // build module - let package = build_module(account.address()).await?; + let package = emit_step_metrics( + time_fn!(build_module, account.address()), + TestName::PublishModule, + BUILD_MODULE, + network_name, + run_id, + )?; // publish module - let blob = publish_module(&client, &mut account, package).await?; - - // check module data persistently - persistent_check::address_bytes( - "check_module_data", - check_module_data, - &client, - account.address(), - &blob, - ) - .await?; + let blob = emit_step_metrics( + time_fn!(publish_module, &client, &mut account, package), + TestName::PublishModule, + PUBLISH_MODULE, + network_name, + run_id, + )?; + + // persistently check that API returns correct module package data + emit_step_metrics( + time_fn!( + persistent_check::address_bytes, + CHECK_MODULE_DATA, + check_module_data, + &client, + account.address(), + &blob + ), + TestName::PublishModule, + CHECK_MODULE_DATA, + network_name, + run_id, + )?; // set message - set_message(&client, &mut account).await?; - - // check message persistently - persistent_check::address("check_message", check_message, &client, account.address()).await?; + emit_step_metrics( + time_fn!(set_message, &client, &mut account), + TestName::PublishModule, + SET_MESSAGE, + network_name, + run_id, + )?; + + // persistently check that the message is correct + emit_step_metrics( + time_fn!( + persistent_check::address, + CHECK_MESSAGE, + check_message, + &client, + account.address() + ), + TestName::PublishModule, + CHECK_MESSAGE, + network_name, + run_id, + )?; Ok(()) } @@ -64,14 +129,14 @@ pub async fn test(network_name: NetworkName) -> Result<(), TestFailure> { async fn setup(network_name: NetworkName) -> Result<(Client, LocalAccount), TestFailure> { // spin up clients - let client = get_client(network_name); - let faucet_client = get_faucet_client(network_name); + let client = network_name.get_client(); + let faucet_client = network_name.get_faucet_client(); // create account - let account = match create_and_fund_account(&faucet_client).await { + let account = match create_and_fund_account(&faucet_client, TestName::PublishModule).await { Ok(account) => account, Err(e) => { - info!( + error!( "test: publish_module part: setup ERROR: {}, with error {:?}", ERROR_COULD_NOT_FUND_ACCOUNT, e ); @@ -82,6 +147,12 @@ async fn setup(network_name: NetworkName) -> Result<(Client, LocalAccount), Test Ok((client, account)) } +async fn check_account_data(client: &Client, account: AccountAddress) -> Result<(), TestFailure> { + check_balance(TestName::PublishModule, client, account, U64(FUND_AMOUNT)).await?; + + Ok(()) +} + async fn build_module(address: AccountAddress) -> Result { // get file to compile let move_dir = PathBuf::from("./aptos-move/move-examples/hello_blockchain"); @@ -100,7 +171,7 @@ async fn build_module(address: AccountAddress) -> Result package, Err(e) => { - info!( + error!( "test: publish_module part: publish_module ERROR: {}, with error {:?}", ERROR_COULD_NOT_BUILD_PACKAGE, e ); @@ -123,7 +194,7 @@ async fn publish_module( let metadata = match package.extract_metadata() { Ok(data) => data, Err(e) => { - info!( + error!( "test: publish_module part: publish_module ERROR: {}, with error {:?}", ERROR_NO_METADATA, e ); @@ -135,7 +206,7 @@ async fn publish_module( let metadata_serialized = match bcs::to_bytes(&metadata) { Ok(data) => data, Err(e) => { - info!( + error!( "test: publish_module part: publish_module ERROR: {}, with error {:?}", ERROR_COULD_NOT_SERIALIZE, e ); @@ -158,9 +229,9 @@ async fn publish_module( { Ok(txn) => txn, Err(e) => { - info!( + error!( "test: publish_module part: publish_module ERROR: {}, with error {:?}", - ERROR_COULD_NOT_CREATE_TRANSACTION, e + ERROR_COULD_NOT_CREATE_AND_SUBMIT_TRANSACTION, e ); return Err(e.into()); }, @@ -168,7 +239,7 @@ async fn publish_module( // wait for transaction to finish if let Err(e) = client.wait_for_transaction(&pending_txn).await { - info!( + error!( "test: publish_module part: publish_module ERROR: {}, with error {:?}", ERROR_COULD_NOT_FINISH_TRANSACTION, e ); @@ -179,7 +250,7 @@ async fn publish_module( let blob = match blobs.get(0) { Some(bytecode) => HexEncodedBytes::from(bytecode.clone()), None => { - info!( + error!( "test: publish_module part: publish_module ERROR: {}", ERROR_NO_BYTECODE ); @@ -199,7 +270,7 @@ async fn check_module_data( let response = match client.get_account_module(address, MODULE_NAME).await { Ok(response) => response, Err(e) => { - info!( + error!( "test: publish_module part: check_module_data ERROR: {}, with error {:?}", ERROR_NO_MODULE, e ); @@ -210,7 +281,7 @@ async fn check_module_data( // compare if expected != actual { - info!( + error!( "test: publish_module part: check_module_data FAIL: {}, expected {:?}, got {:?}", FAIL_WRONG_MODULE, expected, actual ); @@ -225,7 +296,7 @@ async fn set_message(client: &Client, account: &mut LocalAccount) -> Result<(), let message = match bcs::to_bytes(MESSAGE) { Ok(data) => data, Err(e) => { - info!( + error!( "test: publish_module part: set_message ERROR: {}, with error {:?}", ERROR_COULD_NOT_SERIALIZE, e ); @@ -248,9 +319,9 @@ async fn set_message(client: &Client, account: &mut LocalAccount) -> Result<(), { Ok(txn) => txn, Err(e) => { - info!( + error!( "test: publish_module part: set_message ERROR: {}, with error {:?}", - ERROR_COULD_NOT_CREATE_TRANSACTION, e + ERROR_COULD_NOT_CREATE_AND_SUBMIT_TRANSACTION, e ); return Err(e.into()); }, @@ -258,7 +329,7 @@ async fn set_message(client: &Client, account: &mut LocalAccount) -> Result<(), // wait for transaction to finish if let Err(e) = client.wait_for_transaction(&pending_txn).await { - info!( + error!( "test: publish_module part: set_message ERROR: {}, with error {:?}", ERROR_COULD_NOT_FINISH_TRANSACTION, e ); @@ -276,7 +347,7 @@ async fn check_message(client: &Client, address: AccountAddress) -> Result<(), T let actual = match get_message(client, address).await { Some(message) => message, None => { - info!( + error!( "test: publish_module part: check_message ERROR: {}", ERROR_NO_MESSAGE ); @@ -286,7 +357,7 @@ async fn check_message(client: &Client, address: AccountAddress) -> Result<(), T // compare if expected != actual { - info!( + error!( "test: publish_module part: check_message FAIL: {}, expected {:?}, got {:?}", FAIL_WRONG_MESSAGE, expected, actual ); diff --git a/crates/aptos-api-tester/src/tests/nft_transfer.rs b/crates/aptos-api-tester/src/tests/tokenv1_transfer.rs similarity index 65% rename from crates/aptos-api-tester/src/tests/nft_transfer.rs rename to crates/aptos-api-tester/src/tests/tokenv1_transfer.rs index 541966d703d42..a95272e59e6b4 100644 --- a/crates/aptos-api-tester/src/tests/nft_transfer.rs +++ b/crates/aptos-api-tester/src/tests/tokenv1_transfer.rs @@ -1,89 +1,176 @@ // Copyright © Aptos Foundation use crate::{ - fail_message::{ - ERROR_COULD_NOT_CREATE_TRANSACTION, ERROR_COULD_NOT_FINISH_TRANSACTION, + consts::FUND_AMOUNT, + persistent_check, + strings::{ + CHECK_ACCOUNT_DATA, CHECK_COLLECTION_METADATA, CHECK_RECEIVER_BALANCE, + CHECK_SENDER_BALANCE, CHECK_TOKEN_METADATA, CLAIM_TOKEN, CREATE_COLLECTION, CREATE_TOKEN, + ERROR_COULD_NOT_CREATE_AND_SUBMIT_TRANSACTION, ERROR_COULD_NOT_FINISH_TRANSACTION, ERROR_COULD_NOT_FUND_ACCOUNT, ERROR_NO_COLLECTION_DATA, ERROR_NO_TOKEN_BALANCE, ERROR_NO_TOKEN_DATA, FAIL_WRONG_COLLECTION_DATA, FAIL_WRONG_TOKEN_BALANCE, - FAIL_WRONG_TOKEN_DATA, + FAIL_WRONG_TOKEN_DATA, OFFER_TOKEN, SETUP, }, - persistent_check, - utils::{create_and_fund_account, get_client, get_faucet_client, NetworkName, TestFailure}, -}; -use aptos_api_types::U64; -use aptos_logger::info; -use aptos_rest_client::Client; -use aptos_sdk::{ - token_client::{ + time_fn, + tokenv1_client::{ CollectionData, CollectionMutabilityConfig, RoyaltyOptions, TokenClient, TokenData, TokenMutabilityConfig, }, - types::LocalAccount, + utils::{ + check_balance, create_and_fund_account, emit_step_metrics, NetworkName, TestFailure, + TestName, + }, }; +use aptos_api_types::U64; +use aptos_logger::error; +use aptos_rest_client::Client; +use aptos_sdk::types::LocalAccount; use aptos_types::account_address::AccountAddress; -static COLLECTION_NAME: &str = "test collection"; -static TOKEN_NAME: &str = "test token"; -static TOKEN_SUPPLY: u64 = 10; -static OFFER_AMOUNT: u64 = 2; +const COLLECTION_NAME: &str = "test collection"; +const TOKEN_NAME: &str = "test token"; +const TOKEN_SUPPLY: u64 = 10; +const OFFER_AMOUNT: u64 = 2; /// Tests nft transfer. Checks that: /// - collection data exists /// - token data exists /// - token balance reflects transferred amount -pub async fn test(network_name: NetworkName) -> Result<(), TestFailure> { +pub async fn test(network_name: NetworkName, run_id: &str) -> Result<(), TestFailure> { // setup - let (client, mut account, mut receiver) = setup(network_name).await?; + let (client, mut account, mut receiver) = emit_step_metrics( + time_fn!(setup, network_name), + TestName::TokenV1Transfer, + SETUP, + network_name, + run_id, + )?; let token_client = TokenClient::new(&client); + // persistently check that API returns correct account data (auth key and sequence number) + emit_step_metrics( + time_fn!( + persistent_check::address_address, + CHECK_ACCOUNT_DATA, + check_account_data, + &client, + account.address(), + receiver.address() + ), + TestName::TokenV1Transfer, + CHECK_ACCOUNT_DATA, + network_name, + run_id, + )?; + // create collection - create_collection(&client, &token_client, &mut account).await?; - - // check collection metadata persistently - persistent_check::token_address( - "check_collection_metadata", - check_collection_metadata, - &token_client, - account.address(), - ) - .await?; + emit_step_metrics( + time_fn!(create_collection, &client, &token_client, &mut account), + TestName::TokenV1Transfer, + CREATE_COLLECTION, + network_name, + run_id, + )?; + + // persistently check that API returns correct collection metadata + emit_step_metrics( + time_fn!( + persistent_check::token_address, + CHECK_COLLECTION_METADATA, + check_collection_metadata, + &token_client, + account.address() + ), + TestName::TokenV1Transfer, + CHECK_COLLECTION_METADATA, + network_name, + run_id, + )?; // create token - create_token(&client, &token_client, &mut account).await?; - - // check token metadata persistently - persistent_check::token_address( - "check_token_metadata", - check_token_metadata, - &token_client, - account.address(), - ) - .await?; + emit_step_metrics( + time_fn!(create_token, &client, &token_client, &mut account), + TestName::TokenV1Transfer, + CREATE_TOKEN, + network_name, + run_id, + )?; + + // persistently check that API returns correct token metadata + emit_step_metrics( + time_fn!( + persistent_check::token_address, + CHECK_TOKEN_METADATA, + check_token_metadata, + &token_client, + account.address() + ), + TestName::TokenV1Transfer, + CHECK_TOKEN_METADATA, + network_name, + run_id, + )?; // offer token - offer_token(&client, &token_client, &mut account, receiver.address()).await?; - - // check senders balance persistently - persistent_check::token_address( - "check_sender_balance", - check_sender_balance, - &token_client, - account.address(), - ) - .await?; + emit_step_metrics( + time_fn!( + offer_token, + &client, + &token_client, + &mut account, + receiver.address() + ), + TestName::TokenV1Transfer, + OFFER_TOKEN, + network_name, + run_id, + )?; + + // persistently check that sender token balance is correct + emit_step_metrics( + time_fn!( + persistent_check::token_address, + CHECK_SENDER_BALANCE, + check_sender_balance, + &token_client, + account.address() + ), + TestName::TokenV1Transfer, + CHECK_SENDER_BALANCE, + network_name, + run_id, + )?; // claim token - claim_token(&client, &token_client, &mut receiver, account.address()).await?; - - // check receivers balance persistently - persistent_check::token_address_address( - "check_receiver_balance", - check_receiver_balance, - &token_client, - receiver.address(), - account.address(), - ) - .await?; + emit_step_metrics( + time_fn!( + claim_token, + &client, + &token_client, + &mut receiver, + account.address() + ), + TestName::TokenV1Transfer, + CLAIM_TOKEN, + network_name, + run_id, + )?; + + // persistently check that receiver token balance is correct + emit_step_metrics( + time_fn!( + persistent_check::token_address_address, + CHECK_RECEIVER_BALANCE, + check_receiver_balance, + &token_client, + receiver.address(), + account.address() + ), + TestName::TokenV1Transfer, + CHECK_RECEIVER_BALANCE, + network_name, + run_id, + )?; Ok(()) } @@ -94,14 +181,14 @@ async fn setup( network_name: NetworkName, ) -> Result<(Client, LocalAccount, LocalAccount), TestFailure> { // spin up clients - let client = get_client(network_name); - let faucet_client = get_faucet_client(network_name); + let client = network_name.get_client(); + let faucet_client = network_name.get_faucet_client(); // create account - let account = match create_and_fund_account(&faucet_client).await { + let account = match create_and_fund_account(&faucet_client, TestName::TokenV1Transfer).await { Ok(account) => account, Err(e) => { - info!( + error!( "test: nft_transfer part: setup ERROR: {}, with error {:?}", ERROR_COULD_NOT_FUND_ACCOUNT, e ); @@ -110,10 +197,10 @@ async fn setup( }; // create receiver - let receiver = match create_and_fund_account(&faucet_client).await { + let receiver = match create_and_fund_account(&faucet_client, TestName::TokenV1Transfer).await { Ok(receiver) => receiver, Err(e) => { - info!( + error!( "test: nft_transfer part: setup ERROR: {}, with error {:?}", ERROR_COULD_NOT_FUND_ACCOUNT, e ); @@ -124,6 +211,23 @@ async fn setup( Ok((client, account, receiver)) } +async fn check_account_data( + client: &Client, + account: AccountAddress, + receiver: AccountAddress, +) -> Result<(), TestFailure> { + check_balance(TestName::TokenV1Transfer, client, account, U64(FUND_AMOUNT)).await?; + check_balance( + TestName::TokenV1Transfer, + client, + receiver, + U64(FUND_AMOUNT), + ) + .await?; + + Ok(()) +} + async fn create_collection( client: &Client, token_client: &TokenClient<'_>, @@ -146,9 +250,9 @@ async fn create_collection( { Ok(txn) => txn, Err(e) => { - info!( + error!( "test: nft_transfer part: create_collection ERROR: {}, with error {:?}", - ERROR_COULD_NOT_CREATE_TRANSACTION, e + ERROR_COULD_NOT_CREATE_AND_SUBMIT_TRANSACTION, e ); return Err(e.into()); }, @@ -156,7 +260,7 @@ async fn create_collection( // wait for transaction to finish if let Err(e) = client.wait_for_transaction(&pending_txn).await { - info!( + error!( "test: nft_transfer part: create_collection ERROR: {}, with error {:?}", ERROR_COULD_NOT_FINISH_TRANSACTION, e ); @@ -183,7 +287,7 @@ async fn check_collection_metadata( { Ok(data) => data, Err(e) => { - info!( + error!( "test: nft_transfer part: check_collection_metadata ERROR: {}, with error {:?}", ERROR_NO_COLLECTION_DATA, e ); @@ -193,7 +297,7 @@ async fn check_collection_metadata( // compare if expected != actual { - info!( + error!( "test: nft_transfer part: check_collection_metadata FAIL: {}, expected {:?}, got {:?}", FAIL_WRONG_COLLECTION_DATA, expected, actual ); @@ -228,9 +332,9 @@ async fn create_token( { Ok(txn) => txn, Err(e) => { - info!( + error!( "test: nft_transfer part: create_token ERROR: {}, with error {:?}", - ERROR_COULD_NOT_CREATE_TRANSACTION, e + ERROR_COULD_NOT_CREATE_AND_SUBMIT_TRANSACTION, e ); return Err(e.into()); }, @@ -238,7 +342,7 @@ async fn create_token( // wait for transaction to finish if let Err(e) = client.wait_for_transaction(&pending_txn).await { - info!( + error!( "test: nft_transfer part: create_token ERROR: {}, with error {:?}", ERROR_COULD_NOT_FINISH_TRANSACTION, e ); @@ -265,7 +369,7 @@ async fn check_token_metadata( { Ok(data) => data, Err(e) => { - info!( + error!( "test: nft_transfer part: check_token_metadata ERROR: {}, with error {:?}", ERROR_NO_TOKEN_DATA, e ); @@ -275,7 +379,7 @@ async fn check_token_metadata( // compare if expected != actual { - info!( + error!( "test: nft_transfer part: check_token_metadata FAIL: {}, expected {:?}, got {:?}", FAIL_WRONG_TOKEN_DATA, expected, actual ); @@ -307,9 +411,9 @@ async fn offer_token( { Ok(txn) => txn, Err(e) => { - info!( + error!( "test: nft_transfer part: offer_token ERROR: {}, with error {:?}", - ERROR_COULD_NOT_CREATE_TRANSACTION, e + ERROR_COULD_NOT_CREATE_AND_SUBMIT_TRANSACTION, e ); return Err(e.into()); }, @@ -317,7 +421,7 @@ async fn offer_token( // wait for transaction to finish if let Err(e) = client.wait_for_transaction(&pending_txn).await { - info!( + error!( "test: nft_transfer part: offer_token ERROR: {}, with error {:?}", ERROR_COULD_NOT_FINISH_TRANSACTION, e ); @@ -362,9 +466,9 @@ async fn claim_token( { Ok(txn) => txn, Err(e) => { - info!( + error!( "test: nft_transfer part: claim_token ERROR: {}, with error {:?}", - ERROR_COULD_NOT_CREATE_TRANSACTION, e + ERROR_COULD_NOT_CREATE_AND_SUBMIT_TRANSACTION, e ); return Err(e.into()); }, @@ -372,7 +476,7 @@ async fn claim_token( // wait for transaction to finish if let Err(e) = client.wait_for_transaction(&pending_txn).await { - info!( + error!( "test: nft_transfer part: claim_token ERROR: {}, with error {:?}", ERROR_COULD_NOT_FINISH_TRANSACTION, e ); @@ -451,7 +555,7 @@ async fn check_token_balance( { Ok(data) => data.amount, Err(e) => { - info!( + error!( "test: nft_transfer part: {} ERROR: {}, with error {:?}", part, ERROR_NO_TOKEN_BALANCE, e ); @@ -461,7 +565,7 @@ async fn check_token_balance( // compare if expected != actual { - info!( + error!( "test: nft_transfer part: {} FAIL: {}, expected {:?}, got {:?}", part, FAIL_WRONG_TOKEN_BALANCE, expected, actual ); diff --git a/sdk/src/token_client.rs b/crates/aptos-api-tester/src/tokenv1_client.rs similarity index 98% rename from sdk/src/token_client.rs rename to crates/aptos-api-tester/src/tokenv1_client.rs index 0d4f05d8470d9..7ef4f3c25b03b 100644 --- a/sdk/src/token_client.rs +++ b/crates/aptos-api-tester/src/tokenv1_client.rs @@ -1,15 +1,19 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{ - rest_client::{Client as ApiClient, PendingTransaction}, - transaction_builder::TransactionFactory, - types::{account_address::AccountAddress, chain_id::ChainId, LocalAccount}, -}; +// TODO: this should be part of the SDK + use anyhow::{anyhow, Context, Result}; use aptos_api_types::U64; use aptos_cached_packages::aptos_token_sdk_builder::EntryFunctionCall; -use aptos_types::transaction::TransactionPayload; +use aptos_sdk::{ + rest_client::{Client as ApiClient, PendingTransaction}, + transaction_builder::TransactionFactory, + types::LocalAccount, +}; +use aptos_types::{ + account_address::AccountAddress, chain_id::ChainId, transaction::TransactionPayload, +}; use serde::{Deserialize, Serialize}; /// Gets chain ID for use in submitting transactions. diff --git a/crates/aptos-api-tester/src/utils.rs b/crates/aptos-api-tester/src/utils.rs index eb85d94578002..fd7e854c8ea68 100644 --- a/crates/aptos-api-tester/src/utils.rs +++ b/crates/aptos-api-tester/src/utils.rs @@ -1,42 +1,29 @@ // Copyright © Aptos Foundation -use crate::counters::{test_error, test_fail, test_latency, test_success}; +use crate::{ + consts::{ + DEVNET_FAUCET_URL, DEVNET_NODE_URL, FUND_AMOUNT, TESTNET_FAUCET_URL, TESTNET_NODE_URL, + }, + counters::{test_error, test_fail, test_latency, test_step_latency, test_success}, + strings::{ERROR_NO_BALANCE, FAIL_WRONG_BALANCE}, + tests::{coin_transfer, new_account, publish_module, tokenv1_transfer}, + time_fn, +}; use anyhow::Result; +use aptos_api_types::U64; +use aptos_logger::{error, info}; use aptos_rest_client::{error::RestError, Client, FaucetClient}; use aptos_sdk::types::LocalAccount; -use once_cell::sync::Lazy; +use aptos_types::account_address::AccountAddress; use std::env; -use url::Url; - -// network urls -pub static DEVNET_NODE_URL: Lazy = - Lazy::new(|| Url::parse("https://fullnode.devnet.aptoslabs.com").unwrap()); -pub static DEVNET_FAUCET_URL: Lazy = - Lazy::new(|| Url::parse("https://faucet.devnet.aptoslabs.com").unwrap()); -pub static TESTNET_NODE_URL: Lazy = - Lazy::new(|| Url::parse("https://fullnode.testnet.aptoslabs.com").unwrap()); -pub static TESTNET_FAUCET_URL: Lazy = - Lazy::new(|| Url::parse("https://faucet.testnet.aptoslabs.com").unwrap()); -#[derive(Debug)] -pub enum TestResult { - Success, - Fail(&'static str), - Error(anyhow::Error), -} - -impl From for TestResult { - fn from(f: TestFailure) -> TestResult { - match f { - TestFailure::Fail(f) => TestResult::Fail(f), - TestFailure::Error(e) => TestResult::Error(e), - } - } -} +// Test failure #[derive(Debug)] pub enum TestFailure { + // Variant for failed checks, e.g. wrong balance Fail(&'static str), + // Variant for test failures, e.g. client returns an error Error(anyhow::Error), } @@ -52,10 +39,13 @@ impl From for TestFailure { } } +// Test name + +#[derive(Clone, Copy)] pub enum TestName { NewAccount, CoinTransfer, - NftTransfer, + TokenV1Transfer, PublishModule, } @@ -64,12 +54,27 @@ impl ToString for TestName { match &self { TestName::NewAccount => "new_account".to_string(), TestName::CoinTransfer => "coin_transfer".to_string(), - TestName::NftTransfer => "nft_transfer".to_string(), + TestName::TokenV1Transfer => "tokenv1_transfer".to_string(), TestName::PublishModule => "publish_module".to_string(), } } } +impl TestName { + pub async fn run(&self, network_name: NetworkName, run_id: &str) { + let output = match &self { + TestName::NewAccount => time_fn!(new_account::test, network_name, run_id), + TestName::CoinTransfer => time_fn!(coin_transfer::test, network_name, run_id), + TestName::TokenV1Transfer => time_fn!(tokenv1_transfer::test, network_name, run_id), + TestName::PublishModule => time_fn!(publish_module::test, network_name, run_id), + }; + + emit_test_metrics(output, *self, network_name, run_id); + } +} + +// Network name + #[derive(Clone, Copy)] pub enum NetworkName { Testnet, @@ -85,73 +90,200 @@ impl ToString for NetworkName { } } -// Set metrics based on the result. -pub fn set_metrics( - output: &TestResult, - test_name: &str, - network_name: &str, - start_time: &str, - time: f64, -) { - match output { - TestResult::Success => { - test_success(test_name, network_name, start_time).observe(1_f64); - test_fail(test_name, network_name, start_time).observe(0_f64); - test_error(test_name, network_name, start_time).observe(0_f64); - test_latency(test_name, network_name, start_time, "success").observe(time); - }, - TestResult::Fail(_) => { - test_success(test_name, network_name, start_time).observe(0_f64); - test_fail(test_name, network_name, start_time).observe(1_f64); - test_error(test_name, network_name, start_time).observe(0_f64); - test_latency(test_name, network_name, start_time, "fail").observe(time); - }, - TestResult::Error(_) => { - test_success(test_name, network_name, start_time).observe(0_f64); - test_fail(test_name, network_name, start_time).observe(0_f64); - test_error(test_name, network_name, start_time).observe(1_f64); - test_latency(test_name, network_name, start_time, "error").observe(time); - }, +impl NetworkName { + /// Create a REST client. + pub fn get_client(&self) -> Client { + match self { + NetworkName::Testnet => Client::new(TESTNET_NODE_URL.clone()), + NetworkName::Devnet => Client::new(DEVNET_NODE_URL.clone()), + } } -} -// Create a REST client. -pub fn get_client(network_name: NetworkName) -> Client { - match network_name { - NetworkName::Testnet => Client::new(TESTNET_NODE_URL.clone()), - NetworkName::Devnet => Client::new(DEVNET_NODE_URL.clone()), + /// Create a faucet client. + pub fn get_faucet_client(&self) -> FaucetClient { + match self { + NetworkName::Testnet => { + let faucet_client = + FaucetClient::new(TESTNET_FAUCET_URL.clone(), TESTNET_NODE_URL.clone()); + match env::var("TESTNET_FAUCET_CLIENT_TOKEN") { + Ok(token) => faucet_client.with_auth_token(token), + Err(_) => faucet_client, + } + }, + NetworkName::Devnet => { + FaucetClient::new(DEVNET_FAUCET_URL.clone(), DEVNET_NODE_URL.clone()) + }, + } } } -// Create a faucet client. -pub fn get_faucet_client(network_name: NetworkName) -> FaucetClient { - match network_name { - NetworkName::Testnet => { - let faucet_client = - FaucetClient::new(TESTNET_FAUCET_URL.clone(), TESTNET_NODE_URL.clone()); - match env::var("TESTNET_FAUCET_CLIENT_TOKEN") { - Ok(token) => faucet_client.with_auth_token(token), - Err(_) => faucet_client, - } - }, - NetworkName::Devnet => { - FaucetClient::new(DEVNET_FAUCET_URL.clone(), DEVNET_NODE_URL.clone()) - }, - } -} +// Setup helpers -// Create an account with zero balance. -pub async fn create_account(faucet_client: &FaucetClient) -> Result { +/// Create an account with zero balance. +pub async fn create_account( + faucet_client: &FaucetClient, + test_name: TestName, +) -> Result { let account = LocalAccount::generate(&mut rand::rngs::OsRng); faucet_client.create_account(account.address()).await?; + info!( + "CREATED ACCOUNT {} for test: {}", + account.address(), + test_name.to_string() + ); Ok(account) } -// Create an account with 100_000_000 balance. -pub async fn create_and_fund_account(faucet_client: &FaucetClient) -> Result { +/// Create an account with 100_000_000 balance. +pub async fn create_and_fund_account( + faucet_client: &FaucetClient, + test_name: TestName, +) -> Result { let account = LocalAccount::generate(&mut rand::rngs::OsRng); - faucet_client.fund(account.address(), 100_000_000).await?; + faucet_client.fund(account.address(), FUND_AMOUNT).await?; + info!( + "CREATED ACCOUNT {} for test: {}", + account.address(), + test_name.to_string() + ); Ok(account) } + +/// Check account balance. +pub async fn check_balance( + test_name: TestName, + client: &Client, + address: AccountAddress, + expected: U64, +) -> Result<(), TestFailure> { + // actual + let actual = match client.get_account_balance(address).await { + Ok(response) => response.into_inner().coin.value, + Err(e) => { + error!( + "test: {} part: check_account_data ERROR: {}, with error {:?}", + &test_name.to_string(), + ERROR_NO_BALANCE, + e + ); + return Err(e.into()); + }, + }; + + // compare + if expected != actual { + error!( + "test: {} part: check_account_data FAIL: {}, expected {:?}, got {:?}", + &test_name.to_string(), + FAIL_WRONG_BALANCE, + expected, + actual + ); + return Err(TestFailure::Fail(FAIL_WRONG_BALANCE)); + } + + Ok(()) +} + +// Metrics helpers + +/// Emit metrics based on test result. +pub fn emit_test_metrics( + output: (Result<(), TestFailure>, f64), + test_name: TestName, + network_name: NetworkName, + run_id: &str, +) { + // deconstruct + let (result, time) = output; + + // emit success rate and get result word + let result_label = match result { + Ok(_) => { + test_success(&test_name.to_string(), &network_name.to_string(), run_id).observe(1_f64); + test_fail(&test_name.to_string(), &network_name.to_string(), run_id).observe(0_f64); + test_error(&test_name.to_string(), &network_name.to_string(), run_id).observe(0_f64); + + "success" + }, + Err(e) => match e { + TestFailure::Fail(_) => { + test_success(&test_name.to_string(), &network_name.to_string(), run_id) + .observe(0_f64); + test_fail(&test_name.to_string(), &network_name.to_string(), run_id).observe(1_f64); + test_error(&test_name.to_string(), &network_name.to_string(), run_id) + .observe(0_f64); + + "fail" + }, + TestFailure::Error(_) => { + test_success(&test_name.to_string(), &network_name.to_string(), run_id) + .observe(0_f64); + test_fail(&test_name.to_string(), &network_name.to_string(), run_id).observe(0_f64); + test_error(&test_name.to_string(), &network_name.to_string(), run_id) + .observe(1_f64); + + "error" + }, + }, + }; + + // log result + info!( + "----- TEST FINISHED test: {} result: {} time: {} -----", + test_name.to_string(), + result_label, + time, + ); + + // emit latency + test_latency( + &test_name.to_string(), + &network_name.to_string(), + run_id, + result_label, + ) + .observe(time); +} + +/// Emit metrics based on result. +pub fn emit_step_metrics( + output: (Result, f64), + test_name: TestName, + step_name: &str, + network_name: NetworkName, + run_id: &str, +) -> Result { + // deconstruct and get result word + let (result, time) = output; + let result_label = match &result { + Ok(_) => "success", + Err(e) => match e { + TestFailure::Fail(_) => "fail", + TestFailure::Error(_) => "error", + }, + }; + + // log result + info!( + "STEP FINISHED test: {} step: {} result: {} time: {}", + test_name.to_string(), + step_name, + result_label, + time, + ); + + // emit latency + test_step_latency( + &test_name.to_string(), + step_name, + &network_name.to_string(), + run_id, + result_label, + ) + .observe(time); + + result +} diff --git a/crates/aptos-rest-client/src/lib.rs b/crates/aptos-rest-client/src/lib.rs index 1a6f653636f47..996ce2a5b9354 100644 --- a/crates/aptos-rest-client/src/lib.rs +++ b/crates/aptos-rest-client/src/lib.rs @@ -566,6 +566,7 @@ impl Client { F: Fn(HashValue) -> Fut, Fut: Future>>, { + // TODO: make this configurable const DEFAULT_DELAY: Duration = Duration::from_millis(500); let mut reached_mempool = false; let start = std::time::Instant::now(); diff --git a/docker/builder/tools.Dockerfile b/docker/builder/tools.Dockerfile index 043f4c9c11ce3..ff268ea05d3c7 100644 --- a/docker/builder/tools.Dockerfile +++ b/docker/builder/tools.Dockerfile @@ -34,7 +34,10 @@ COPY --link --from=tools-builder /aptos/dist/aptos-transaction-emitter /usr/loca COPY --link --from=tools-builder /aptos/dist/aptos-api-tester /usr/local/bin/aptos-api-tester # Copy the example module to publish for api-tester -COPY --link --from=tools-builder /aptos/aptos-move /aptos-move +COPY --link --from=tools-builder /aptos/aptos-move/framework/aptos-framework /aptos-move/framework/aptos-framework +COPY --link --from=tools-builder /aptos/aptos-move/framework/aptos-stdlib /aptos-move/framework/aptos-stdlib +COPY --link --from=tools-builder /aptos/aptos-move/framework/move-stdlib /aptos-move/framework/move-stdlib +COPY --link --from=tools-builder /aptos/aptos-move/move-examples/hello_blockchain /aptos-move/move-examples/hello_blockchain ### Get Aptos Move releases for genesis ceremony RUN mkdir -p /aptos-framework/move diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index aeaa0df01242f..0f326eb95452b 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -25,7 +25,6 @@ ed25519-dalek-bip32 = { workspace = true } move-core-types = { workspace = true } rand_core = { workspace = true } serde = { workspace = true } -serde_json = { workspace = true } tiny-bip39 = { workspace = true } [dev-dependencies] diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index dab8f30a32b7c..4fad517174074 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -24,8 +24,6 @@ pub use bcs; pub mod coin_client; -pub mod token_client; - pub mod crypto { pub use aptos_crypto::*; }