From 1de250f591f0bd70255bb785f721021a6fbcf950 Mon Sep 17 00:00:00 2001 From: Zekun Li Date: Sun, 20 Mar 2022 21:24:39 -0700 Subject: [PATCH] [AptosFramework] migrate forge tests Closes: #260 --- Cargo.lock | 3 + api/src/tests/transactions_test.rs | 10 +- crates/aptos-rest-client/src/aptos.rs | 26 ++++ crates/aptos-rest-client/src/lib.rs | 51 ++++++- crates/aptos-rest-client/src/types.rs | 2 +- crates/transaction-emitter/Cargo.toml | 1 + crates/transaction-emitter/src/lib.rs | 141 +++++++++--------- crates/transaction-emitter/src/main.rs | 82 ++-------- .../executor-benchmark/src/db_generator.rs | 5 +- scripts/fgi/run | 5 +- sdk/src/transaction_builder.rs | 2 +- testsuite/forge-cli/Cargo.toml | 2 + testsuite/forge-cli/src/main.rs | 101 ++++--------- .../forge/src/backend/k8s/cluster_helper.rs | 3 +- testsuite/forge/src/backend/k8s/swarm.rs | 21 +-- .../smoke-test/src/aptos/mint_transfer.rs | 8 + testsuite/smoke-test/src/fullnode.rs | 2 +- .../smoke-test/src/scripts_and_modules.rs | 6 +- testsuite/smoke-test/src/test_utils.rs | 4 +- testsuite/testcases/src/compatibility_test.rs | 8 +- testsuite/testcases/src/fixed_tps_test.rs | 2 +- testsuite/testcases/src/lib.rs | 7 +- .../testcases/src/partial_nodes_down_test.rs | 2 +- testsuite/testcases/src/performance_test.rs | 2 +- .../testcases/src/state_sync_performance.rs | 2 +- 25 files changed, 233 insertions(+), 265 deletions(-) create mode 100644 crates/aptos-rest-client/src/aptos.rs diff --git a/Cargo.lock b/Cargo.lock index 360e30225199e..22418cfa0e50a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3165,9 +3165,11 @@ name = "forge-cli" version = "0.0.0" dependencies = [ "anyhow", + "aptos-framework-releases", "aptos-rest-client", "aptos-sdk", "aptos-workspace-hack", + "async-trait", "forge", "itertools", "rand_core 0.6.3", @@ -8405,6 +8407,7 @@ dependencies = [ "aptos-logger", "aptos-rest-client", "aptos-sdk", + "aptos-transaction-builder", "aptos-workspace-hack", "futures", "generate-key", diff --git a/api/src/tests/transactions_test.rs b/api/src/tests/transactions_test.rs index 3189ae5952c51..14bba6ab013a6 100644 --- a/api/src/tests/transactions_test.rs +++ b/api/src/tests/transactions_test.rs @@ -319,7 +319,7 @@ async fn test_get_transactions_output_user_transaction_with_script_function_payl "vm_status": "Executed successfully", "sender": "0xb1e55ed", "sequence_number": "0", - "max_gas_amount": "1000000", + "max_gas_amount": "1000", "gas_unit_price": "0", "gas_currency_code": "XUS", "expiration_timestamp_secs": txn.expiration_timestamp_secs().to_string(), @@ -547,7 +547,7 @@ async fn test_post_bcs_format_transaction() { "hash": hash.to_hex_literal(), "sender": "0xb1e55ed", "sequence_number": "0", - "max_gas_amount": "1000000", + "max_gas_amount": "1000", "gas_unit_price": "0", "gas_currency_code": "XUS", "expiration_timestamp_secs": expiration_timestamp.to_string(), @@ -754,9 +754,9 @@ async fn test_multi_ed25519_signed_transaction() { "0xfe047a766a47719591348a4601afb3f38b0c77fa3f820e0298c064e7cde6763f" ], "signatures": [ - "0xab0ffa0926dd765979c422572b4429d11161a2df6975e223ad4d75c87a117e6c790558e8286caf95550ab97515d2cfa8654365f54524688df91b3b4e91b69d0e", - "0x300774b6dd50658d4b693ad5cc1842944465a92b31f1652b445d36b911d4ca625260c451ab7d998534b61253f3bfcdd6bcb03adf4c048b03bd18678d56cd5a03", - "0x4bac0f0d9dde41196efae43849f8e4427ee142e04e57e7291ecdfb225528b0fe31eff8e17461a220430daea94a14f750a37b5e0360aa1c72cb956c402743c202" + "0x51ba5206ec53806411fb67f67fe9adea1e3c90d3b3bd53985ba72cf9ea096489a489081036db3c91e24b01bed8fa2f0c082293236e3fa512218c910a23f7fe01", + "0xbaabf59869be9a12ef93e156c640cf38bd9a04d720aedb1e64faea259c532c68584fcc5444a90d9485bb3dc024c76bb7ec411ea83287823afc9453c711150a0c", + "0x96bf8311f06610aec340798c7bac2859d0b7778fad0b648b70ff4091f3147040ef5bc3a2fa10114b2593cf58b3100e276460630f37d948abd3214e2d13882604" ], "threshold": 3, "bitmap": "0xe0000000" diff --git a/crates/aptos-rest-client/src/aptos.rs b/crates/aptos-rest-client/src/aptos.rs new file mode 100644 index 0000000000000..382605f844a83 --- /dev/null +++ b/crates/aptos-rest-client/src/aptos.rs @@ -0,0 +1,26 @@ +// Copyright (c) Aptos +// SPDX-License-Identifier: Apache-2.0 + +use aptos_api_types::U64; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct TestCoin { + pub value: U64, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Balance { + pub coin: TestCoin, +} + +impl Balance { + pub fn get(&self) -> u64 { + *self.coin.value.inner() + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct AptosVersion { + major: U64, +} diff --git a/crates/aptos-rest-client/src/lib.rs b/crates/aptos-rest-client/src/lib.rs index 62be0ceb365d7..09756d4f195ba 100644 --- a/crates/aptos-rest-client/src/lib.rs +++ b/crates/aptos-rest-client/src/lib.rs @@ -6,8 +6,9 @@ pub use aptos_api_types::{MoveModuleBytecode, PendingTransaction, Transaction}; use aptos_crypto::HashValue; use aptos_types::{account_address::AccountAddress, transaction::SignedTransaction}; use move_core_types::{ + ident_str, identifier::Identifier, - language_storage::{StructTag, TypeTag}, + language_storage::{StructTag, TypeTag, CORE_CODE_ADDRESS}, move_resource::MoveStructType, }; use reqwest::{header::CONTENT_TYPE, Client as ReqwestClient, StatusCode}; @@ -16,6 +17,8 @@ use std::time::Duration; use url::Url; pub use aptos_api_types; +use aptos_types::account_config::aptos_root_address; + pub mod error; pub mod faucet; pub use faucet::FaucetClient; @@ -24,7 +27,10 @@ pub use response::Response; mod state; use state::State; pub mod types; -pub use types::{DiemAccount, Resource, RestError}; +use crate::aptos::{AptosVersion, Balance}; +pub use types::{Account, Resource, RestError}; + +pub mod aptos; macro_rules! cfg_dpn { ($($item:item)*) => { @@ -62,7 +68,7 @@ impl Client { } cfg_dpn! { - pub async fn get_account_balances( + pub async fn get_dpn_account_balances( &self, address: AccountAddress, ) -> Result>> { @@ -95,7 +101,7 @@ impl Client { } // Returns root account DiemAccount::Config resource - pub async fn get_aptos_version(&self) -> Result>> { + pub async fn get_dpn_version(&self) -> Result>> { self.get_resource::>(dpn::aptos_root_address(), &dpn::diem_config_struct_tag(dpn::diem_version_identifier())).await } @@ -106,6 +112,41 @@ impl Client { } + pub async fn get_aptos_version(&self) -> Result> { + self.get_resource::( + aptos_root_address(), + &StructTag { + address: CORE_CODE_ADDRESS, + name: ident_str!("Version").to_owned(), + module: ident_str!("Version").to_owned(), + type_params: vec![], + }, + ) + .await + } + + pub async fn get_account_balance(&self, address: AccountAddress) -> Result> { + let resp = self + .get_account_resources_by_type( + address, + aptos_types::account_config::CORE_CODE_ADDRESS, + &ident_str!("TestCoin").to_owned(), + &ident_str!("Balance").to_owned(), + ) + .await?; + resp.and_then(|mut resources| { + let resource = resources.pop(); + if !resources.is_empty() { + return Err(anyhow!("More than one data returned")); + } + if let Some(res) = resource { + Ok(serde_json::from_value::(res.data)?) + } else { + Err(anyhow!("No data returned")) + } + }) + } + pub async fn get_ledger_information(&self) -> Result> { #[derive(Deserialize)] struct Response { @@ -377,7 +418,7 @@ impl Client { self.json(response).await } - pub async fn get_account(&self, address: AccountAddress) -> Result> { + pub async fn get_account(&self, address: AccountAddress) -> Result> { let url = self.base_url.join(&format!("accounts/{}", address))?; let response = self.inner.get(url).send().await?; self.json(response).await diff --git a/crates/aptos-rest-client/src/types.rs b/crates/aptos-rest-client/src/types.rs index d21b28b03e517..2e85cedc25150 100644 --- a/crates/aptos-rest-client/src/types.rs +++ b/crates/aptos-rest-client/src/types.rs @@ -58,7 +58,7 @@ where } #[derive(Clone, Debug, Deserialize)] -pub struct DiemAccount { +pub struct Account { #[serde(deserialize_with = "deserialize_from_prefixed_hex_string")] pub authentication_key: AuthenticationKey, #[serde(deserialize_with = "deserialize_from_string")] diff --git a/crates/transaction-emitter/Cargo.toml b/crates/transaction-emitter/Cargo.toml index 51e73695cc86b..0d2b3530df3d9 100644 --- a/crates/transaction-emitter/Cargo.toml +++ b/crates/transaction-emitter/Cargo.toml @@ -29,3 +29,4 @@ aptos-crypto = { path = "../aptos-crypto" } aptos-logger = { path = "../../crates/aptos-logger" } aptos-sdk = { path = "../../sdk" } aptos-workspace-hack = { version = "0.1", path = "../aptos-workspace-hack" } +aptos-transaction-builder = { path = "../../sdk/transaction-builder" } diff --git a/crates/transaction-emitter/src/lib.rs b/crates/transaction-emitter/src/lib.rs index 66c77eddd2fdc..5497b7a208915 100644 --- a/crates/transaction-emitter/src/lib.rs +++ b/crates/transaction-emitter/src/lib.rs @@ -6,9 +6,8 @@ use aptos_logger::*; use aptos_rest_client::{Client as RestClient, PendingTransaction, Response}; use aptos_sdk::{ move_types::account_address::AccountAddress, - transaction_builder::{Currency, TransactionFactory}, + transaction_builder::TransactionFactory, types::{ - account_config::XUS_NAME, chain_id::ChainId, transaction::{authenticator::AuthenticationKey, SignedTransaction}, LocalAccount, @@ -39,8 +38,11 @@ pub mod atomic_histogram; pub mod cluster; pub mod instance; -use aptos_crypto::ed25519::Ed25519PrivateKey; -use aptos_sdk::types::AccountKey; +use aptos_crypto::ed25519::{Ed25519PrivateKey, Ed25519PublicKey}; +use aptos_sdk::{ + transaction_builder::aptos_stdlib, + types::{transaction::authenticator::AuthenticationKeyPreimage, AccountKey}, +}; use atomic_histogram::*; use rand::rngs::StdRng; @@ -312,19 +314,17 @@ impl SubmissionWorker { } #[derive(Debug)] -pub struct TxnEmitter<'t, 'd> { +pub struct TxnEmitter<'t> { accounts: Vec, txn_factory: TransactionFactory, - treasury_compliance_account: &'t mut LocalAccount, - designated_dealer_account: &'d mut LocalAccount, client: RestClient, rng: ::rand::rngs::StdRng, + root_account: &'t mut LocalAccount, } -impl<'t, 'd> TxnEmitter<'t, 'd> { +impl<'t> TxnEmitter<'t> { pub fn new( - treasury_compliance_account: &'t mut LocalAccount, - designated_dealer_account: &'d mut LocalAccount, + root_account: &'t mut LocalAccount, client: RestClient, transaction_factory: TransactionFactory, rng: ::rand::rngs::StdRng, @@ -332,8 +332,7 @@ impl<'t, 'd> TxnEmitter<'t, 'd> { Self { accounts: vec![], txn_factory: transaction_factory, - treasury_compliance_account, - designated_dealer_account, + root_account, client, rng, } @@ -358,19 +357,16 @@ impl<'t, 'd> TxnEmitter<'t, 'd> { pub async fn get_money_source(&mut self, coins_total: u64) -> Result<&mut LocalAccount> { let client = self.client.clone(); println!("Creating and minting faucet account"); - let faucet_account = &mut self.designated_dealer_account; - let balances = client - .get_account_balances(faucet_account.address()) - .await?; - for b in balances.into_inner() { - if b.currency_code().eq(XUS_NAME) { - println!( - "DD account current balances are {}, requested {} coins", - b.amount, coins_total - ); - break; - } - } + let faucet_account = &mut self.root_account; + let balance = client + .get_account_balance(faucet_account.address()) + .await? + .into_inner(); + println!( + "Root account current balances are {}, requested {} coins", + balance.get(), + coins_total + ); Ok(faucet_account) } @@ -404,7 +400,6 @@ impl<'t, 'd> TxnEmitter<'t, 'd> { info!("Creating and minting seeds accounts"); let mut i = 0; let mut seed_accounts = vec![]; - // load vasp account created by AOS directly if vasp { let client = self.pick_mint_client(rest_clients).clone(); info!("Loading VASP account as seed accounts"); @@ -421,16 +416,12 @@ impl<'t, 'd> TxnEmitter<'t, 'd> { let batch_size = min(MAX_TXN_BATCH_SIZE, seed_account_num - i); let mut rng = self.from_rng(); let mut batch = gen_random_accounts(batch_size, &mut rng); - let creation_account = &mut self.treasury_compliance_account; + let creation_account = &mut self.root_account; let txn_factory = &self.txn_factory; let create_requests = batch .iter() .map(|account| { - create_parent_vasp_request( - creation_account, - account.authentication_key(), - txn_factory, - ) + create_account_request(creation_account, account.public_key(), txn_factory) }) .collect(); execute_and_wait_transactions(&client, creation_account, create_requests).await?; @@ -444,13 +435,13 @@ impl<'t, 'd> TxnEmitter<'t, 'd> { /// workflow of mint accounts: /// 1. mint faucet account as the money source - /// 2. load tc account to create seed accounts(parent VASP), one seed account for each endpoint + /// 2. load tc account to create seed accounts, one seed account for each endpoint /// 3. mint coins from faucet to new created seed accounts - /// 4. split number of requested accounts(child VASP) into equally size of groups + /// 4. split number of requested accounts into equally size of groups /// 5. each seed account take responsibility to create one size of group requested accounts and mint coins to them /// example: /// requested totally 100 new accounts with 10 endpoints - /// will create 10 seed accounts(parent VASP), each seed account create 10 new accounts + /// will create 10 seed accounts, each seed account create 10 new accounts pub async fn mint_accounts( &mut self, req: &EmitJobRequest, @@ -476,26 +467,33 @@ impl<'t, 'd> TxnEmitter<'t, 'd> { let seed_accounts = self .get_seed_accounts(&req.rest_clients, expected_num_seed_accounts, req.vasp) .await?; - let rng = self.from_rng(); + let mut rng = self.from_rng(); let faucet_account = self.get_money_source(coins_total).await?; let actual_num_seed_accounts = seed_accounts.len(); let num_new_child_accounts = (num_accounts + actual_num_seed_accounts - 1) / actual_num_seed_accounts; let coins_per_seed_account = coins_per_account * num_new_child_accounts as u64; - mint_to_new_accounts( + fund_new_accounts( faucet_account, &seed_accounts, - coins_per_seed_account as u64, + // * 2 for gas fee + coins_per_seed_account * 2, 100, client.clone(), &txn_factory, - rng, + &mut rng, ) .await .map_err(|e| format_err!("Failed to mint seed_accounts: {}", e))?; - println!("Completed minting seed accounts"); - println!("Minting additional {} accounts", num_accounts); - tokio::time::sleep(Duration::from_secs(10)).await; + println!( + "Completed minting seed accounts, each with {} coins", + coins_per_seed_account + ); + println!( + "Minting additional {} accounts wtih {} coins each", + num_accounts, coins_per_account + ); + // tokio::time::sleep(Duration::from_secs(10)).await; let seed_rngs = gen_rng_for_reusable_account(actual_num_seed_accounts); // For each seed account, create a future and transfer coins from that seed account to new accounts @@ -536,7 +534,6 @@ impl<'t, 'd> TxnEmitter<'t, 'd> { self.accounts.len() ); println!("Mint is done"); - tokio::time::sleep(Duration::from_secs(60)).await; Ok(()) } @@ -673,7 +670,7 @@ impl<'t, 'd> TxnEmitter<'t, 'd> { receiver, num_coins, &self.txn_factory, - 0, + 1, )) .await?; let deadline = Instant::now() + TXN_MAX_WAIT; @@ -695,9 +692,7 @@ pub async fn execute_and_wait_transactions( ); let pending_txns: Vec> = - try_join_all(txns.iter().map(|t| client.submit(t))) - .await - .context("submit transactions failed")?; + try_join_all(txns.iter().map(|t| client.submit(t))).await?; for pt in pending_txns { client @@ -791,21 +786,24 @@ where gen_reusable_accounts(&client, batch_size, &mut rng).await? } else { let batch = gen_random_accounts(batch_size, &mut rng); - let requests = batch + let creation_requests = batch .as_slice() .iter() .map(|account| { - source_account.sign_with_transaction_builder( - txn_factory.create_child_vasp_account( - Currency::XUS, - account.authentication_key(), - false, - coins_per_new_account, - ), - ) + create_account_request(&mut source_account, account.public_key(), txn_factory) }) .collect(); - execute_and_wait_transactions(&client, &mut source_account, requests).await?; + execute_and_wait_transactions(&client, &mut source_account, creation_requests).await?; + fund_new_accounts( + &mut source_account, + batch.as_slice(), + coins_per_new_account, + 100, + client.clone(), + txn_factory, + &mut rng, + ) + .await?; batch }; @@ -815,15 +813,15 @@ where Ok(accounts) } -/// Mint `coins_per_new_account` from `minting_account` to each account in `accounts`. -async fn mint_to_new_accounts( +/// Transfer `coins_per_new_account` from `minting_account` to each account in `accounts`. +async fn fund_new_accounts( minting_account: &mut LocalAccount, accounts: &[LocalAccount], coins_per_new_account: u64, max_num_accounts_per_batch: u64, client: RestClient, txn_factory: &TransactionFactory, - mut rng: R, + rng: &mut R, ) -> Result<()> where R: ::rand_core::RngCore + ::rand_core::CryptoRng, @@ -846,7 +844,7 @@ where &account.address(), coins_per_new_account, txn_factory, - 0, + 1, ) }) .collect(); @@ -857,17 +855,18 @@ where Ok(()) } -pub fn create_parent_vasp_request( +pub fn create_account_request( creation_account: &mut LocalAccount, - account_auth_key: AuthenticationKey, + pubkey: &Ed25519PublicKey, txn_factory: &TransactionFactory, ) -> SignedTransaction { - creation_account.sign_with_transaction_builder(txn_factory.create_parent_vasp_account( - Currency::XUS, - 0, - account_auth_key, - "", - false, + let preimage = AuthenticationKeyPreimage::ed25519(pubkey); + let auth_key = AuthenticationKey::from_preimage(&preimage); + creation_account.sign_with_transaction_builder(txn_factory.payload( + aptos_stdlib::encode_create_account_script_function( + auth_key.derived_address(), + preimage.into_vec(), + ), )) } @@ -889,7 +888,9 @@ pub fn gen_transfer_txn_request( ) -> SignedTransaction { sender.sign_with_transaction_builder( txn_factory - .peer_to_peer(Currency::XUS, *receiver, num_coins) + .payload(aptos_stdlib::encode_transfer_script_function( + *receiver, num_coins, + )) .gas_unit_price(gas_price), ) } diff --git a/crates/transaction-emitter/src/main.rs b/crates/transaction-emitter/src/main.rs index 8640e13fda172..1b6aea77e58b4 100644 --- a/crates/transaction-emitter/src/main.rs +++ b/crates/transaction-emitter/src/main.rs @@ -3,10 +3,7 @@ use anyhow::{bail, format_err, Result}; use aptos_config::config::DEFAULT_PORT; -use aptos_sdk::{ - transaction_builder::TransactionFactory, - types::{chain_id::ChainId, LocalAccount}, -}; +use aptos_sdk::{transaction_builder::TransactionFactory, types::chain_id::ChainId}; use futures::future::join_all; use itertools::zip; use rand::{rngs::StdRng, Rng, SeedableRng}; @@ -89,25 +86,11 @@ async fn emit_tx(cluster: &Cluster, args: &Args) -> Result<()> { }; let duration = Duration::from_secs(args.duration); let client = cluster.random_instance().rest_client(); - let (mut treasury_compliance_account, mut designated_dealer_account) = if args.vasp { - ( - LocalAccount::generate(&mut rand::rngs::OsRng), - cluster - .load_dd_account(&client) - .await - .map_err(|e| format_err!("Failed to get dd account: {}", e))?, - ) - } else { - ( - cluster.load_tc_account(&client).await?, - cluster.load_faucet_account(&client).await?, - ) - }; + let mut root_account = cluster.load_aptos_root_account(&client).await?; let mut emitter = TxnEmitter::new( - &mut treasury_compliance_account, - &mut designated_dealer_account, + &mut root_account, client, - TransactionFactory::new(cluster.chain_id), + TransactionFactory::new(cluster.chain_id).with_gas_unit_price(1), StdRng::from_seed(OsRng.gen()), ); let mut emit_job_request = @@ -170,63 +153,18 @@ impl BasicSwarmUtil { Self { cluster } } - pub async fn diag(&self, vasp: bool) -> Result<()> { + pub async fn diag(&self, _vasp: bool) -> Result<()> { let client = self.cluster.random_instance().rest_client(); - let (mut treasury_compliance_account, mut designated_dealer_account) = if vasp { - ( - LocalAccount::generate(&mut rand::rngs::OsRng), - self.cluster - .load_dd_account(&client) - .await - .map_err(|e| format_err!("Failed to get dd account: {}", e))?, - ) - } else { - ( - self.cluster.load_tc_account(&client).await?, - self.cluster.load_faucet_account(&client).await?, - ) - }; + let mut root_account = self.cluster.load_aptos_root_account(&client).await?; + let mut faucet_account = self.cluster.load_aptos_root_account(&client).await?; let emitter = TxnEmitter::new( - &mut treasury_compliance_account, - &mut designated_dealer_account, + &mut root_account, client, - TransactionFactory::new(self.cluster.chain_id), + TransactionFactory::new(self.cluster.chain_id).with_gas_unit_price(1), StdRng::from_seed(OsRng.gen()), ); - let mut faucet_account: Option = None; - let instances: Vec<_> = self.cluster.all_instances().collect(); - for instance in &instances { - let client = instance.rest_client(); - print!("Getting faucet account sequence number on {}...", instance); - let account = if vasp { - self.cluster - .load_dd_account(&client) - .await - .map_err(|e| format_err!("Failed to get dd account: {}", e))? - } else { - self.cluster - .load_faucet_account(&client) - .await - .map_err(|e| { - format_err!("Failed to get faucet account sequence number: {}", e) - })? - }; - println!("seq={}", account.sequence_number()); - if let Some(faucet_account) = &faucet_account { - if account.sequence_number() != faucet_account.sequence_number() { - bail!( - "Loaded sequence number {}, which is different from seen before {}", - account.sequence_number(), - faucet_account.sequence_number() - ); - } - } else { - faucet_account = Some(account); - } - } - let mut faucet_account = - faucet_account.expect("There is no faucet account set (not expected)"); let faucet_account_address = faucet_account.address(); + let instances: Vec<_> = self.cluster.all_instances().collect(); for instance in &instances { print!("Submitting txn through {}...", instance); let deadline = emitter diff --git a/execution/executor-benchmark/src/db_generator.rs b/execution/executor-benchmark/src/db_generator.rs index 9a25b2d86896b..bdd92b39ec53a 100644 --- a/execution/executor-benchmark/src/db_generator.rs +++ b/execution/executor-benchmark/src/db_generator.rs @@ -121,7 +121,10 @@ pub fn run( ]) .get(); let data_size = DIEM_STORAGE_ROCKSDB_PROPERTIES - .with_label_values(&[JELLYFISH_MERKLE_NODE_CF_NAME, "aptos_rocksdb_total-sst-files-size"]) + .with_label_values(&[ + JELLYFISH_MERKLE_NODE_CF_NAME, + "aptos_rocksdb_total-sst-files-size", + ]) .get(); let reads = DIEM_JELLYFISH_STORAGE_READS.get(); let leaf_bytes = DIEM_JELLYFISH_LEAF_ENCODED_BYTES.get(); diff --git a/scripts/fgi/run b/scripts/fgi/run index 0f8ebda6f9745..6c68114a24209 100755 --- a/scripts/fgi/run +++ b/scripts/fgi/run @@ -107,9 +107,12 @@ if not args.tag: if ret != 0: print(f"{FAIL}Failed to access codebuild. Try aws-mfa?{RESTORE}") sys.exit(1) - subprocess.call( + ret = subprocess.call( ["./docker/build-aws.sh", "--build-forge", "--version", f"pull/{args.pr}"] ) + if ret != 0: + print(f"{FAIL}Failed to build forge.") + sys.exit(1) TAG = f"dev_{USER}_pull_{args.pr}" print( f"**TIP Use ./scripts/fgi/run -T {TAG} <...> to restart this run with the same tag without rebuilding it" diff --git a/sdk/src/transaction_builder.rs b/sdk/src/transaction_builder.rs index 8f40cea310935..9dac052da694b 100644 --- a/sdk/src/transaction_builder.rs +++ b/sdk/src/transaction_builder.rs @@ -89,7 +89,7 @@ pub struct TransactionFactory { impl TransactionFactory { pub fn new(chain_id: ChainId) -> Self { Self { - max_gas_amount: 1_000_000, + max_gas_amount: 1_000, gas_unit_price: 0, gas_currency: Currency::XUS, transaction_expiration_time: 30, diff --git a/testsuite/forge-cli/Cargo.toml b/testsuite/forge-cli/Cargo.toml index 34710184d07b9..905dbdc4888d1 100644 --- a/testsuite/forge-cli/Cargo.toml +++ b/testsuite/forge-cli/Cargo.toml @@ -11,6 +11,7 @@ edition = "2018" [dependencies] anyhow = { version = "1.0.52", features = ["backtrace"] } +async-trait = "0.1.42" aptos-sdk = { path = "../../sdk" } aptos-rest-client = { path = "../../crates/aptos-rest-client"} forge = { path = "../forge" } @@ -21,6 +22,7 @@ tokio = { version = "1.8.1", features = ["full"] } testcases = { path = "../testcases" } url = "2.2.2" aptos-workspace-hack = { version = "0.1", path = "../../crates/aptos-workspace-hack" } +aptos-framework-releases = { path = "../../aptos-move/framework/aptos-framework/releases" } [[bin]] name = "forge" diff --git a/testsuite/forge-cli/src/main.rs b/testsuite/forge-cli/src/main.rs index 3c07a3727edbf..8dd966bd2df0e 100644 --- a/testsuite/forge-cli/src/main.rs +++ b/testsuite/forge-cli/src/main.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use aptos_rest_client::Client as RestClient; -use aptos_sdk::{move_types::account_address::AccountAddress, transaction_builder::Currency}; +use aptos_sdk::{move_types::account_address::AccountAddress, transaction_builder::aptos_stdlib}; use forge::{ForgeConfig, Options, Result, *}; use std::{env, num::NonZeroUsize, process, time::Duration}; use structopt::StructOpt; @@ -337,15 +337,16 @@ fn get_test_suite(suite_name: &str) -> ForgeConfig<'static> { fn local_test_suite() -> ForgeConfig<'static> { ForgeConfig::default() - .with_public_usage_tests(&[&FundAccount, &TransferCoins]) + .with_aptos_tests(&[&FundAccount, &TransferCoins]) .with_admin_tests(&[&GetMetadata]) .with_network_tests(&[&RestartValidator, &EmitTransaction]) + .with_genesis_modules_bytes(aptos_framework_releases::current_module_blobs().to_vec()) } fn k8s_test_suite() -> ForgeConfig<'static> { ForgeConfig::default() .with_initial_validator_count(NonZeroUsize::new(30).unwrap()) - .with_public_usage_tests(&[&FundAccount, &TransferCoins]) + .with_aptos_tests(&[&FundAccount, &TransferCoins]) .with_admin_tests(&[&GetMetadata]) .with_network_tests(&[&EmitTransaction, &SimpleValidatorUpgrade]) } @@ -415,19 +416,14 @@ impl AdminTest for GetMetadata { pub async fn check_account_balance( client: &RestClient, - currency: Currency, account_address: AccountAddress, expected: u64, ) -> Result<()> { - let balances = client - .get_account_balances(account_address) + let balance = client + .get_account_balance(account_address) .await? .into_inner(); - let balance = balances - .iter() - .find(|b| b.currency_code() == currency) - .unwrap(); - assert_eq!(balance.amount, expected); + assert_eq!(balance.get(), expected); Ok(()) } @@ -441,24 +437,16 @@ impl Test for FundAccount { } } -impl PublicUsageTest for FundAccount { - fn run<'t>(&self, ctx: &mut PublicUsageContext<'t>) -> Result<()> { - let runtime = Runtime::new().unwrap(); - runtime.block_on(self.async_run(ctx)) - } -} - -impl FundAccount { - async fn async_run(&self, ctx: &mut PublicUsageContext<'_>) -> Result<()> { - let client = ctx.rest_client(); +#[async_trait::async_trait] +impl AptosTest for FundAccount { + async fn run<'t>(&self, ctx: &mut AptosContext<'t>) -> Result<()> { + let client = ctx.client(); let account = ctx.random_account(); let amount = 1000; - let currency = Currency::XUS; - ctx.create_parent_vasp_account(account.authentication_key()) - .await?; - ctx.fund(account.address(), amount).await?; - check_account_balance(&client, currency, account.address(), amount).await?; + ctx.create_user_account(account.public_key()).await?; + ctx.mint(account.address(), amount).await?; + check_account_balance(&client, account.address(), amount).await?; Ok(()) } @@ -473,51 +461,23 @@ impl Test for TransferCoins { } } -impl PublicUsageTest for TransferCoins { - fn run<'t>(&self, ctx: &mut PublicUsageContext<'t>) -> Result<()> { - let runtime = Runtime::new().unwrap(); - runtime.block_on(self.async_run(ctx)) - } -} - -impl TransferCoins { - async fn async_run(&self, ctx: &mut PublicUsageContext<'_>) -> Result<()> { - let mut account = ctx.random_account(); - let amount = 1000; - let currency = Currency::XUS; - let client = ctx.rest_client(); - ctx.create_parent_vasp_account(account.authentication_key()) - .await?; - ctx.fund(account.address(), amount).await?; - +#[async_trait::async_trait] +impl AptosTest for TransferCoins { + async fn run<'t>(&self, ctx: &mut AptosContext<'t>) -> Result<()> { + let client = ctx.client(); let mut payer = ctx.random_account(); let payee = ctx.random_account(); - let create_payer = account.sign_with_transaction_builder( - ctx.transaction_factory().create_child_vasp_account( - currency, - payer.authentication_key(), - false, - 100, - ), - ); - let create_payee = account.sign_with_transaction_builder( - ctx.transaction_factory().create_child_vasp_account( - currency, - payee.authentication_key(), - false, - 0, - ), - ); - client.submit(&create_payer).await?; - client.submit(&create_payee).await?; - client.wait_for_signed_transaction(&create_payer).await?; - client.wait_for_signed_transaction(&create_payee).await?; - check_account_balance(&client, currency, payer.address(), 100).await?; - - ctx.transfer_coins(currency, &mut payer, payee.address(), 10) - .await?; - check_account_balance(&client, currency, payer.address(), 90).await?; - check_account_balance(&client, currency, payee.address(), 10).await?; + ctx.create_user_account(payer.public_key()).await?; + ctx.create_user_account(payee.public_key()).await?; + ctx.mint(payer.address(), 10000).await?; + check_account_balance(&client, payer.address(), 10000).await?; + + let transfer_txn = + payer.sign_with_transaction_builder(ctx.aptos_transaction_factory().payload( + aptos_stdlib::encode_transfer_script_function(payee.address(), 10), + )); + client.submit_and_wait(&transfer_txn).await?; + check_account_balance(&client, payee.address(), 10).await?; Ok(()) } @@ -541,6 +501,7 @@ impl NetworkTest for RestartValidator { node.stop().unwrap(); println!("Restarting node {}", node.peer_id()); node.start().await.unwrap(); + tokio::time::sleep(Duration::from_secs(1)).await; node.health_check().await.expect("node health check failed"); }); Ok(()) @@ -564,7 +525,7 @@ impl NetworkTest for EmitTransaction { .validators() .map(|v| v.peer_id()) .collect::>(); - let stats = generate_traffic(ctx, &all_validators, duration, 0, None).unwrap(); + let stats = generate_traffic(ctx, &all_validators, duration, 1, None).unwrap(); ctx.report .report_txn_stats(self.name().to_string(), stats, duration); diff --git a/testsuite/forge/src/backend/k8s/cluster_helper.rs b/testsuite/forge/src/backend/k8s/cluster_helper.rs index 8d54adf181ef6..d22c276be8866 100644 --- a/testsuite/forge/src/backend/k8s/cluster_helper.rs +++ b/testsuite/forge/src/backend/k8s/cluster_helper.rs @@ -39,8 +39,7 @@ const VALIDATOR_SCALING_FACTOR: i64 = 3; const UTILITIES_SCALING_FACTOR: i64 = 3; const TRUSTED_SCALING_FACTOR: i64 = 1; -// XXX: swap this out for aptos-framework eventually -const GENESIS_MODULES_DIR: &str = "/aptos/move/modules"; +const GENESIS_MODULES_DIR: &str = "/aptos-framework/move/modules"; async fn wait_genesis_job(kube_client: &K8sClient, era: &str) -> Result<()> { aptos_retrier::retry_async(k8s_retry_strategy(), || { diff --git a/testsuite/forge/src/backend/k8s/swarm.rs b/testsuite/forge/src/backend/k8s/swarm.rs index cbec7c35de419..760033c53da5c 100644 --- a/testsuite/forge/src/backend/k8s/swarm.rs +++ b/testsuite/forge/src/backend/k8s/swarm.rs @@ -74,29 +74,12 @@ impl K8sSwarm { let key = load_tc_key(treasury_compliance_key); let account_key = AccountKey::from_private_key(key); let address = aptos_sdk::types::account_config::treasury_compliance_account_address(); - let sequence_number = query_sequence_numbers(&client, &[address]) - .await - .map_err(|e| { - format_err!( - "query_sequence_numbers on {:?} for dd account failed: {}", - client, - e - ) - })?[0]; + let sequence_number = 0; let treasury_compliance_account = LocalAccount::new(address, account_key, sequence_number); let key = load_tc_key(treasury_compliance_key); let account_key = AccountKey::from_private_key(key); let address = aptos_sdk::types::account_config::testnet_dd_account_address(); - let sequence_number = query_sequence_numbers(&client, &[address]) - .await - .map_err(|e| { - format_err!( - "query_sequence_numbers on {:?} for dd account failed: {}", - client, - e - ) - })?[0]; let designated_dealer_account = LocalAccount::new(address, account_key, sequence_number); let mut versions = HashMap::new(); @@ -395,8 +378,6 @@ pub async fn nodes_healthcheck(nodes: Vec<&K8sNode>) -> Result> { if !unhealthy_nodes.is_empty() { debug!("Unhealthy validators after cleanup: {:?}", unhealthy_nodes); } - println!("Wait for the instance to sync up with peers"); - tokio::time::sleep(Duration::from_secs(20)).await; Ok(unhealthy_nodes) } diff --git a/testsuite/smoke-test/src/aptos/mint_transfer.rs b/testsuite/smoke-test/src/aptos/mint_transfer.rs index 96df30aa903a9..9182cacfab7f1 100644 --- a/testsuite/smoke-test/src/aptos/mint_transfer.rs +++ b/testsuite/smoke-test/src/aptos/mint_transfer.rs @@ -27,6 +27,14 @@ impl AptosTest for MintTransfer { aptos_stdlib::encode_transfer_script_function(account2.address(), 400), )); ctx.client().submit_and_wait(&transfer_txn).await?; + assert_eq!( + ctx.client() + .get_account_balance(account2.address()) + .await? + .into_inner() + .get(), + 400 + ); // test delegation let txn_factory = ctx.aptos_transaction_factory(); diff --git a/testsuite/smoke-test/src/fullnode.rs b/testsuite/smoke-test/src/fullnode.rs index bd156ee00bb32..a30d58ef8d15d 100644 --- a/testsuite/smoke-test/src/fullnode.rs +++ b/testsuite/smoke-test/src/fullnode.rs @@ -68,7 +68,7 @@ impl LaunchFullnode { client.submit_and_wait(&txn).await?; let balances = client - .get_account_balances(account1.address()) + .get_dpn_account_balances(account1.address()) .await? .into_inner(); diff --git a/testsuite/smoke-test/src/scripts_and_modules.rs b/testsuite/smoke-test/src/scripts_and_modules.rs index bd44e86ae3c6a..543ab296ef119 100644 --- a/testsuite/smoke-test/src/scripts_and_modules.rs +++ b/testsuite/smoke-test/src/scripts_and_modules.rs @@ -122,7 +122,7 @@ impl ExecuteCustomModuleAndScript { .await?; let balances = client - .get_account_balances(account1.address()) + .get_dpn_account_balances(account1.address()) .await? .into_inner(); assert_eq!(balances.len(), 1); @@ -197,7 +197,7 @@ impl ExecuteCustomModuleAndScript { assert_eq!( vec![(90, "XUS".to_string())], client - .get_account_balances(account1.address()) + .get_dpn_account_balances(account1.address()) .await? .into_inner() .into_iter() @@ -208,7 +208,7 @@ impl ExecuteCustomModuleAndScript { assert_eq!( vec![(11, "XUS".to_string())], client - .get_account_balances(account2.address()) + .get_dpn_account_balances(account2.address()) .await? .into_inner() .into_iter() diff --git a/testsuite/smoke-test/src/test_utils.rs b/testsuite/smoke-test/src/test_utils.rs index 2c9a7651bd487..c8b41935dd26b 100644 --- a/testsuite/smoke-test/src/test_utils.rs +++ b/testsuite/smoke-test/src/test_utils.rs @@ -70,7 +70,7 @@ pub async fn transfer_and_reconfig( for _ in 0..num_transfers { // Reconfigurations have a 20% chance of being executed if random::() % 5 == 0 { - let diem_version = client.get_aptos_version().await.unwrap(); + let diem_version = client.get_dpn_version().await.unwrap(); let current_version = *diem_version.into_inner().payload.major.inner(); let txn = root_account.sign_with_transaction_builder( transaction_factory.update_diem_version(0, current_version + 1), @@ -86,7 +86,7 @@ pub async fn transfer_and_reconfig( pub async fn assert_balance(client: &RestClient, account: &LocalAccount, balance: u64) { let balances = client - .get_account_balances(account.address()) + .get_dpn_account_balances(account.address()) .await .unwrap() .into_inner(); diff --git a/testsuite/testcases/src/compatibility_test.rs b/testsuite/testcases/src/compatibility_test.rs index 39a6959e1126e..d4b209f292a9f 100644 --- a/testsuite/testcases/src/compatibility_test.rs +++ b/testsuite/testcases/src/compatibility_test.rs @@ -66,7 +66,7 @@ impl NetworkTest for SimpleValidatorUpgrade { runtime.block_on(batch_update(ctx, &validators_to_downgrade, &old_version))?; // Generate some traffic - generate_traffic(ctx, &all_validators, duration, 0, None)?; + generate_traffic(ctx, &all_validators, duration, 1, None)?; // Update the first Validator let msg = format!( @@ -76,7 +76,7 @@ impl NetworkTest for SimpleValidatorUpgrade { println!("{}", msg); ctx.report.report_text(msg); runtime.block_on(batch_update(ctx, &[first_node], &new_version))?; - generate_traffic(ctx, &[first_node], duration, 0, None)?; + generate_traffic(ctx, &[first_node], duration, 1, None)?; // Update the rest of the first batch let msg = format!( @@ -86,7 +86,7 @@ impl NetworkTest for SimpleValidatorUpgrade { println!("{}", msg); ctx.report.report_text(msg); runtime.block_on(batch_update(ctx, &first_batch, &new_version))?; - generate_traffic(ctx, &first_batch, duration, 0, None)?; + generate_traffic(ctx, &first_batch, duration, 1, None)?; ctx.swarm().fork_check()?; @@ -95,7 +95,7 @@ impl NetworkTest for SimpleValidatorUpgrade { println!("{}", msg); ctx.report.report_text(msg); runtime.block_on(batch_update(ctx, &second_batch, &new_version))?; - generate_traffic(ctx, &second_batch, duration, 0, None)?; + generate_traffic(ctx, &second_batch, duration, 1, None)?; let msg = "5. check swarm health".to_string(); println!("{}", msg); diff --git a/testsuite/testcases/src/fixed_tps_test.rs b/testsuite/testcases/src/fixed_tps_test.rs index 83afec41d953c..f220c218b8cff 100644 --- a/testsuite/testcases/src/fixed_tps_test.rs +++ b/testsuite/testcases/src/fixed_tps_test.rs @@ -23,7 +23,7 @@ impl NetworkTest for FixedTpsTest { .collect::>(); // Generate some traffic with fixed tps 10 - let txn_stat = generate_traffic(ctx, &all_validators, duration, 0, Some(10))?; + let txn_stat = generate_traffic(ctx, &all_validators, duration, 1, Some(10))?; ctx.report .report_txn_stats(self.name().to_string(), txn_stat, duration); diff --git a/testsuite/testcases/src/lib.rs b/testsuite/testcases/src/lib.rs index 7b8454b2d16f8..0a4320ffb1b36 100644 --- a/testsuite/testcases/src/lib.rs +++ b/testsuite/testcases/src/lib.rs @@ -9,6 +9,7 @@ pub mod performance_test; pub mod reconfiguration_test; pub mod state_sync_performance; +use anyhow::ensure; use aptos_sdk::{transaction_builder::TransactionFactory, types::PeerId}; use forge::{NetworkContext, NodeExt, Result, TxnEmitter, TxnStats, Version}; use rand::SeedableRng; @@ -47,6 +48,7 @@ pub fn generate_traffic<'t>( gas_price: u64, fixed_tps: Option, ) -> Result { + ensure!(gas_price > 0, "gas_price is required to be non zero"); let rt = Runtime::new()?; let rng = SeedableRng::from_rng(ctx.core().rng())?; let validator_clients = ctx @@ -57,10 +59,9 @@ pub fn generate_traffic<'t>( .collect::>(); let mut emit_job_request = ctx.global_job.clone(); let chain_info = ctx.swarm().chain_info(); - let transaction_factory = TransactionFactory::new(chain_info.chain_id); + let transaction_factory = TransactionFactory::new(chain_info.chain_id).with_gas_unit_price(1); let mut emitter = TxnEmitter::new( - chain_info.treasury_compliance_account, - chain_info.designated_dealer_account, + chain_info.root_account, validator_clients[0].clone(), transaction_factory, rng, diff --git a/testsuite/testcases/src/partial_nodes_down_test.rs b/testsuite/testcases/src/partial_nodes_down_test.rs index a6a96eb790e84..a2135e7bea4c8 100644 --- a/testsuite/testcases/src/partial_nodes_down_test.rs +++ b/testsuite/testcases/src/partial_nodes_down_test.rs @@ -32,7 +32,7 @@ impl NetworkTest for PartialNodesDown { thread::sleep(Duration::from_secs(5)); // Generate some traffic - let txn_stat = generate_traffic(ctx, &up_nodes, duration, 0, None)?; + let txn_stat = generate_traffic(ctx, &up_nodes, duration, 1, None)?; ctx.report .report_txn_stats(self.name().to_string(), txn_stat, duration); let runtime = Runtime::new()?; diff --git a/testsuite/testcases/src/performance_test.rs b/testsuite/testcases/src/performance_test.rs index 27ddf79c33442..2029b4b80cac8 100644 --- a/testsuite/testcases/src/performance_test.rs +++ b/testsuite/testcases/src/performance_test.rs @@ -23,7 +23,7 @@ impl NetworkTest for PerformanceBenchmark { .collect::>(); // Generate some traffic - let txn_stat = generate_traffic(ctx, &all_validators, duration, 0, None)?; + let txn_stat = generate_traffic(ctx, &all_validators, duration, 1, None)?; ctx.report .report_txn_stats(self.name().to_string(), txn_stat, duration); diff --git a/testsuite/testcases/src/state_sync_performance.rs b/testsuite/testcases/src/state_sync_performance.rs index 3b04c298f3f90..2e1a187913b47 100644 --- a/testsuite/testcases/src/state_sync_performance.rs +++ b/testsuite/testcases/src/state_sync_performance.rs @@ -41,7 +41,7 @@ impl NetworkTest for StateSyncPerformance { ctx.swarm().full_node_mut(*fullnode_id).unwrap().stop()?; // 2. emit txn to validators - generate_traffic(ctx, &all_validators, duration, 0, None)?; + generate_traffic(ctx, &all_validators, duration, 1, None)?; // 3. read the validator synced version let validator_id = all_validators.iter().choose(&mut rng).unwrap();