From 6fcc1cd263c540f8f0b73ef954650d60e3289212 Mon Sep 17 00:00:00 2001 From: MASQrauder <60554948+masqrauder@users.noreply.github.com> Date: Sun, 29 Sep 2024 18:31:53 -0400 Subject: [PATCH 01/56] GH-813: Correctly parse max block range error message (#531) --- node/src/blockchain/blockchain_bridge.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index b23d597bf..0bb34fbfd 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -456,7 +456,7 @@ impl BlockchainBridge { pub fn extract_max_block_count(&self, error: BlockchainError) -> Option { let regex_result = - Regex::new(r".* (max: |allowed for your plan: |is limited to |block range limit \()(?P\d+).*") + Regex::new(r".* (max: |allowed for your plan: |is limited to |block range limit \(|exceeds max block range )(?P\d+).*") .expect("Invalid regex"); let max_block_count = match error { BlockchainError::QueryFailed(msg) => match regex_result.captures(msg.as_str()) { @@ -1755,6 +1755,19 @@ mod tests { assert_eq!(None, max_block_count); } + #[test] + fn extract_max_block_range_for_nodies_error_response() { + let result = BlockchainError::QueryFailed("RPC error: Error { code: InvalidParams, message: \"query exceeds max block range 100000\", data: None }".to_string()); + let subject = BlockchainBridge::new( + Box::new(BlockchainInterfaceMock::default()), + Box::new(PersistentConfigurationMock::default()), + false, + ); + let max_block_count = subject.extract_max_block_count(result); + + assert_eq!(Some(100000), max_block_count); + } + #[test] fn extract_max_block_range_for_expected_batch_got_single_error_response() { let result = BlockchainError::QueryFailed( From a4fb720b339aff8e24ad576c8b0b2aae8abd984b Mon Sep 17 00:00:00 2001 From: Bert <65427484+bertllll@users.noreply.github.com> Date: Wed, 2 Oct 2024 05:05:28 +0200 Subject: [PATCH 02/56] GH-500: Adding Base chains (#510) * GH-500: ready for an urged live test * GH-500: probably finished the deployment of Base, let's get the QA going * GH-500: removed an eprintln! * GH-500: version changed to 0.8.1 --------- Co-authored-by: Bert --- automap/Cargo.lock | 4 +- automap/Cargo.toml | 2 +- dns_utility/Cargo.lock | 4 +- dns_utility/Cargo.toml | 2 +- masq/Cargo.toml | 2 +- masq_lib/Cargo.toml | 2 +- .../src/blockchains/blockchain_records.rs | 127 +++++++++++++----- masq_lib/src/blockchains/chains.rs | 13 +- masq_lib/src/constants.rs | 17 ++- masq_lib/src/shared_schema.rs | 55 ++++++-- multinode_integration_tests/Cargo.toml | 2 +- node/Cargo.lock | 10 +- node/Cargo.toml | 2 +- .../blockchain_interface_web3/mod.rs | 91 +++++++++---- node/src/db_config/config_dao.rs | 4 +- node/src/sub_lib/neighborhood.rs | 4 +- node/tests/contract_test.rs | 26 ++++ port_exposer/Cargo.lock | 2 +- port_exposer/Cargo.toml | 2 +- 19 files changed, 271 insertions(+), 100 deletions(-) diff --git a/automap/Cargo.lock b/automap/Cargo.lock index c970dc200..63c58616e 100644 --- a/automap/Cargo.lock +++ b/automap/Cargo.lock @@ -137,7 +137,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "automap" -version = "0.8.0" +version = "0.8.1" dependencies = [ "crossbeam-channel 0.5.8", "flexi_logger", @@ -1051,7 +1051,7 @@ dependencies = [ [[package]] name = "masq_lib" -version = "0.8.0" +version = "0.8.1" dependencies = [ "actix", "clap", diff --git a/automap/Cargo.toml b/automap/Cargo.toml index c89c47ced..1275d9e8d 100644 --- a/automap/Cargo.toml +++ b/automap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "automap" -version = "0.8.0" +version = "0.8.1" authors = ["Dan Wiebe ", "MASQ"] license = "GPL-3.0-only" description = "Library full of code to make routers map ports through firewalls" diff --git a/dns_utility/Cargo.lock b/dns_utility/Cargo.lock index 52a3ec6b3..970263d93 100644 --- a/dns_utility/Cargo.lock +++ b/dns_utility/Cargo.lock @@ -430,7 +430,7 @@ dependencies = [ [[package]] name = "dns_utility" -version = "0.8.0" +version = "0.8.1" dependencies = [ "core-foundation", "ipconfig 0.2.2", @@ -854,7 +854,7 @@ dependencies = [ [[package]] name = "masq_lib" -version = "0.8.0" +version = "0.8.1" dependencies = [ "actix", "clap", diff --git a/dns_utility/Cargo.toml b/dns_utility/Cargo.toml index f8ce5620f..21e5cbc8c 100644 --- a/dns_utility/Cargo.toml +++ b/dns_utility/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dns_utility" -version = "0.8.0" +version = "0.8.1" license = "GPL-3.0-only" authors = ["Dan Wiebe ", "MASQ"] copyright = "Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved." diff --git a/masq/Cargo.toml b/masq/Cargo.toml index 87a20ad67..9f3e2ab46 100644 --- a/masq/Cargo.toml +++ b/masq/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "masq" -version = "0.8.0" +version = "0.8.1" authors = ["Dan Wiebe ", "MASQ"] license = "GPL-3.0-only" description = "Reference implementation of user interface for MASQ Node" diff --git a/masq_lib/Cargo.toml b/masq_lib/Cargo.toml index f87de81a1..7917eb744 100644 --- a/masq_lib/Cargo.toml +++ b/masq_lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "masq_lib" -version = "0.8.0" +version = "0.8.1" authors = ["Dan Wiebe ", "MASQ"] license = "GPL-3.0-only" description = "Code common to Node and masq; also, temporarily, to dns_utility" diff --git a/masq_lib/src/blockchains/blockchain_records.rs b/masq_lib/src/blockchains/blockchain_records.rs index 5227195f7..67a8870e2 100644 --- a/masq_lib/src/blockchains/blockchain_records.rs +++ b/masq_lib/src/blockchains/blockchain_records.rs @@ -2,15 +2,17 @@ use crate::blockchains::chains::Chain; use crate::constants::{ - AMOY_TESTNET_CONTRACT_CREATION_BLOCK, DEV_CHAIN_FULL_IDENTIFIER, - ETH_MAINNET_CONTRACT_CREATION_BLOCK, ETH_MAINNET_FULL_IDENTIFIER, ETH_ROPSTEN_FULL_IDENTIFIER, - MULTINODE_TESTNET_CONTRACT_CREATION_BLOCK, POLYGON_AMOY_FULL_IDENTIFIER, - POLYGON_MAINNET_CONTRACT_CREATION_BLOCK, POLYGON_MAINNET_FULL_IDENTIFIER, - ROPSTEN_TESTNET_CONTRACT_CREATION_BLOCK, + BASE_MAINNET_CONTRACT_CREATION_BLOCK, BASE_MAINNET_FULL_IDENTIFIER, + BASE_SEPOLIA_CONTRACT_CREATION_BLOCK, BASE_SEPOLIA_FULL_IDENTIFIER, DEV_CHAIN_FULL_IDENTIFIER, + ETH_MAINNET_CONTRACT_CREATION_BLOCK, ETH_MAINNET_FULL_IDENTIFIER, + ETH_ROPSTEN_CONTRACT_CREATION_BLOCK, ETH_ROPSTEN_FULL_IDENTIFIER, + MULTINODE_TESTNET_CONTRACT_CREATION_BLOCK, POLYGON_AMOY_CONTRACT_CREATION_BLOCK, + POLYGON_AMOY_FULL_IDENTIFIER, POLYGON_MAINNET_CONTRACT_CREATION_BLOCK, + POLYGON_MAINNET_FULL_IDENTIFIER, }; use ethereum_types::{Address, H160}; -pub const CHAINS: [BlockchainRecord; 5] = [ +pub const CHAINS: [BlockchainRecord; 7] = [ BlockchainRecord { self_id: Chain::PolyMainnet, num_chain_id: 137, @@ -25,19 +27,33 @@ pub const CHAINS: [BlockchainRecord; 5] = [ contract: ETH_MAINNET_CONTRACT_ADDRESS, contract_creation_block: ETH_MAINNET_CONTRACT_CREATION_BLOCK, }, + BlockchainRecord { + self_id: Chain::BaseMainnet, + num_chain_id: 8453, + literal_identifier: BASE_MAINNET_FULL_IDENTIFIER, + contract: BASE_MAINNET_CONTRACT_ADDRESS, + contract_creation_block: BASE_MAINNET_CONTRACT_CREATION_BLOCK, + }, + BlockchainRecord { + self_id: Chain::BaseSepolia, + num_chain_id: 84532, + literal_identifier: BASE_SEPOLIA_FULL_IDENTIFIER, + contract: BASE_SEPOLIA_TESTNET_CONTRACT_ADDRESS, + contract_creation_block: BASE_SEPOLIA_CONTRACT_CREATION_BLOCK, + }, BlockchainRecord { self_id: Chain::PolyAmoy, num_chain_id: 80002, literal_identifier: POLYGON_AMOY_FULL_IDENTIFIER, - contract: AMOY_TESTNET_CONTRACT_ADDRESS, - contract_creation_block: AMOY_TESTNET_CONTRACT_CREATION_BLOCK, + contract: POLYGON_AMOY_TESTNET_CONTRACT_ADDRESS, + contract_creation_block: POLYGON_AMOY_CONTRACT_CREATION_BLOCK, }, BlockchainRecord { self_id: Chain::EthRopsten, num_chain_id: 3, literal_identifier: ETH_ROPSTEN_FULL_IDENTIFIER, - contract: ROPSTEN_TESTNET_CONTRACT_ADDRESS, - contract_creation_block: ROPSTEN_TESTNET_CONTRACT_CREATION_BLOCK, + contract: ETH_ROPSTEN_TESTNET_CONTRACT_ADDRESS, + contract_creation_block: ETH_ROPSTEN_CONTRACT_CREATION_BLOCK, }, BlockchainRecord { self_id: Chain::Dev, @@ -68,17 +84,27 @@ const ETH_MAINNET_CONTRACT_ADDRESS: Address = H160([ ]); // $tMASQ (Amoy) -const AMOY_TESTNET_CONTRACT_ADDRESS: Address = H160([ +const POLYGON_AMOY_TESTNET_CONTRACT_ADDRESS: Address = H160([ 0xd9, 0x8c, 0x3e, 0xbd, 0x6b, 0x7f, 0x9b, 0x7c, 0xda, 0x24, 0x49, 0xec, 0xac, 0x00, 0xd1, 0xe5, 0xf4, 0x7a, 0x81, 0x93, ]); // SHRD (Ropsten) -const ROPSTEN_TESTNET_CONTRACT_ADDRESS: Address = H160([ +const ETH_ROPSTEN_TESTNET_CONTRACT_ADDRESS: Address = H160([ 0x38, 0x4d, 0xec, 0x25, 0xe0, 0x3f, 0x94, 0x93, 0x17, 0x67, 0xce, 0x4c, 0x35, 0x56, 0x16, 0x84, 0x68, 0xba, 0x24, 0xc3, ]); +const BASE_MAINNET_CONTRACT_ADDRESS: Address = H160([ + 0x45, 0xD9, 0xC1, 0x01, 0xa3, 0x87, 0x0C, 0xa5, 0x02, 0x45, 0x82, 0xfd, 0x78, 0x8F, 0x4E, 0x1e, + 0x8F, 0x79, 0x71, 0xc3, +]); + +const BASE_SEPOLIA_TESTNET_CONTRACT_ADDRESS: Address = H160([ + 0x89, 0x8e, 0x1c, 0xe7, 0x20, 0x08, 0x4A, 0x90, 0x2b, 0xc3, 0x7d, 0xd8, 0x22, 0xed, 0x6d, 0x6a, + 0x5f, 0x02, 0x7e, 0x10, +]); + const MULTINODE_TESTNET_CONTRACT_ADDRESS: Address = H160([ 0x59, 0x88, 0x2e, 0x4a, 0x8f, 0x5d, 0x24, 0x64, 0x3d, 0x4d, 0xda, 0x42, 0x29, 0x22, 0xa8, 0x70, 0xf1, 0xb3, 0xe6, 0x64, @@ -88,9 +114,7 @@ const MULTINODE_TESTNET_CONTRACT_ADDRESS: Address = H160([ mod tests { use super::*; use crate::blockchains::chains::chain_from_chain_identifier_opt; - use crate::constants::{ - AMOY_TESTNET_CONTRACT_CREATION_BLOCK, POLYGON_MAINNET_CONTRACT_CREATION_BLOCK, - }; + use crate::constants::BASE_MAINNET_CONTRACT_CREATION_BLOCK; use std::collections::HashSet; use std::iter::FromIterator; @@ -98,10 +122,12 @@ mod tests { fn record_returns_correct_blockchain_record() { let test_array = [ assert_returns_correct_record(Chain::EthMainnet, 1), - assert_returns_correct_record(Chain::Dev, 2), assert_returns_correct_record(Chain::EthRopsten, 3), assert_returns_correct_record(Chain::PolyMainnet, 137), assert_returns_correct_record(Chain::PolyAmoy, 80002), + assert_returns_correct_record(Chain::BaseMainnet, 8453), + assert_returns_correct_record(Chain::BaseSepolia, 84532), + assert_returns_correct_record(Chain::Dev, 2), ]; assert_exhaustive(&test_array) } @@ -118,6 +144,8 @@ mod tests { assert_from_str(Chain::PolyAmoy), assert_from_str(Chain::EthMainnet), assert_from_str(Chain::EthRopsten), + assert_from_str(Chain::BaseMainnet), + assert_from_str(Chain::BaseSepolia), assert_from_str(Chain::Dev), ]; assert_exhaustive(&test_array) @@ -137,18 +165,23 @@ mod tests { #[test] fn chains_are_ordered_by_their_significance_for_users() { let test_array = [ - assert_chain_significance(0, Chain::PolyMainnet), - assert_chain_significance(1, Chain::EthMainnet), - assert_chain_significance(2, Chain::PolyAmoy), - assert_chain_significance(3, Chain::EthRopsten), - assert_chain_significance(4, Chain::Dev), + Chain::PolyMainnet, + Chain::EthMainnet, + Chain::BaseMainnet, + Chain::BaseSepolia, + Chain::PolyAmoy, + Chain::EthRopsten, + Chain::Dev, ]; + test_array + .iter() + .enumerate() + .for_each(assert_chain_significance); assert_exhaustive(&test_array) } - fn assert_chain_significance(idx: usize, chain: Chain) -> Chain { - assert_eq!(CHAINS[idx].self_id, chain, "Error at index {}", idx); - chain + fn assert_chain_significance((idx, chain): (usize, &Chain)) { + assert_eq!(CHAINS[idx].self_id, *chain, "Error at index {}", idx); } #[test] @@ -177,8 +210,8 @@ mod tests { num_chain_id: 3, self_id: examined_chain, literal_identifier: "eth-ropsten", - contract: ROPSTEN_TESTNET_CONTRACT_ADDRESS, - contract_creation_block: ROPSTEN_TESTNET_CONTRACT_CREATION_BLOCK, + contract: ETH_ROPSTEN_TESTNET_CONTRACT_ADDRESS, + contract_creation_block: ETH_ROPSTEN_CONTRACT_CREATION_BLOCK, } ); } @@ -209,8 +242,40 @@ mod tests { num_chain_id: 80002, self_id: examined_chain, literal_identifier: "polygon-amoy", - contract: AMOY_TESTNET_CONTRACT_ADDRESS, - contract_creation_block: AMOY_TESTNET_CONTRACT_CREATION_BLOCK, + contract: POLYGON_AMOY_TESTNET_CONTRACT_ADDRESS, + contract_creation_block: POLYGON_AMOY_CONTRACT_CREATION_BLOCK, + } + ); + } + + #[test] + fn base_mainnet_record_is_properly_declared() { + let examined_chain = Chain::BaseMainnet; + let chain_record = return_examined(examined_chain); + assert_eq!( + chain_record, + &BlockchainRecord { + num_chain_id: 8453, + self_id: examined_chain, + literal_identifier: "base-mainnet", + contract: BASE_MAINNET_CONTRACT_ADDRESS, + contract_creation_block: BASE_MAINNET_CONTRACT_CREATION_BLOCK, + } + ); + } + + #[test] + fn base_sepolia_record_is_properly_declared() { + let examined_chain = Chain::BaseSepolia; + let chain_record = return_examined(examined_chain); + assert_eq!( + chain_record, + &BlockchainRecord { + num_chain_id: 84532, + self_id: examined_chain, + literal_identifier: "base-sepolia", + contract: BASE_SEPOLIA_TESTNET_CONTRACT_ADDRESS, + contract_creation_block: BASE_SEPOLIA_CONTRACT_CREATION_BLOCK, } ); } @@ -226,7 +291,7 @@ mod tests { self_id: examined_chain, literal_identifier: "dev", contract: MULTINODE_TESTNET_CONTRACT_ADDRESS, - contract_creation_block: 0, + contract_creation_block: MULTINODE_TESTNET_CONTRACT_CREATION_BLOCK, } ); } @@ -240,9 +305,11 @@ mod tests { let test_array = [ assert_chain_from_chain_identifier_opt("eth-mainnet", Some(Chain::EthMainnet)), assert_chain_from_chain_identifier_opt("eth-ropsten", Some(Chain::EthRopsten)), - assert_chain_from_chain_identifier_opt("dev", Some(Chain::Dev)), assert_chain_from_chain_identifier_opt("polygon-mainnet", Some(Chain::PolyMainnet)), assert_chain_from_chain_identifier_opt("polygon-amoy", Some(Chain::PolyAmoy)), + assert_chain_from_chain_identifier_opt("base-mainnet", Some(Chain::BaseMainnet)), + assert_chain_from_chain_identifier_opt("base-sepolia", Some(Chain::BaseSepolia)), + assert_chain_from_chain_identifier_opt("dev", Some(Chain::Dev)), ]; assert_exhaustive(&test_array) } diff --git a/masq_lib/src/blockchains/chains.rs b/masq_lib/src/blockchains/chains.rs index 433d5524c..b7733b842 100644 --- a/masq_lib/src/blockchains/chains.rs +++ b/masq_lib/src/blockchains/chains.rs @@ -2,8 +2,9 @@ use crate::blockchains::blockchain_records::{BlockchainRecord, CHAINS}; use crate::constants::{ - DEFAULT_CHAIN, DEV_CHAIN_FULL_IDENTIFIER, ETH_MAINNET_FULL_IDENTIFIER, - ETH_ROPSTEN_FULL_IDENTIFIER, POLYGON_AMOY_FULL_IDENTIFIER, POLYGON_MAINNET_FULL_IDENTIFIER, + BASE_MAINNET_FULL_IDENTIFIER, BASE_SEPOLIA_FULL_IDENTIFIER, DEFAULT_CHAIN, + DEV_CHAIN_FULL_IDENTIFIER, ETH_MAINNET_FULL_IDENTIFIER, ETH_ROPSTEN_FULL_IDENTIFIER, + POLYGON_AMOY_FULL_IDENTIFIER, POLYGON_MAINNET_FULL_IDENTIFIER, }; use serde_derive::{Deserialize, Serialize}; @@ -13,6 +14,8 @@ pub enum Chain { EthRopsten, PolyMainnet, PolyAmoy, + BaseMainnet, + BaseSepolia, Dev, } @@ -28,6 +31,10 @@ impl From<&str> for Chain { Chain::PolyMainnet } else if str == ETH_MAINNET_FULL_IDENTIFIER { Chain::EthMainnet + } else if str == BASE_MAINNET_FULL_IDENTIFIER { + Chain::BaseMainnet + } else if str == BASE_SEPOLIA_FULL_IDENTIFIER { + Chain::BaseSepolia } else if str == POLYGON_AMOY_FULL_IDENTIFIER { Chain::PolyAmoy } else if str == ETH_ROPSTEN_FULL_IDENTIFIER { @@ -56,7 +63,7 @@ impl Chain { } fn mainnets() -> &'static [Chain] { - &[Chain::PolyMainnet, Chain::EthMainnet] + &[Chain::PolyMainnet, Chain::BaseMainnet, Chain::EthMainnet] } } diff --git a/masq_lib/src/constants.rs b/masq_lib/src/constants.rs index 1a0542837..9cfdc90c6 100644 --- a/masq_lib/src/constants.rs +++ b/masq_lib/src/constants.rs @@ -25,9 +25,11 @@ pub const MASQ_TOTAL_SUPPLY: u64 = 37_500_000; pub const WEIS_IN_GWEI: i128 = 1_000_000_000; pub const ETH_MAINNET_CONTRACT_CREATION_BLOCK: u64 = 11_170_708; -pub const ROPSTEN_TESTNET_CONTRACT_CREATION_BLOCK: u64 = 8_688_171; +pub const ETH_ROPSTEN_CONTRACT_CREATION_BLOCK: u64 = 8_688_171; pub const POLYGON_MAINNET_CONTRACT_CREATION_BLOCK: u64 = 14_863_650; -pub const AMOY_TESTNET_CONTRACT_CREATION_BLOCK: u64 = 5_323_366; +pub const POLYGON_AMOY_CONTRACT_CREATION_BLOCK: u64 = 5_323_366; +pub const BASE_MAINNET_CONTRACT_CREATION_BLOCK: u64 = 19_711_235; +pub const BASE_SEPOLIA_CONTRACT_CREATION_BLOCK: u64 = 14_732_730; pub const MULTINODE_TESTNET_CONTRACT_CREATION_BLOCK: u64 = 0; //Migration versions @@ -89,12 +91,15 @@ pub const CHAIN_IDENTIFIER_DELIMITER: char = ':'; //chains const POLYGON_FAMILY: &str = "polygon"; const ETH_FAMILY: &str = "eth"; +const BASE_FAMILY: &str = "base"; const MAINNET: &str = "mainnet"; const LINK: char = '-'; pub const POLYGON_MAINNET_FULL_IDENTIFIER: &str = concatcp!(POLYGON_FAMILY, LINK, MAINNET); pub const POLYGON_AMOY_FULL_IDENTIFIER: &str = concatcp!(POLYGON_FAMILY, LINK, "amoy"); pub const ETH_MAINNET_FULL_IDENTIFIER: &str = concatcp!(ETH_FAMILY, LINK, MAINNET); pub const ETH_ROPSTEN_FULL_IDENTIFIER: &str = concatcp!(ETH_FAMILY, LINK, "ropsten"); +pub const BASE_MAINNET_FULL_IDENTIFIER: &str = concatcp!(BASE_FAMILY, LINK, MAINNET); +pub const BASE_SEPOLIA_FULL_IDENTIFIER: &str = concatcp!(BASE_FAMILY, LINK, "sepolia"); pub const DEV_CHAIN_FULL_IDENTIFIER: &str = "dev"; #[cfg(test)] @@ -118,9 +123,11 @@ mod tests { assert_eq!(MASQ_TOTAL_SUPPLY, 37_500_000); assert_eq!(WEIS_IN_GWEI, 1_000_000_000); assert_eq!(ETH_MAINNET_CONTRACT_CREATION_BLOCK, 11_170_708); - assert_eq!(ROPSTEN_TESTNET_CONTRACT_CREATION_BLOCK, 8_688_171); + assert_eq!(ETH_ROPSTEN_CONTRACT_CREATION_BLOCK, 8_688_171); assert_eq!(POLYGON_MAINNET_CONTRACT_CREATION_BLOCK, 14_863_650); - assert_eq!(AMOY_TESTNET_CONTRACT_CREATION_BLOCK, 5_323_366); + assert_eq!(POLYGON_AMOY_CONTRACT_CREATION_BLOCK, 5_323_366); + assert_eq!(BASE_MAINNET_CONTRACT_CREATION_BLOCK, 19_711_235); + assert_eq!(BASE_SEPOLIA_CONTRACT_CREATION_BLOCK, 14_732_730); assert_eq!(MULTINODE_TESTNET_CONTRACT_CREATION_BLOCK, 0); assert_eq!(CONFIGURATOR_PREFIX, 0x0001_0000_0000_0000); assert_eq!(CONFIGURATOR_READ_ERROR, CONFIGURATOR_PREFIX | 1); @@ -159,12 +166,14 @@ mod tests { assert_eq!(CHAIN_IDENTIFIER_DELIMITER, ':'); assert_eq!(POLYGON_FAMILY, "polygon"); assert_eq!(ETH_FAMILY, "eth"); + assert_eq!(BASE_FAMILY, "base"); assert_eq!(MAINNET, "mainnet"); assert_eq!(LINK, '-'); assert_eq!(POLYGON_MAINNET_FULL_IDENTIFIER, "polygon-mainnet"); assert_eq!(POLYGON_AMOY_FULL_IDENTIFIER, "polygon-amoy"); assert_eq!(ETH_MAINNET_FULL_IDENTIFIER, "eth-mainnet"); assert_eq!(ETH_ROPSTEN_FULL_IDENTIFIER, "eth-ropsten"); + assert_eq!(BASE_SEPOLIA_FULL_IDENTIFIER, "base-sepolia"); assert_eq!(DEV_CHAIN_FULL_IDENTIFIER, "dev"); assert_eq!( CLIENT_REQUEST_PAYLOAD_CURRENT_VERSION, diff --git a/masq_lib/src/shared_schema.rs b/masq_lib/src/shared_schema.rs index cc3e34b54..276108d2e 100644 --- a/masq_lib/src/shared_schema.rs +++ b/masq_lib/src/shared_schema.rs @@ -1,9 +1,10 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. use crate::constants::{ - DEFAULT_GAS_PRICE, DEFAULT_UI_PORT, DEV_CHAIN_FULL_IDENTIFIER, ETH_MAINNET_FULL_IDENTIFIER, - ETH_ROPSTEN_FULL_IDENTIFIER, HIGHEST_USABLE_PORT, LOWEST_USABLE_INSECURE_PORT, - POLYGON_AMOY_FULL_IDENTIFIER, POLYGON_MAINNET_FULL_IDENTIFIER, + BASE_MAINNET_FULL_IDENTIFIER, BASE_SEPOLIA_FULL_IDENTIFIER, DEFAULT_GAS_PRICE, DEFAULT_UI_PORT, + DEV_CHAIN_FULL_IDENTIFIER, ETH_MAINNET_FULL_IDENTIFIER, ETH_ROPSTEN_FULL_IDENTIFIER, + HIGHEST_USABLE_PORT, LOWEST_USABLE_INSECURE_PORT, POLYGON_AMOY_FULL_IDENTIFIER, + POLYGON_MAINNET_FULL_IDENTIFIER, }; use crate::crash_point::CrashPoint; use clap::{App, Arg}; @@ -13,6 +14,7 @@ pub const BLOCKCHAIN_SERVICE_HELP: &str = "The Ethereum client you wish to use to provide Blockchain \ exit services from your MASQ Node (e.g. http://localhost:8545, \ https://ropsten.infura.io/v3/YOUR-PROJECT-ID, https://mainnet.infura.io/v3/YOUR-PROJECT-ID), \ + https://base-mainnet.g.alchemy.com/v2/d66UL0lPrltmweEqVsv3opBSVI3wkL8I, \ https://polygon-mainnet.infura.io/v3/YOUR-PROJECT-ID"; pub const CHAIN_HELP: &str = "The blockchain network MASQ Node will configure itself to use. You must ensure the \ @@ -64,8 +66,9 @@ pub const NEIGHBORS_HELP: &str = "One or more Node descriptors for running Nodes on startup. A Node descriptor looks similar to one of these:\n\n\ masq://polygon-mainnet:d2U3Dv1BqtS5t_Zz3mt9_sCl7AgxUlnkB4jOMElylrU@172.50.48.6:9342\n\ masq://eth-mainnet:gBviQbjOS3e5ReFQCvIhUM3i02d1zPleo1iXg_EN6zQ@86.75.30.9:5542\n\ + masq://base-mainnet:ZjPLnb9RrgsRM1D9edqH8jx9DkbPZSWqqFqLnmdKhsk@112.55.78.0:7878\n\ masq://polygon-amoy:A6PGHT3rRjaeFpD_rFi3qGEXAVPq7bJDfEUZpZaIyq8@14.10.50.6:10504\n\ - masq://eth-ropsten:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@150.60.42.72:6642/4789/5254\n\n\ + masq://base-sepolia:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@150.60.42.72:6642/4789/5254\n\n\ Notice each of the different chain identifiers in the masq protocol prefix - they determine a family of chains \ and also the network the descriptor belongs to (mainnet or a testnet). See also the last descriptor which shows \ a configuration with multiple clandestine ports.\n\n\ @@ -256,6 +259,8 @@ pub fn official_chain_names() -> &'static [&'static str] { &[ POLYGON_MAINNET_FULL_IDENTIFIER, ETH_MAINNET_FULL_IDENTIFIER, + BASE_MAINNET_FULL_IDENTIFIER, + BASE_SEPOLIA_FULL_IDENTIFIER, POLYGON_AMOY_FULL_IDENTIFIER, ETH_ROPSTEN_FULL_IDENTIFIER, DEV_CHAIN_FULL_IDENTIFIER, @@ -670,11 +675,11 @@ impl ConfiguratorError { #[cfg(test)] mod tests { - use super::*; use crate::blockchains::chains::Chain; use crate::shared_schema::common_validators::validate_non_zero_u16; use crate::shared_schema::{common_validators, official_chain_names}; + use std::collections::HashSet; #[test] fn constants_have_correct_values() { @@ -683,6 +688,7 @@ mod tests { "The Ethereum client you wish to use to provide Blockchain \ exit services from your MASQ Node (e.g. http://localhost:8545, \ https://ropsten.infura.io/v3/YOUR-PROJECT-ID, https://mainnet.infura.io/v3/YOUR-PROJECT-ID), \ + https://base-mainnet.g.alchemy.com/v2/d66UL0lPrltmweEqVsv3opBSVI3wkL8I, \ https://polygon-mainnet.infura.io/v3/YOUR-PROJECT-ID" ); assert_eq!( @@ -757,8 +763,9 @@ mod tests { on startup. A Node descriptor looks similar to one of these:\n\n\ masq://polygon-mainnet:d2U3Dv1BqtS5t_Zz3mt9_sCl7AgxUlnkB4jOMElylrU@172.50.48.6:9342\n\ masq://eth-mainnet:gBviQbjOS3e5ReFQCvIhUM3i02d1zPleo1iXg_EN6zQ@86.75.30.9:5542\n\ + masq://base-mainnet:ZjPLnb9RrgsRM1D9edqH8jx9DkbPZSWqqFqLnmdKhsk@112.55.78.0:7878\n\ masq://polygon-amoy:A6PGHT3rRjaeFpD_rFi3qGEXAVPq7bJDfEUZpZaIyq8@14.10.50.6:10504\n\ - masq://eth-ropsten:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@150.60.42.72:6642/4789/5254\n\n\ + masq://base-sepolia:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@150.60.42.72:6642/4789/5254\n\n\ Notice each of the different chain identifiers in the masq protocol prefix - they determine a family of chains \ and also the network the descriptor belongs to (mainnet or a testnet). See also the last descriptor which shows \ a configuration with multiple clandestine ports.\n\n\ @@ -1141,12 +1148,34 @@ mod tests { #[test] fn official_chain_names_are_reliable() { - let mut iterator = official_chain_names().iter(); - assert_eq!(Chain::from(*iterator.next().unwrap()), Chain::PolyMainnet); - assert_eq!(Chain::from(*iterator.next().unwrap()), Chain::EthMainnet); - assert_eq!(Chain::from(*iterator.next().unwrap()), Chain::PolyAmoy); - assert_eq!(Chain::from(*iterator.next().unwrap()), Chain::EthRopsten); - assert_eq!(Chain::from(*iterator.next().unwrap()), Chain::Dev); - assert_eq!(iterator.next(), None) + let expected_supported_chains = [ + Chain::PolyMainnet, + Chain::EthMainnet, + Chain::BaseMainnet, + Chain::BaseSepolia, + Chain::PolyAmoy, + Chain::EthRopsten, + Chain::Dev, + ] + .into_iter() + .collect::>(); + + let chain_names_recognizable_by_clap = official_chain_names(); + + let chains_from_clap = chain_names_recognizable_by_clap + .into_iter() + .map(|chain_name| Chain::from(*chain_name)) + .collect::>(); + let differences = chains_from_clap + .symmetric_difference(&expected_supported_chains) + .collect::>(); + assert!( + differences.is_empty(), + "There are differences in the Clap schema in the collection of supported chains, \ + between the expected values {:?} and actual {:?}, specifically {:?}", + expected_supported_chains, + chains_from_clap, + differences + ); } } diff --git a/multinode_integration_tests/Cargo.toml b/multinode_integration_tests/Cargo.toml index edf7a03f4..05bb47051 100644 --- a/multinode_integration_tests/Cargo.toml +++ b/multinode_integration_tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multinode_integration_tests" -version = "0.8.0" +version = "0.8.1" authors = ["Dan Wiebe ", "MASQ"] license = "GPL-3.0-only" description = "" diff --git a/node/Cargo.lock b/node/Cargo.lock index 04806d093..20fda85c6 100644 --- a/node/Cargo.lock +++ b/node/Cargo.lock @@ -182,7 +182,7 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "automap" -version = "0.8.0" +version = "0.8.1" dependencies = [ "crossbeam-channel 0.5.1", "flexi_logger 0.17.1", @@ -1802,7 +1802,7 @@ dependencies = [ [[package]] name = "masq" -version = "0.8.0" +version = "0.8.1" dependencies = [ "atty", "clap", @@ -1822,7 +1822,7 @@ dependencies = [ [[package]] name = "masq_lib" -version = "0.8.0" +version = "0.8.1" dependencies = [ "actix", "clap", @@ -1999,7 +1999,7 @@ dependencies = [ [[package]] name = "multinode_integration_tests" -version = "0.8.0" +version = "0.8.1" dependencies = [ "base64 0.13.0", "crossbeam-channel 0.5.1", @@ -2092,7 +2092,7 @@ dependencies = [ [[package]] name = "node" -version = "0.8.0" +version = "0.8.1" dependencies = [ "actix", "automap", diff --git a/node/Cargo.toml b/node/Cargo.toml index 4ae89971d..44dadafe5 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node" -version = "0.8.0" +version = "0.8.1" license = "GPL-3.0-only" authors = ["Dan Wiebe ", "MASQ"] description = "MASQ Node is the foundation of MASQ Network, an open-source network that allows anyone to allocate spare computing resources to make the internet a free and fair place for the entire world." diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 09d54ad89..b9bfa37bf 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -579,7 +579,9 @@ where fn web3_gas_limit_const_part(chain: Chain) -> u64 { match chain { Chain::EthMainnet | Chain::EthRopsten | Chain::Dev => 55_000, - Chain::PolyMainnet | Chain::PolyAmoy => 70_000, + Chain::PolyMainnet | Chain::PolyAmoy | Chain::BaseMainnet | Chain::BaseSepolia => { + 70_000 + } } } @@ -676,6 +678,7 @@ mod tests { BlockchainTransaction, RpcPayablesFailure, }; use indoc::indoc; + use sodiumoxide::hex; use std::str::FromStr; use std::sync::{Arc, Mutex}; use std::time::SystemTime; @@ -1629,6 +1632,10 @@ mod tests { 70_000 ); assert_eq!(Subject::web3_gas_limit_const_part(Chain::PolyAmoy), 70_000); + assert_eq!( + Subject::web3_gas_limit_const_part(Chain::BaseSepolia), + 70_000 + ); assert_eq!(Subject::web3_gas_limit_const_part(Chain::Dev), 55_000); } @@ -1842,8 +1849,11 @@ mod tests { let gas_price = match chain { Chain::EthMainnet | Chain::EthRopsten | Chain::Dev => 110, Chain::PolyMainnet | Chain::PolyAmoy => 55, + // It performs on even cheaper fees, but we're + // limited by the units here + Chain::BaseMainnet | Chain::BaseSepolia => 1, }; - let payment_size_wei = 1_000_000_000_000; + let payment_size_wei = gwei_to_wei(1_000_u64); let payable_account = make_payable_account_with_wallet_and_balance_and_timestamp_opt( recipient_wallet, payment_size_wei, @@ -1861,7 +1871,13 @@ mod tests { .unwrap(); let byte_set_to_compare = signed_transaction.raw_transaction.0; - assert_eq!(byte_set_to_compare.as_slice(), template) + assert_eq!( + byte_set_to_compare, + template, + "Actual signed transaction {} does not match {} as expected", + hex::encode(byte_set_to_compare.clone()), + hex::encode(template.to_vec()) + ) } // Transaction with this input was verified on the test network @@ -1879,6 +1895,20 @@ mod tests { assert_that_signed_transactions_agrees_with_template(chain, nonce, &in_bytes) } + #[test] + fn web3_interface_signing_a_transaction_works_for_base_sepolia() { + let chain = Chain::BaseSepolia; + let nonce = 2; + let signed_transaction_data = "\ + f8ac02843b9aca008301198094898e1ce720084a902bc37dd822ed6d6a5f027e1080b844a9059cbb00000000000\ + 00000000000007788df76bbd9a0c7c3e5bf0f77bb28c60a167a7b00000000000000000000000000000000000000\ + 0000000000000000e8d4a510008302948ca07b57223b566ade08ec817770c8b9ae94373edbefc13372c3463cf7b\ + 6ce542231a020991f2ff180a12cbc2745465a4e710da294b890901a3887519b191c3a69cd4f"; + let in_bytes = decode_hex(signed_transaction_data).unwrap(); + + assert_that_signed_transactions_agrees_with_template(chain, nonce, &in_bytes) + } + // Transaction with this input was verified on the test network #[test] fn web3_interface_signing_a_transaction_works_for_eth_ropsten() { @@ -1899,20 +1929,14 @@ mod tests { fn web3_interface_signing_a_transaction_for_polygon_mainnet() { let chain = Chain::PolyMainnet; let nonce = 10; - // Generated locally - let signed_transaction_data = [ - 248, 172, 10, 133, 12, 206, 65, 102, 0, 131, 1, 25, 128, 148, 238, 154, 53, 47, 106, - 172, 74, 241, 165, 185, 244, 103, 246, 169, 62, 15, 251, 233, 221, 53, 128, 184, 68, - 169, 5, 156, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119, 136, 223, 118, 187, 217, - 160, 199, 195, 229, 191, 15, 119, 187, 40, 198, 10, 22, 122, 123, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 212, 165, 16, 0, 130, - 1, 53, 160, 200, 159, 77, 202, 128, 195, 67, 122, 35, 204, 26, 65, 171, 89, 253, 82, 6, - 176, 192, 225, 41, 61, 151, 82, 66, 232, 72, 44, 68, 131, 140, 117, 160, 117, 66, 154, - 132, 183, 97, 219, 131, 214, 72, 220, 66, 152, 72, 15, 107, 44, 237, 193, 16, 193, 52, - 6, 94, 216, 149, 94, 102, 199, 80, 68, 105, - ]; + let signed_transaction_data = "f8ac0a850cce4166008301198094ee9a352f6aac4af1a5b9f467f6a\ + 93e0ffbe9dd3580b844a9059cbb0000000000000000000000007788df76bbd9a0c7c3e5bf0f77bb28c60a167a7b\ + 000000000000000000000000000000000000000000000000000000e8d4a51000820135a0c89f4dca80c3437a23c\ + c1a41ab59fd5206b0c0e1293d975242e8482c44838c75a075429a84b761db83d648dc4298480f6b2cedc110c134\ + 065ed8955e66c7504469"; + let in_bytes = decode_hex(signed_transaction_data).unwrap(); - assert_that_signed_transactions_agrees_with_template(chain, nonce, &signed_transaction_data) + assert_that_signed_transactions_agrees_with_template(chain, nonce, &in_bytes) } // Unconfirmed on the real network @@ -1920,20 +1944,29 @@ mod tests { fn web3_interface_signing_a_transaction_for_eth_mainnet() { let chain = Chain::EthMainnet; let nonce = 10; - // Generated locally - let signed_transaction_data = [ - 248, 169, 10, 133, 25, 156, 130, 204, 0, 130, 222, 232, 148, 6, 243, 195, 35, 240, 35, - 140, 114, 191, 53, 1, 16, 113, 242, 181, 183, 244, 58, 5, 76, 128, 184, 68, 169, 5, - 156, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119, 136, 223, 118, 187, 217, 160, 199, - 195, 229, 191, 15, 119, 187, 40, 198, 10, 22, 122, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 212, 165, 16, 0, 38, 160, 199, - 155, 76, 106, 39, 227, 3, 151, 90, 117, 245, 211, 86, 98, 187, 117, 120, 103, 165, 131, - 99, 72, 36, 211, 10, 224, 252, 104, 51, 200, 230, 158, 160, 84, 18, 140, 248, 119, 22, - 193, 14, 148, 253, 48, 59, 185, 11, 38, 152, 103, 150, 120, 60, 74, 56, 159, 206, 22, - 15, 73, 173, 153, 11, 76, 74, - ]; + let signed_transaction_data = "f8a90a85199c82cc0082dee89406f3c323f0238c72bf35011071f2b\ + 5b7f43a054c80b844a9059cbb0000000000000000000000007788df76bbd9a0c7c3e5bf0f77bb28c60a167a7b00\ + 0000000000000000000000000000000000000000000000000000e8d4a5100026a0c79b4c6a27e303975a75f5d35\ + 662bb757867a583634824d30ae0fc6833c8e69ea054128cf87716c10e94fd303bb90b26986796783c4a389fce16\ + 0f49ad990b4c4a"; + let in_bytes = decode_hex(signed_transaction_data).unwrap(); - assert_that_signed_transactions_agrees_with_template(chain, nonce, &signed_transaction_data) + assert_that_signed_transactions_agrees_with_template(chain, nonce, &in_bytes) + } + + // Unconfirmed on the real network + #[test] + fn web3_interface_signing_a_transaction_for_base_mainnet() { + let chain = Chain::BaseMainnet; + let nonce = 124; + let signed_transaction_data = "f8ab7c843b9aca00830119809445d9c101a3870ca5024582fd788f4\ + e1e8f7971c380b844a9059cbb0000000000000000000000007788df76bbd9a0c7c3e5bf0f77bb28c60a167a7b00\ + 0000000000000000000000000000000000000000000000000000e8d4a5100082422da0587b5f8401225d5cf6267\ + 6f51f376f085805851e2e59c5253eb2834612295bdba05b6963872bac7eeafb38191079e8c8df919c193839022b\ + d57b91ace5a8638034"; + let in_bytes = decode_hex(signed_transaction_data).unwrap(); + + assert_that_signed_transactions_agrees_with_template(chain, nonce, &in_bytes) } // Adapted test from old times when we had our own signing method. diff --git a/node/src/db_config/config_dao.rs b/node/src/db_config/config_dao.rs index 23bd1fce5..759440c42 100644 --- a/node/src/db_config/config_dao.rs +++ b/node/src/db_config/config_dao.rs @@ -180,7 +180,7 @@ mod tests { use crate::database::db_initializer::{DbInitializer, DbInitializerReal}; use crate::database::test_utils::ConnectionWrapperMock; use crate::test_utils::assert_contains; - use masq_lib::constants::{CURRENT_SCHEMA_VERSION, ROPSTEN_TESTNET_CONTRACT_CREATION_BLOCK}; + use masq_lib::constants::{CURRENT_SCHEMA_VERSION, ETH_ROPSTEN_CONTRACT_CREATION_BLOCK}; use masq_lib::test_utils::utils::ensure_node_home_directory_exists; use rusqlite::Connection; use std::path::Path; @@ -205,7 +205,7 @@ mod tests { &result, &ConfigDaoRecord::new( "start_block", - Some(&ROPSTEN_TESTNET_CONTRACT_CREATION_BLOCK.to_string()), + Some(Ð_ROPSTEN_CONTRACT_CREATION_BLOCK.to_string()), false, ), ); diff --git a/node/src/sub_lib/neighborhood.rs b/node/src/sub_lib/neighborhood.rs index dc4872273..d3acc5655 100644 --- a/node/src/sub_lib/neighborhood.rs +++ b/node/src/sub_lib/neighborhood.rs @@ -752,7 +752,7 @@ mod tests { assert_eq!( result, Err( - "Chain identifier 'bitcoin' is not valid; possible values are 'polygon-mainnet', 'eth-mainnet', 'polygon-amoy', 'eth-ropsten' while formatted as 'masq://:@'" + "Chain identifier 'bitcoin' is not valid; possible values are 'polygon-mainnet', 'eth-mainnet', 'base-mainnet', 'base-sepolia', 'polygon-amoy', 'eth-ropsten' while formatted as 'masq://:@'" .to_string() ) ); @@ -851,7 +851,7 @@ mod tests { let result = DescriptorParsingError::WrongChainIdentifier("blah").to_string(); - assert_eq!(result, "Chain identifier 'blah' is not valid; possible values are 'polygon-mainnet', 'eth-mainnet', 'polygon-amoy', 'eth-ropsten' while formatted as 'masq://:@'") + assert_eq!(result, "Chain identifier 'blah' is not valid; possible values are 'polygon-mainnet', 'eth-mainnet', 'base-mainnet', 'base-sepolia', 'polygon-amoy', 'eth-ropsten' while formatted as 'masq://:@'") } #[test] diff --git a/node/tests/contract_test.rs b/node/tests/contract_test.rs index 8e9e74395..42d6fce37 100644 --- a/node/tests/contract_test.rs +++ b/node/tests/contract_test.rs @@ -140,6 +140,32 @@ fn masq_erc20_contract_exists_on_ethereum_mainnet_integration() { assert_contract(blockchain_urls, &chain, assertion_body) } +#[test] +fn masq_erc20_contract_exists_on_base_mainnet_integration() { + let blockchain_urls = vec![ + "https://base-rpc.publicnode.com", + "https://base.drpc.org", + "https://base-pokt.nodies.app", + ]; + let chain = Chain::BaseMainnet; + + let assertion_body = |url, chain| assert_contract_existence(url, chain, "MASQ", 18); + assert_contract(blockchain_urls, &chain, assertion_body) +} + +#[test] +fn masq_erc20_contract_exists_on_base_sepolia_integration() { + let blockchain_urls = vec![ + "https://rpc.ankr.com/base_sepolia", + "https://base-sepolia-rpc.publicnode.com", + "https://base-sepolia.public.blastapi.io", + ]; + let chain = Chain::BaseSepolia; + + let assertion_body = |url, chain| assert_contract_existence(url, chain, "tMASQ", 18); + assert_contract(blockchain_urls, &chain, assertion_body) +} + fn assert_total_supply( blockchain_service_url: &str, chain: &Chain, diff --git a/port_exposer/Cargo.lock b/port_exposer/Cargo.lock index 1f2db3a9d..52e735fac 100644 --- a/port_exposer/Cargo.lock +++ b/port_exposer/Cargo.lock @@ -20,7 +20,7 @@ checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "port_exposer" -version = "0.8.0" +version = "0.8.1" dependencies = [ "default-net", ] diff --git a/port_exposer/Cargo.toml b/port_exposer/Cargo.toml index 042deb104..6f77da5e1 100644 --- a/port_exposer/Cargo.toml +++ b/port_exposer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "port_exposer" -version = "0.8.0" +version = "0.8.1" authors = ["Dan Wiebe ", "MASQ"] license = "GPL-3.0-only" copyright = "Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved." From 91f3b8cb8d0ce26661d8b82059dffcb075ba2cef Mon Sep 17 00:00:00 2001 From: KauriHero Date: Thu, 3 Oct 2024 13:47:51 +1300 Subject: [PATCH 03/56] update readme and tag v0.8.1 (#532) Signed-off-by: KauriHero --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 404cd7573..84fb5ac44 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,7 @@ stage - MASQ Network and it's developers are not responsible for any activity, o ## Source The MASQ project was forked from Substratum's Node project in order to carry on development after Substratum ceased operations in October of 2019. In 2021, Substratum's Node repositories were removed from GitHub, so the fork link -with MASQ was broken, but all credit for the original idea, the original design, and the first two years of MASQ's -development belongs to Substratum. +with MASQ was broken, but all credit for the original idea and the original design belongs to Substratum (and properly attributed through GPLv3 license) ## Running the MASQ Node @@ -452,6 +451,4 @@ recommend using a 64-bit version to build. We do plan to release binaries that will run on 32-bit Windows, but they will likely be built on 64-bit Windows. -Copyright (c) 2019-2022, MASQ Network - -Copyright (c) 2017-2019, Substratum LLC and/or its affiliates. All rights reserved. +Copyright (c) 2019-2024, MASQ Network From f5572f30f8297d8abad8b9548d8b187b0cb8f3e5 Mon Sep 17 00:00:00 2001 From: Utkarsh Gupta <32920299+utkarshg6@users.noreply.github.com> Date: Tue, 8 Oct 2024 09:07:17 +0530 Subject: [PATCH 04/56] GH-524: Disable `entry_dns` (#526) --- node/src/server_initializer.rs | 45 +++++++++++++++++-------------- node/tests/dns_round_trip_test.rs | 4 +++ 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/node/src/server_initializer.rs b/node/src/server_initializer.rs index 2f2c5f320..ea288fdce 100644 --- a/node/src/server_initializer.rs +++ b/node/src/server_initializer.rs @@ -28,6 +28,7 @@ use time::OffsetDateTime; use tokio::prelude::{Async, Future}; pub struct ServerInitializerReal { + #[allow(dead_code)] dns_socket_server: Box>, bootstrapper: Box>, privilege_dropper: Box, @@ -42,12 +43,13 @@ impl ServerInitializer for ServerInitializerReal { let data_directory = value_m!(multi_config, "data-directory", String) .expect("ServerInitializer: Data directory not present in Multi Config"); + // TODO: GH-525: This card should bring back the commented out code for dns_socket_server let result: RunModeResult = Ok(()) - .combine_results( - self.dns_socket_server - .as_mut() - .initialize_as_privileged(&multi_config), - ) + // .combine_results( + // self.dns_socket_server + // .as_mut() + // .initialize_as_privileged(&multi_config), + // ) .combine_results( self.bootstrapper .as_mut() @@ -60,11 +62,11 @@ impl ServerInitializer for ServerInitializerReal { self.privilege_dropper.drop_privileges(&real_user); result - .combine_results( - self.dns_socket_server - .as_mut() - .initialize_as_unprivileged(&multi_config, streams), - ) + // .combine_results( + // self.dns_socket_server + // .as_mut() + // .initialize_as_unprivileged(&multi_config, streams), + // ) .combine_results( self.bootstrapper .as_mut() @@ -79,11 +81,12 @@ impl Future for ServerInitializerReal { type Error = (); fn poll(&mut self) -> Result::Item>, ::Error> { - try_ready!(self - .dns_socket_server - .as_mut() - .join(self.bootstrapper.as_mut()) - .poll()); + // try_ready!(self + // .dns_socket_server + // .as_mut() + // .join(self.bootstrapper.as_mut()) + // .poll()); + try_ready!(self.bootstrapper.as_mut().poll()); Ok(Async::Ready(())) } } @@ -726,7 +729,8 @@ pub mod tests { } #[test] - #[should_panic(expected = "EntryDnsServerMock was instructed to panic")] + // TODO: GH-525: It should panic + // #[should_panic(expected = "EntryDnsServerMock was instructed to panic")] fn server_initializer_dns_socket_server_panics() { let bootstrapper = CrashTestDummy::new(CrashPoint::None, BootstrapperConfig::new()); let privilege_dropper = PrivilegeDropperMock::new(); @@ -840,8 +844,8 @@ pub mod tests { [ bootstrapper_init_privileged_params_arc, bootstrapper_init_unprivileged_params_arc, - dns_socket_server_privileged_params_arc, - dns_socket_server_unprivileged_params_arc, + // dns_socket_server_privileged_params_arc, // TODO: GH-525: Fix me + // dns_socket_server_unprivileged_params_arc, ] .iter() .for_each(|arc_params| { @@ -889,12 +893,13 @@ pub mod tests { let result = subject.go(&mut holder.streams(), &args); + // TODO: GH-525: Fix me assert_eq!( result, Err(ConfiguratorError::new(vec![ - ParamError::new("dns-iap", "dns-iap-reason"), + // ParamError::new("dns-iap", "dns-iap-reason"), ParamError::new("boot-iap", "boot-iap-reason"), - ParamError::new("dns-iau", "dns-iau-reason"), + // ParamError::new("dns-iau", "dns-iau-reason"), ParamError::new("boot-iau", "boot-iau-reason") ])) ); diff --git a/node/tests/dns_round_trip_test.rs b/node/tests/dns_round_trip_test.rs index c3c82c297..7d32e0892 100644 --- a/node/tests/dns_round_trip_test.rs +++ b/node/tests/dns_round_trip_test.rs @@ -9,6 +9,8 @@ use trust_dns::op::{OpCode, ResponseCode}; use trust_dns::rr::{DNSClass, RecordType}; #[test] +// TODO This ignore should be lifted by GH-525 +#[ignore] #[serial(port53)] fn handles_two_consecutive_ipv4_dns_requests_integration() { let _node = utils::MASQNode::start_standard( @@ -25,6 +27,8 @@ fn handles_two_consecutive_ipv4_dns_requests_integration() { } #[test] +// TODO This ignore should be lifted by GH-525 +#[ignore] #[serial(port53)] fn handles_consecutive_heterogeneous_dns_requests_integration() { let _node = utils::MASQNode::start_standard( From 7693d004cc0d10966ecfd75ef7912c5a1de3aad7 Mon Sep 17 00:00:00 2001 From: Utkarsh Gupta <32920299+utkarshg6@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:35:04 +0530 Subject: [PATCH 05/56] GH-539: Don't Panic! (#540) * GH-539: Don't Panic * GH-539: remove commented out code --- .../neighborhood/overall_connection_status.rs | 81 +++++++++++++------ 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/node/src/neighborhood/overall_connection_status.rs b/node/src/neighborhood/overall_connection_status.rs index 18e5b2a13..abb533f8c 100644 --- a/node/src/neighborhood/overall_connection_status.rs +++ b/node/src/neighborhood/overall_connection_status.rs @@ -93,21 +93,28 @@ impl ConnectionProgress { } pub fn handle_pass_gossip(&mut self, logger: &Logger, new_pass_target: IpAddr) { - if self.connection_stage != ConnectionStage::TcpConnectionEstablished { - panic!( - "Can't update the stage from {:?} to {:?}", + let preliminary_msg = format!( + "Pass gossip received from Node with IP Address {:?} to a Node with IP Address {:?}", + self.current_peer_addr, new_pass_target, + ); + match self.connection_stage { + ConnectionStage::StageZero => { + error!( + logger, + "{preliminary_msg}. Requested to update the stage from StageZero to StageZero.", + ) + } + ConnectionStage::TcpConnectionEstablished => { + debug!( + logger, + "{preliminary_msg}. Updating the stage from TcpConnectionEstablished to StageZero.", + ) + } + _ => panic!( + "{preliminary_msg}. Can't update the stage from {:?} to StageZero", self.connection_stage, - ConnectionStage::StageZero - ) - }; - - debug!( - logger, - "Pass gossip received from Node with IP Address {:?} to a Node with IP Address {:?}. \ - Hence, updating the connection stage of the new Node to StageZero.", - self.current_peer_addr, - new_pass_target - ); + ), + } self.connection_stage = ConnectionStage::StageZero; self.current_peer_addr = new_pass_target; @@ -351,13 +358,13 @@ mod tests { #[test] fn connection_progress_handles_pass_gossip_correctly_and_performs_logging_in_order() { init_test_logging(); + let test_name = + "connection_progress_handles_pass_gossip_correctly_and_performs_logging_in_order"; let ip_addr = make_ip(1); let initial_node_descriptor = make_node_descriptor(ip_addr); let mut subject = ConnectionProgress::new(initial_node_descriptor.clone()); let pass_target = make_ip(2); - let logger = Logger::new( - "connection_progress_handles_pass_gossip_correctly_and_performs_logging_in_order", - ); + let logger = Logger::new(test_name); subject.update_stage(&logger, ConnectionStage::TcpConnectionEstablished); subject.handle_pass_gossip(&logger, pass_target); @@ -372,29 +379,57 @@ mod tests { ); TestLogHandler::new().assert_logs_contain_in_order(vec![ &format!( - "DEBUG: connection_progress_handles_pass_gossip_correctly_and\ - _performs_logging_in_order: The connection stage \ + "DEBUG: {test_name}: The connection stage \ for Node with IP address {:?} has been updated from {:?} to {:?}.", ip_addr, ConnectionStage::StageZero, ConnectionStage::TcpConnectionEstablished ), &format!( - "DEBUG: connection_progress_handles_pass_gossip_correctly_and_performs_logging\ - _in_order: Pass gossip received from Node with IP Address {:?} to a Node with \ - IP Address {:?}. Hence, updating the connection stage of the new Node to StageZero.", + "DEBUG: {test_name}: Pass gossip received from Node with IP Address {:?} to a Node with \ + IP Address {:?}. Updating the stage from TcpConnectionEstablished to StageZero.", ip_addr, pass_target ), ]); } #[test] - #[should_panic(expected = "Can't update the stage from StageZero to StageZero")] + fn connection_progress_logs_error_while_handling_pass_gossip_in_case_tcp_connection_is_not_established( + ) { + init_test_logging(); + let test_name = "connection_progress_logs_error_while_handling_pass_gossip_in_case_tcp_connection_is_not_established"; + let ip_addr = make_ip(1); + let initial_node_descriptor = make_node_descriptor(ip_addr); + let mut subject = ConnectionProgress::new(initial_node_descriptor.clone()); + let pass_target = make_ip(2); + + subject.handle_pass_gossip(&Logger::new(test_name), pass_target); + + assert_eq!( + subject, + ConnectionProgress { + initial_node_descriptor, + current_peer_addr: pass_target, + connection_stage: ConnectionStage::StageZero + } + ); + TestLogHandler::new().exists_log_containing(&format!( + "ERROR: {test_name}: Pass gossip received from Node with IP Address 1.1.1.1 to a Node \ + with IP Address 1.1.1.2. Requested to update the stage from StageZero to StageZero." + )); + } + + #[test] + #[should_panic( + expected = "Pass gossip received from Node with IP Address 1.1.1.1 to a Node \ + with IP Address 1.1.1.2. Can't update the stage from NeighborshipEstablished to StageZero" + )] fn connection_progress_panics_while_handling_pass_gossip_in_case_tcp_connection_is_not_established( ) { let ip_addr = make_ip(1); let initial_node_descriptor = make_node_descriptor(ip_addr); let mut subject = ConnectionProgress::new(initial_node_descriptor); + subject.connection_stage = ConnectionStage::NeighborshipEstablished; let pass_target = make_ip(2); subject.handle_pass_gossip(&Logger::new("test"), pass_target); From 8ad336d4b81a84ff2cfbae01aa504e98e1b170d6 Mon Sep 17 00:00:00 2001 From: Utkarsh Gupta <32920299+utkarshg6@users.noreply.github.com> Date: Tue, 15 Oct 2024 12:47:00 +0530 Subject: [PATCH 06/56] New Version: v0.8.2 (#542) --- automap/Cargo.lock | 4 ++-- automap/Cargo.toml | 2 +- dns_utility/Cargo.lock | 4 ++-- dns_utility/Cargo.toml | 2 +- masq/Cargo.toml | 2 +- masq_lib/Cargo.toml | 2 +- multinode_integration_tests/Cargo.toml | 2 +- node/Cargo.lock | 10 +++++----- node/Cargo.toml | 2 +- port_exposer/Cargo.lock | 2 +- port_exposer/Cargo.toml | 2 +- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/automap/Cargo.lock b/automap/Cargo.lock index 63c58616e..73d051ebb 100644 --- a/automap/Cargo.lock +++ b/automap/Cargo.lock @@ -137,7 +137,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "automap" -version = "0.8.1" +version = "0.8.2" dependencies = [ "crossbeam-channel 0.5.8", "flexi_logger", @@ -1051,7 +1051,7 @@ dependencies = [ [[package]] name = "masq_lib" -version = "0.8.1" +version = "0.8.2" dependencies = [ "actix", "clap", diff --git a/automap/Cargo.toml b/automap/Cargo.toml index 1275d9e8d..21c1acf91 100644 --- a/automap/Cargo.toml +++ b/automap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "automap" -version = "0.8.1" +version = "0.8.2" authors = ["Dan Wiebe ", "MASQ"] license = "GPL-3.0-only" description = "Library full of code to make routers map ports through firewalls" diff --git a/dns_utility/Cargo.lock b/dns_utility/Cargo.lock index 970263d93..59f5a3bda 100644 --- a/dns_utility/Cargo.lock +++ b/dns_utility/Cargo.lock @@ -430,7 +430,7 @@ dependencies = [ [[package]] name = "dns_utility" -version = "0.8.1" +version = "0.8.2" dependencies = [ "core-foundation", "ipconfig 0.2.2", @@ -854,7 +854,7 @@ dependencies = [ [[package]] name = "masq_lib" -version = "0.8.1" +version = "0.8.2" dependencies = [ "actix", "clap", diff --git a/dns_utility/Cargo.toml b/dns_utility/Cargo.toml index 21e5cbc8c..50f358db8 100644 --- a/dns_utility/Cargo.toml +++ b/dns_utility/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dns_utility" -version = "0.8.1" +version = "0.8.2" license = "GPL-3.0-only" authors = ["Dan Wiebe ", "MASQ"] copyright = "Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved." diff --git a/masq/Cargo.toml b/masq/Cargo.toml index 9f3e2ab46..9a4fca0c1 100644 --- a/masq/Cargo.toml +++ b/masq/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "masq" -version = "0.8.1" +version = "0.8.2" authors = ["Dan Wiebe ", "MASQ"] license = "GPL-3.0-only" description = "Reference implementation of user interface for MASQ Node" diff --git a/masq_lib/Cargo.toml b/masq_lib/Cargo.toml index 7917eb744..af1fd5d15 100644 --- a/masq_lib/Cargo.toml +++ b/masq_lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "masq_lib" -version = "0.8.1" +version = "0.8.2" authors = ["Dan Wiebe ", "MASQ"] license = "GPL-3.0-only" description = "Code common to Node and masq; also, temporarily, to dns_utility" diff --git a/multinode_integration_tests/Cargo.toml b/multinode_integration_tests/Cargo.toml index 05bb47051..18bb5a16d 100644 --- a/multinode_integration_tests/Cargo.toml +++ b/multinode_integration_tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multinode_integration_tests" -version = "0.8.1" +version = "0.8.2" authors = ["Dan Wiebe ", "MASQ"] license = "GPL-3.0-only" description = "" diff --git a/node/Cargo.lock b/node/Cargo.lock index 20fda85c6..63e2b2029 100644 --- a/node/Cargo.lock +++ b/node/Cargo.lock @@ -182,7 +182,7 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "automap" -version = "0.8.1" +version = "0.8.2" dependencies = [ "crossbeam-channel 0.5.1", "flexi_logger 0.17.1", @@ -1802,7 +1802,7 @@ dependencies = [ [[package]] name = "masq" -version = "0.8.1" +version = "0.8.2" dependencies = [ "atty", "clap", @@ -1822,7 +1822,7 @@ dependencies = [ [[package]] name = "masq_lib" -version = "0.8.1" +version = "0.8.2" dependencies = [ "actix", "clap", @@ -1999,7 +1999,7 @@ dependencies = [ [[package]] name = "multinode_integration_tests" -version = "0.8.1" +version = "0.8.2" dependencies = [ "base64 0.13.0", "crossbeam-channel 0.5.1", @@ -2092,7 +2092,7 @@ dependencies = [ [[package]] name = "node" -version = "0.8.1" +version = "0.8.2" dependencies = [ "actix", "automap", diff --git a/node/Cargo.toml b/node/Cargo.toml index 44dadafe5..7d01fd728 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node" -version = "0.8.1" +version = "0.8.2" license = "GPL-3.0-only" authors = ["Dan Wiebe ", "MASQ"] description = "MASQ Node is the foundation of MASQ Network, an open-source network that allows anyone to allocate spare computing resources to make the internet a free and fair place for the entire world." diff --git a/port_exposer/Cargo.lock b/port_exposer/Cargo.lock index 52e735fac..210c0de54 100644 --- a/port_exposer/Cargo.lock +++ b/port_exposer/Cargo.lock @@ -20,7 +20,7 @@ checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "port_exposer" -version = "0.8.1" +version = "0.8.2" dependencies = [ "default-net", ] diff --git a/port_exposer/Cargo.toml b/port_exposer/Cargo.toml index 6f77da5e1..a5eab68f0 100644 --- a/port_exposer/Cargo.toml +++ b/port_exposer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "port_exposer" -version = "0.8.1" +version = "0.8.2" authors = ["Dan Wiebe ", "MASQ"] license = "GPL-3.0-only" copyright = "Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved." From 3d35b4c498be99888940f905cc653ca830e36e66 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 21 Oct 2024 23:50:02 +1300 Subject: [PATCH 07/56] GH-744: Review-1 first lot of changes --- .../startup_shutdown_tests_integration.rs | 2 +- node/src/accountant/mod.rs | 15 +-- .../payable_scanner/agent_web3.rs | 2 +- node/src/blockchain/batch_web3.rs | 3 - node/src/blockchain/blockchain_bridge.rs | 2 +- .../lower_level_interface_web3.rs | 91 +------------------ .../lower_level_interface.rs | 13 +-- .../blockchain_interface/test_utils.rs | 9 +- node/src/blockchain/mod.rs | 4 +- node/tests/utils.rs | 5 +- 10 files changed, 24 insertions(+), 122 deletions(-) delete mode 100644 node/src/blockchain/batch_web3.rs diff --git a/masq/tests/startup_shutdown_tests_integration.rs b/masq/tests/startup_shutdown_tests_integration.rs index a152ec8a4..c66589130 100644 --- a/masq/tests/startup_shutdown_tests_integration.rs +++ b/masq/tests/startup_shutdown_tests_integration.rs @@ -116,7 +116,7 @@ fn handles_startup_and_shutdown_integration() { "--data-directory", dir_path.to_str().unwrap(), "--blockchain-service-url", - "https://example.com", + "https://nonexistentblockchainservice.com", ]); let (stdout, stderr, exit_code) = masq_handle.stop(); diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index 1e7a16a81..6607c622b 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -1597,6 +1597,10 @@ mod tests { context_id: 4321, }) ); + assert_eq!( + payments_instructions.agent.arbitrary_id_stamp(), + agent_id_stamp + ); assert_eq!(blockchain_bridge_recording.len(), 1); test_use_of_the_same_logger(&logger_clone, test_name) // adjust_payments() did not need a prepared result which means it wasn't reached @@ -1709,6 +1713,10 @@ mod tests { let blockchain_bridge_recording = blockchain_bridge_recording_arc.lock().unwrap(); let payments_instructions = blockchain_bridge_recording.get_record::(0); + assert_eq!( + payments_instructions.agent.arbitrary_id_stamp(), + agent_id_stamp_second_phase + ); assert_eq!( payments_instructions.affordable_accounts, affordable_accounts @@ -3510,7 +3518,6 @@ mod tests { ) .end_batch() .start(); - let non_pending_payables_params_arc = Arc::new(Mutex::new(vec![])); let mark_pending_payable_params_arc = Arc::new(Mutex::new(vec![])); let return_all_errorless_fingerprints_params_arc = Arc::new(Mutex::new(vec![])); @@ -3628,8 +3635,6 @@ mod tests { no_rowid_results: vec![], }); let mut pending_payable_dao_for_pending_payable_scanner = PendingPayableDaoMock::new() - .insert_fingerprints_result(Ok(())) - .insert_fingerprints_result(Ok(())) .return_all_errorless_fingerprints_params(&return_all_errorless_fingerprints_params_arc) .return_all_errorless_fingerprints_result(vec![]) .return_all_errorless_fingerprints_result(vec![ @@ -3706,9 +3711,7 @@ mod tests { assert_eq!(system.run(), 0); let mut mark_pending_payable_params = mark_pending_payable_params_arc.lock().unwrap(); - let mut one_set_of_mark_pending_payable_params = mark_pending_payable_params.remove(0); - assert!(mark_pending_payable_params.is_empty()); let first_payable = one_set_of_mark_pending_payable_params.remove(0); assert_eq!(first_payable.0, wallet_account_1); @@ -3864,7 +3867,6 @@ mod tests { let amount_1 = 12345; let hash_2 = make_tx_hash(0x1b207); let amount_2 = 87654; - let hash_and_amount_1 = HashAndAmount { hash: hash_1, amount: amount_1, @@ -3873,7 +3875,6 @@ mod tests { hash: hash_2, amount: amount_2, }; - let init_params = vec![hash_and_amount_1, hash_and_amount_2]; let init_fingerprints_msg = PendingPayableFingerprintSeeds { batch_wide_timestamp: timestamp, diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs index 846a8b342..5f6afa4ad 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs @@ -5,7 +5,7 @@ use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; use web3::types::U256; -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone)] pub struct BlockchainAgentWeb3 { gas_price_gwei: u64, gas_limit_const_part: u64, diff --git a/node/src/blockchain/batch_web3.rs b/node/src/blockchain/batch_web3.rs deleted file mode 100644 index 0487be8de..000000000 --- a/node/src/blockchain/batch_web3.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub trait BatchWeb3 { - fn submit_batch(&self) {} -} diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index ae89f1b79..26d0edf54 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -393,7 +393,7 @@ impl BlockchainBridge { Box::new( self.blockchain_interface .lower_interface() - .get_transaction_receipt_batch(transaction_hashes) + .get_transaction_receipt_in_batch(transaction_hashes) .map_err(move |e| e.to_string()) .and_then(move |transaction_receipts_results| { let length = transaction_receipts_results.len(); diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index cfe79e092..46ab9ace4 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -92,19 +92,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } - fn get_transaction_receipt( - &self, - hash: H256, - ) -> Box, Error = BlockchainError>> { - Box::new( - self.web3 - .eth() - .transaction_receipt(hash) - .map_err(|e| QueryFailed(e.to_string())), - ) - } - - fn get_transaction_receipt_batch( + fn get_transaction_receipt_in_batch( &self, hash_vec: Vec, ) -> Box, Error = BlockchainError>> { @@ -431,79 +419,6 @@ mod tests { ) } - #[test] - fn transaction_receipt_works() { - let port = find_free_port(); - let tx_hash = - H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0e") - .unwrap(); - let block_hash = - H256::from_str("6d0abccae617442c26104c2bc63d1bc05e1e002e555aec4ab62a46e826b18f18") - .unwrap(); - let block_number = U64::from_str("b0328d").unwrap(); - let cumulative_gas_used = U256::from_str("60ef").unwrap(); - let gas_used = U256::from_str("60ef").unwrap(); - let status = U64::from(0); - let tx_receipt_response = ReceiptResponseBuilder::default() - .transaction_hash(tx_hash) - .block_hash(block_hash) - .block_number(block_number) - .cumulative_gas_used(cumulative_gas_used) - .gas_used(gas_used) - .status(status) - .build(); - let _blockchain_client_server = MBCSBuilder::new(port) - .raw_response(tx_receipt_response) - .start(); - let subject = make_blockchain_interface_web3(Some(port)); - - let result = subject - .lower_interface() - .get_transaction_receipt(tx_hash) - .wait(); - - let expected_receipt = TransactionReceipt { - transaction_hash: tx_hash, - transaction_index: Default::default(), - block_hash: Some(block_hash), - block_number: Some(block_number), - cumulative_gas_used, - gas_used: Some(gas_used), - contract_address: None, - logs: vec![], - status: Some(status), - root: None, - logs_bloom: Default::default(), - }; - assert_eq!(result, Ok(Some(expected_receipt))); - } - - #[test] - fn get_transaction_receipt_handles_errors() { - let port = find_free_port(); - let subject = make_blockchain_interface_web3(Some(port)); - let tx_hash = make_tx_hash(4564546); - - let actual_error = subject - .lower_interface() - .get_transaction_receipt(tx_hash) - .wait() - .unwrap_err(); - let error_message = if let BlockchainError::QueryFailed(em) = actual_error { - em - } else { - panic!("Expected BlockchainError::QueryFailed(msg)"); - }; - assert_string_contains( - error_message.as_str(), - "Transport error: Error(Connect, Os { code: ", - ); - assert_string_contains( - error_message.as_str(), - ", kind: ConnectionRefused, message: ", - ); - } - #[test] fn transaction_receipt_batch_works() { let port = find_free_port(); @@ -554,7 +469,7 @@ mod tests { let result = subject .lower_interface() - .get_transaction_receipt_batch(tx_hash_vec) + .get_transaction_receipt_in_batch(tx_hash_vec) .wait() .unwrap(); @@ -599,7 +514,7 @@ mod tests { let result = subject .lower_interface() - .get_transaction_receipt_batch(tx_hash_vec) + .get_transaction_receipt_in_batch(tx_hash_vec) .wait() .unwrap_err(); diff --git a/node/src/blockchain/blockchain_interface/lower_level_interface.rs b/node/src/blockchain/blockchain_interface/lower_level_interface.rs index 58b75f5f8..17cb36551 100644 --- a/node/src/blockchain/blockchain_interface/lower_level_interface.rs +++ b/node/src/blockchain/blockchain_interface/lower_level_interface.rs @@ -7,7 +7,7 @@ use ethereum_types::{H256, U64}; use futures::Future; use web3::contract::Contract; use web3::transports::Http; -use web3::types::{Address, Filter, Log, TransactionReceipt, U256}; +use web3::types::{Address, Filter, Log, U256}; use masq_lib::blockchains::chains::Chain; use masq_lib::logger::Logger; use crate::accountant::db_access_objects::payable_dao::PayableAccount; @@ -38,14 +38,9 @@ pub trait LowBlockchainInt { address: Address, ) -> Box>; - fn get_transaction_receipt( - &self, - hash: H256, - ) -> Box, Error = BlockchainError>>; - - fn get_transaction_receipt_batch( - &self, - hash_vec: Vec, + fn get_transaction_receipt_in_batch( + &self, + hash_vec: Vec, ) -> Box, Error = BlockchainError>>; fn get_contract(&self) -> Contract; diff --git a/node/src/blockchain/blockchain_interface/test_utils.rs b/node/src/blockchain/blockchain_interface/test_utils.rs index 824a63a4a..321d6f4f3 100644 --- a/node/src/blockchain/blockchain_interface/test_utils.rs +++ b/node/src/blockchain/blockchain_interface/test_utils.rs @@ -62,14 +62,7 @@ impl LowBlockchainInt for LowBlockchainIntMock { unimplemented!("not needed so far") } - fn get_transaction_receipt( - &self, - _hash: H256, - ) -> Box, Error = BlockchainError>> { - unimplemented!("not needed so far") - } - - fn get_transaction_receipt_batch( + fn get_transaction_receipt_in_batch( &self, _hash_vec: Vec, ) -> Box, Error = BlockchainError>> { diff --git a/node/src/blockchain/mod.rs b/node/src/blockchain/mod.rs index 5415cd56d..20435b48b 100644 --- a/node/src/blockchain/mod.rs +++ b/node/src/blockchain/mod.rs @@ -4,10 +4,8 @@ pub mod bip39; pub mod blockchain_bridge; pub mod blockchain_interface; pub mod blockchain_interface_initializer; +mod blockchain_interface_utils; pub mod payer; pub mod signature; - -mod batch_web3; -mod blockchain_interface_utils; #[cfg(test)] pub mod test_utils; diff --git a/node/tests/utils.rs b/node/tests/utils.rs index e5199b3c6..adeec8c7e 100644 --- a/node/tests/utils.rs +++ b/node/tests/utils.rs @@ -485,7 +485,10 @@ impl MASQNode { "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", ) .pair("--log-level", "trace") - .pair("--blockchain-service-url", "https://example.com") + .pair( + "--blockchain-service-url", + "https://nonexistentblockchainservice.com", + ) .args } From cc709be56f9ac09f1cf18dd6a7e30415627eae55 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Tue, 22 Oct 2024 20:29:09 +1300 Subject: [PATCH 08/56] GH-744: Review-1 - fixed more tests --- .../blockchain_interface/blockchain_interface_web3/mod.rs | 1 + node/src/blockchain/blockchain_interface_initializer.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 930ed9ba3..c62bf448c 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -158,6 +158,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { get_gas_price .map_err(BlockchainAgentBuildError::GasPrice) .and_then(move |gas_price_wei| { + eprintln!("gas_price_wei: {}", gas_price_wei); get_transaction_fee_balance .map_err(move |e| { BlockchainAgentBuildError::TransactionFeeBalance(wallet_address, e) diff --git a/node/src/blockchain/blockchain_interface_initializer.rs b/node/src/blockchain/blockchain_interface_initializer.rs index f7d002497..08aca8daa 100644 --- a/node/src/blockchain/blockchain_interface_initializer.rs +++ b/node/src/blockchain/blockchain_interface_initializer.rs @@ -63,7 +63,7 @@ mod tests { fn initialize_web3_interface_works() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0) + .response("0x3B9ACA00".to_string(), 0)// gas_price = 10000000000 .response("0xFF40".to_string(), 0) .response( "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), From e9bddc8103d54846771319235e48cb4775391f0f Mon Sep 17 00:00:00 2001 From: Syther007 Date: Tue, 22 Oct 2024 21:32:49 +1300 Subject: [PATCH 09/56] GH-744: improved wildcard IP check --- .../blockchain_interface_web3/mod.rs | 1 - .../src/blockchain/blockchain_interface_initializer.rs | 10 +++++++++- node/src/neighborhood/mod.rs | 10 ++++++---- node/src/test_utils/persistent_configuration_mock.rs | 4 ++-- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index c62bf448c..930ed9ba3 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -158,7 +158,6 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { get_gas_price .map_err(BlockchainAgentBuildError::GasPrice) .and_then(move |gas_price_wei| { - eprintln!("gas_price_wei: {}", gas_price_wei); get_transaction_fee_balance .map_err(move |e| { BlockchainAgentBuildError::TransactionFeeBalance(wallet_address, e) diff --git a/node/src/blockchain/blockchain_interface_initializer.rs b/node/src/blockchain/blockchain_interface_initializer.rs index 08aca8daa..aee2f9c92 100644 --- a/node/src/blockchain/blockchain_interface_initializer.rs +++ b/node/src/blockchain/blockchain_interface_initializer.rs @@ -62,7 +62,7 @@ mod tests { #[test] fn initialize_web3_interface_works() { let port = find_free_port(); - let _blockchain_client_server = MBCSBuilder::new(port) + let blockchain_client_server = MBCSBuilder::new(port) .response("0x3B9ACA00".to_string(), 0)// gas_price = 10000000000 .response("0xFF40".to_string(), 0) .response( @@ -83,6 +83,14 @@ mod tests { .wait() .unwrap(); + // TODO: GH-543 will improve MBCS to be stronger by validating each response via its request parameters. + let mbcs_requests = blockchain_client_server.requests(); + assert_eq! (mbcs_requests, vec! [ + "POST / HTTP/1.1\r\ncontent-type: application/json\r\nuser-agent: web3.rs\r\ncontent-length: 60\r\nhost: 127.0.0.1:32768\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":0}".to_string(), + "POST / HTTP/1.1\r\ncontent-type: application/json\r\nuser-agent: web3.rs\r\ncontent-length: 115\r\nhost: 127.0.0.1:32768\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBalance\",\"params\":[\"0x0000000000000000000000000000000000313233\",\"latest\"],\"id\":1}".to_string(), + "POST / HTTP/1.1\r\ncontent-type: application/json\r\nuser-agent: web3.rs\r\ncontent-length: 200\r\nhost: 127.0.0.1:32768\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"eth_call\",\"params\":[{\"data\":\"0x70a082310000000000000000000000000000000000000000000000000000000000313233\",\"to\":\"0xee9a352f6aac4af1a5b9f467f6a93e0ffbe9dd35\"},\"latest\"],\"id\":2}".to_string(), + "POST / HTTP/1.1\r\ncontent-type: application/json\r\nuser-agent: web3.rs\r\ncontent-length: 125\r\nhost: 127.0.0.1:32768\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\":[\"0x0000000000000000000000000000000000313233\",\"pending\"],\"id\":3}".to_string() + ]); assert_eq!(blockchain_agent.consuming_wallet(), &wallet); assert_eq!(blockchain_agent.agreed_fee_per_computation_unit(), 2); } diff --git a/node/src/neighborhood/mod.rs b/node/src/neighborhood/mod.rs index 09d007ab7..553ff785b 100644 --- a/node/src/neighborhood/mod.rs +++ b/node/src/neighborhood/mod.rs @@ -10,7 +10,7 @@ pub mod overall_connection_status; use std::collections::HashSet; use std::convert::TryFrom; -use std::net::{IpAddr, SocketAddr}; +use std::net::{AddrParseError, IpAddr, Ipv4Addr, SocketAddr}; use std::path::PathBuf; use actix::Context; @@ -508,9 +508,11 @@ impl Neighborhood { fn handle_route_query_message(&mut self, msg: RouteQueryMessage) -> Option { if let Some(ref url) = msg.hostname_opt { - if url.contains("0.0.0.0") { - error!(self.logger, "Request to wildcard IP detected 0.0.0.0. Most likely because Blockchain Service URL is not set"); - return None; + if let Ok(ip) = url.parse::() { + if ip == IpAddr::V4(Ipv4Addr::new(0,0,0,0)) { + error!(self.logger, "Request to wildcard IP detected 0.0.0.0. Most likely because Blockchain Service URL is not set"); + return None; + } } } diff --git a/node/src/test_utils/persistent_configuration_mock.rs b/node/src/test_utils/persistent_configuration_mock.rs index 00c50e7c2..c1e63bb7a 100644 --- a/node/src/test_utils/persistent_configuration_mock.rs +++ b/node/src/test_utils/persistent_configuration_mock.rs @@ -678,8 +678,8 @@ impl PersistentConfigurationMock { set_arbitrary_id_stamp_in_mock_impl!(); - // TODO: Review this, maybe we should return an error instead of panic? - // Also unsure why we have the else if clause. + // result_from allows a tester to push only a single value that can then be called multiple times. + // as opposed to pushing the same value for every call. fn result_from(results: &RefCell>) -> T { let mut borrowed = results.borrow_mut(); if borrowed.is_empty() { From b72c61bb7d9e42c822cf4d422d4d0cdec45fcb2b Mon Sep 17 00:00:00 2001 From: Syther007 Date: Tue, 22 Oct 2024 21:38:09 +1300 Subject: [PATCH 10/56] GH-744: removed unused imports --- .../blockchain_interface_web3/lower_level_interface_web3.rs | 4 ++-- node/src/blockchain/blockchain_interface/test_utils.rs | 2 +- node/src/neighborhood/mod.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index 46ab9ace4..4f0020389 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -208,8 +208,8 @@ mod tests { use crate::blockchain::blockchain_interface::blockchain_interface_web3::TRANSACTION_LITERAL; use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError::QueryFailed; - use crate::blockchain::test_utils::{make_blockchain_interface_web3, make_tx_hash, ReceiptResponseBuilder}; - use crate::test_utils::{assert_string_contains, make_wallet}; + use crate::blockchain::test_utils::{make_blockchain_interface_web3, ReceiptResponseBuilder}; + use crate::test_utils::make_wallet; #[test] fn get_transaction_fee_balance_works() { diff --git a/node/src/blockchain/blockchain_interface/test_utils.rs b/node/src/blockchain/blockchain_interface/test_utils.rs index 321d6f4f3..9f24b704d 100644 --- a/node/src/blockchain/blockchain_interface/test_utils.rs +++ b/node/src/blockchain/blockchain_interface/test_utils.rs @@ -12,7 +12,7 @@ use ethereum_types::{H256, U256, U64}; use futures::Future; use web3::contract::Contract; use web3::transports::Http; -use web3::types::{Address, Filter, Log, TransactionReceipt}; +use web3::types::{Address, Filter, Log}; use masq_lib::blockchains::chains::Chain; use masq_lib::logger::Logger; use crate::accountant::db_access_objects::payable_dao::PayableAccount; diff --git a/node/src/neighborhood/mod.rs b/node/src/neighborhood/mod.rs index 553ff785b..8c3c2d522 100644 --- a/node/src/neighborhood/mod.rs +++ b/node/src/neighborhood/mod.rs @@ -10,7 +10,7 @@ pub mod overall_connection_status; use std::collections::HashSet; use std::convert::TryFrom; -use std::net::{AddrParseError, IpAddr, Ipv4Addr, SocketAddr}; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::path::PathBuf; use actix::Context; From d4c5be9dd8f83e662d9461a71ff619a8e54a6901 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Sat, 26 Oct 2024 00:31:23 +1300 Subject: [PATCH 11/56] GH-744: fixed a bunch more comments from review 1 --- .../mock_blockchain_client_server.rs | 13 +- .../src/mock_blockchain_client_server.rs | 17 +- .../tests/blockchain_interaction_test.rs | 2 +- node/src/accountant/scanners/mod.rs | 4 +- .../batch_payable_tools.rs | 1 - .../lower_level_interface_web3.rs | 1 + .../blockchain_interface_web3/mod.rs | 58 ++-- .../lower_level_interface.rs | 1 + .../blockchain_interface/test_utils.rs | 266 +++++++++--------- .../blockchain_interface_initializer.rs | 8 - .../blockchain/blockchain_interface_utils.rs | 7 +- node/src/blockchain/test_utils.rs | 9 +- 12 files changed, 207 insertions(+), 180 deletions(-) delete mode 100644 node/src/blockchain/blockchain_interface/blockchain_interface_web3/batch_payable_tools.rs diff --git a/masq_lib/src/test_utils/mock_blockchain_client_server.rs b/masq_lib/src/test_utils/mock_blockchain_client_server.rs index cb9e55cf1..96caf1d67 100644 --- a/masq_lib/src/test_utils/mock_blockchain_client_server.rs +++ b/masq_lib/src/test_utils/mock_blockchain_client_server.rs @@ -24,7 +24,7 @@ lazy_static! { pub struct MBCSBuilder { port: u16, - run_on_docker: bool, + run_in_docker: bool, response_batch_opt: Option>, responses: Vec, notifier: Sender<()>, @@ -34,15 +34,15 @@ impl MBCSBuilder { pub fn new(port: u16) -> Self { Self { port, - run_on_docker: false, + run_in_docker: false, response_batch_opt: None, responses: vec![], notifier: unbounded().0, } } - pub fn run_on_docker(mut self) -> Self { - self.run_on_docker = true; + pub fn run_in_docker(mut self) -> Self { + self.run_in_docker = true; self } @@ -112,7 +112,7 @@ impl MBCSBuilder { pub fn start(self) -> MockBlockchainClientServer { let requests = Arc::new(Mutex::new(vec![])); let mut server = MockBlockchainClientServer { - port_or_local_addr: if self.run_on_docker { + port_or_local_addr: if self.run_in_docker { Right(SocketAddr::V4(SocketAddrV4::new( Ipv4Addr::new(172, 18, 0, 1), self.port, @@ -413,4 +413,5 @@ struct ConnectionState { request_accumulator: String, } -// Test for this are located: multinode_integration_tests/src/mock_blockchain_client_server.rs +// TODO GH-805 +// Tests for this are located: multinode_integration_tests/src/mock_blockchain_client_server.rs diff --git a/multinode_integration_tests/src/mock_blockchain_client_server.rs b/multinode_integration_tests/src/mock_blockchain_client_server.rs index 6eef0e839..dc211803c 100644 --- a/multinode_integration_tests/src/mock_blockchain_client_server.rs +++ b/multinode_integration_tests/src/mock_blockchain_client_server.rs @@ -1,6 +1,7 @@ // Copyright (c) 2022, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -// Code has been migrated to masq_lib/src/test_utils/mock_blockchain_client_server.rs +// TODO: GH-805 +// The actual mock server has been migrated to masq_lib/src/test_utils/mock_blockchain_client_server.rs #[cfg(test)] mod tests { @@ -29,7 +30,7 @@ mod tests { let port = find_free_port(); let _subject = MockBlockchainClientServer::builder(port) .response("Thank you and good night", 40) - .run_on_docker() + .run_in_docker() .start(); let mut client = connect(port); let chunks = vec![ @@ -61,7 +62,7 @@ mod tests { let _subject = MockBlockchainClientServer::builder(port) .response("Welcome, and thanks for coming!", 39) .response("Thank you and good night", 40) - .run_on_docker() + .run_in_docker() .start(); let mut client = connect(port); client.write (b"POST /biddle HTTP/1.1\r\nContent-Length: 5\r\n\r\nfirstPOST /biddle HTTP/1.1\r\nContent-Length: 6\r\n\r\nsecond").unwrap(); @@ -85,7 +86,7 @@ mod tests { let port = find_free_port(); let _subject = MockBlockchainClientServer::builder(port) .response("irrelevant".to_string(), 42) - .run_on_docker() + .run_in_docker() .start(); let mut client = connect(port); let request = b"POST /biddle HTTP/1.1\r\n\r\nbody"; @@ -102,7 +103,7 @@ mod tests { let port = find_free_port(); let _subject = MockBlockchainClientServer::builder(port) .response("irrelevant".to_string(), 42) - .run_on_docker() + .run_in_docker() .start(); let mut client = connect(port); let request = b"GET /booga\r\nContent-Length: 4\r\n\r\nbody"; @@ -119,7 +120,7 @@ mod tests { let port = find_free_port(); let _subject = MockBlockchainClientServer::builder(port) .response("irrelevant".to_string(), 42) - .run_on_docker() + .run_in_docker() .start(); let mut client = connect(port); let request = b"GET /booga HTTP/2.0\r\nContent-Length: 4\r\n\r\nbody"; @@ -155,7 +156,7 @@ mod tests { age: 37, }), ) - .run_on_docker() + .run_in_docker() .start(); let mut client = connect(port); @@ -217,7 +218,7 @@ mod tests { }, 42, ) - .run_on_docker() + .run_in_docker() .start(); let mut client = connect(port); let request = diff --git a/multinode_integration_tests/tests/blockchain_interaction_test.rs b/multinode_integration_tests/tests/blockchain_interaction_test.rs index 7f86d0e10..42381891c 100644 --- a/multinode_integration_tests/tests/blockchain_interaction_test.rs +++ b/multinode_integration_tests/tests/blockchain_interaction_test.rs @@ -59,7 +59,7 @@ fn debtors_are_credited_once_but_not_twice() { }], 1, ) - .run_on_docker() + .run_in_docker() .start(); // Start a real Node pointing at the mock blockchain client with a start block of 1000 let node_config = NodeStartupConfigBuilder::standard() diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index 4a37d3385..a97b565be 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -654,6 +654,8 @@ impl PendingPayableScanner { msg: ReportTransactionReceipts, logger: &Logger, ) -> PendingPayableScanReport { + // TODO: We want to ensure that failed transactions are not marked still pending, + // and also adjust log levels accordingly. fn handle_none_receipt( mut scan_report: PendingPayableScanReport, payable: PendingPayableFingerprint, @@ -879,6 +881,7 @@ impl Scanner for ReceivableScanner { warning!(logger, "{:?} update max_block_count to {}. Scheduling next scan with that limit.", e, max_block_count); }, |e| { + // TODO: GH-744: This should be changed into a panic warning!(logger, "Writing max_block_count failed: {:?}", e); }, ) @@ -946,7 +949,6 @@ impl ReceivableScanner { new_start_block, e ), } - debug!(logger, "Updated start block to: {}", new_start_block) } else { let mut txn = self .receivable_dao diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/batch_payable_tools.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/batch_payable_tools.rs deleted file mode 100644 index 8b1378917..000000000 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/batch_payable_tools.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index 4f0020389..054ddb48d 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -127,6 +127,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } + // TODO: GH-744: this should be just get_contract_address, we only need the address. fn get_contract(&self) -> Contract { self.contract.clone() } diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 930ed9ba3..4bb6fce5e 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -1,6 +1,5 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -mod batch_payable_tools; pub mod lower_level_interface_web3; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError; @@ -94,6 +93,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { let response_block_number = match response_block_number_result { Ok(block_number) => { debug!(logger, "Latest block number: {}", block_number.as_u64()); + // TODO: GH-744: This could be Eths type U64 instead of u64 block_number.as_u64() } Err(_) => { @@ -123,6 +123,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { .build(); lower_level_interface.get_transaction_logs(filter) .then(move |logs| { + // TODO: GH-744: change the word Transactions for Logs and also to use trace! instead of debug! debug!(logger, "Transaction retrieval completed: {:?}", logs); future::result::( match logs { @@ -463,6 +464,24 @@ mod tests { ] } ) + + // TODO: GH-543: Improve MBCS so we can confirm the calls we make are the correct ones. + // Example of older code + // let requests = test_server.requests_so_far(); + // let bodies: Vec = requests + // .into_iter() + // .map(|request| serde_json::from_slice(&request.body()).unwrap()) + // .map(|b: Value| serde_json::to_string(&b).unwrap()) + // .collect(); + // let expected_body_prefix = r#"[{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber","params":[]},{"id":1,"jsonrpc":"2.0","method":"eth_getLogs","params":[{"address":"0x384dec25e03f94931767ce4c3556168468ba24c3","fromBlock":"0x2a","toBlock":"0x400","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",null,"0x000000000000000000000000"#; + // let expected_body_suffix = r#""]}]}]"#; + // let expected_body = format!( + // "{}{}{}", + // expected_body_prefix, + // &to[2..], + // expected_body_suffix + // ); + // assert_eq!(bodies, vec!(expected_body)); } #[test] @@ -492,27 +511,34 @@ mod tests { transactions: vec![] }) ); + + + // TODO: GH-543: Improve MBCS so we can confirm the calls we make are the correct ones. + // Example of older code + // let requests = test_server.requests_so_far(); + // let bodies: Vec = requests + // .into_iter() + // .map(|request| serde_json::from_slice(&request.body()).unwrap()) + // .map(|b: Value| serde_json::to_string(&b).unwrap()) + // .collect(); + // let expected_body_prefix = r#"[{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber","params":[]},{"id":1,"jsonrpc":"2.0","method":"eth_getLogs","params":[{"address":"0x384dec25e03f94931767ce4c3556168468ba24c3","fromBlock":"0x2a","toBlock":"0x400","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",null,"0x000000000000000000000000"#; + // let expected_body_suffix = r#""]}]}]"#; + // let expected_body = format!( + // "{}{}{}", + // expected_body_prefix, + // &to[2..], + // expected_body_suffix + // ); + // assert_eq!(bodies, vec!(expected_body)); } #[test] #[should_panic(expected = "No address for an uninitialized wallet!")] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_the_to_address_is_invalid( + fn retrieving_address_of_uninitialised_wallet_panics( ) { - let port = find_free_port(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = Wallet::new("0x3f69f9efd4f2592fd70beecd9dce71c472fc"); - let result = subject - .retrieve_transactions( - BlockNumber::Number(42u64.into()), - 555u64, - Wallet::new("0x3f69f9efd4f2592fd70beecd9dce71c472fc").address(), - ) - .wait(); - - assert_eq!( - result.expect_err("Expected an Err, got Ok"), - BlockchainError::InvalidAddress - ); + subject.address(); } #[test] diff --git a/node/src/blockchain/blockchain_interface/lower_level_interface.rs b/node/src/blockchain/blockchain_interface/lower_level_interface.rs index 17cb36551..9109159d3 100644 --- a/node/src/blockchain/blockchain_interface/lower_level_interface.rs +++ b/node/src/blockchain/blockchain_interface/lower_level_interface.rs @@ -19,6 +19,7 @@ pub trait LowBlockchainInt { // TODO: GH-495 The data structures in this trait are not generic, will need associated_type_defaults to implement it. // see issue #29661 for more information + // TODO: Address can be a wrapper type fn get_transaction_fee_balance( &self, address: Address, diff --git a/node/src/blockchain/blockchain_interface/test_utils.rs b/node/src/blockchain/blockchain_interface/test_utils.rs index 9f24b704d..936b29070 100644 --- a/node/src/blockchain/blockchain_interface/test_utils.rs +++ b/node/src/blockchain/blockchain_interface/test_utils.rs @@ -1,133 +1,133 @@ -// Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. - -#![cfg(test)] -use crate::blockchain::blockchain_interface::lower_level_interface::{ - LowBlockchainInt, -}; -use crate::sub_lib::wallet::Wallet; -use std::cell::RefCell; -use std::sync::{Arc, Mutex}; -use actix::Recipient; -use ethereum_types::{H256, U256, U64}; -use futures::Future; -use web3::contract::Contract; -use web3::transports::Http; -use web3::types::{Address, Filter, Log}; -use masq_lib::blockchains::chains::Chain; -use masq_lib::logger::Logger; -use crate::accountant::db_access_objects::payable_dao::PayableAccount; -use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; -use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; -use crate::blockchain::blockchain_interface::data_structures::errors::{BlockchainError, PayableTransactionError}; -use crate::blockchain::blockchain_interface::data_structures::ProcessedPayableFallible; - -#[derive(Default)] -pub struct LowBlockchainIntMock { - get_transaction_fee_balance_params: Arc>>, - get_transaction_fee_balance_results: RefCell>>, - get_masq_balance_params: Arc>>, - get_masq_balance_results: RefCell>>, - get_block_number_results: RefCell>>, - get_transaction_id_params: Arc>>, - get_transaction_id_results: RefCell>>, -} - -impl LowBlockchainInt for LowBlockchainIntMock { - fn get_transaction_fee_balance( - &self, - _address: Address, - ) -> Box> { - unimplemented!("not needed so far") - } - - fn get_service_fee_balance( - &self, - _address: Address, - ) -> Box> { - unimplemented!("not needed so far") - } - - fn get_gas_price(&self) -> Box> { - unimplemented!("not needed so far") - } - - fn get_block_number(&self) -> Box> { - unimplemented!("not needed so far") - } - - fn get_transaction_id( - &self, - _address: Address, - ) -> Box> { - unimplemented!("not needed so far") - } - - fn get_transaction_receipt_in_batch( - &self, - _hash_vec: Vec, - ) -> Box, Error = BlockchainError>> { - unimplemented!("not needed so far") - } - - fn get_contract(&self) -> Contract { - unimplemented!("not needed so far") - } - - fn get_transaction_logs( - &self, - _filter: Filter, - ) -> Box, Error = BlockchainError>> { - unimplemented!("not needed so far") - } - - fn submit_payables_in_batch( - &self, - _logger: Logger, - _chain: Chain, - _consuming_wallet: Wallet, - _fingerprints_recipient: Recipient, - _affordable_accounts: Vec, - ) -> Box, Error = PayableTransactionError>> - { - unimplemented!("not needed so far") - } -} - -impl LowBlockchainIntMock { - pub fn get_transaction_fee_balance_params(mut self, params: &Arc>>) -> Self { - self.get_transaction_fee_balance_params = params.clone(); - self - } - - pub fn get_transaction_fee_balance_result(self, result: Result) -> Self { - self.get_transaction_fee_balance_results - .borrow_mut() - .push(result); - self - } - - pub fn get_masq_balance_params(mut self, params: &Arc>>) -> Self { - self.get_masq_balance_params = params.clone(); - self - } - - pub fn get_masq_balance_result(self, result: Result) -> Self { - self.get_masq_balance_results.borrow_mut().push(result); - self - } - - pub fn get_block_number_result(self, result: Result) -> Self { - self.get_block_number_results.borrow_mut().push(result); - self - } - - pub fn get_transaction_id_params(mut self, params: &Arc>>) -> Self { - self.get_transaction_id_params = params.clone(); - self - } - - pub fn get_transaction_id_result(self, result: Result) -> Self { - self.get_transaction_id_results.borrow_mut().push(result); - self - } -} +// // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. +// +// #![cfg(test)] +// use crate::blockchain::blockchain_interface::lower_level_interface::{ +// LowBlockchainInt, +// }; +// use crate::sub_lib::wallet::Wallet; +// use std::cell::RefCell; +// use std::sync::{Arc, Mutex}; +// use actix::Recipient; +// use ethereum_types::{H256, U256, U64}; +// use futures::Future; +// use web3::contract::Contract; +// use web3::transports::Http; +// use web3::types::{Address, Filter, Log}; +// use masq_lib::blockchains::chains::Chain; +// use masq_lib::logger::Logger; +// use crate::accountant::db_access_objects::payable_dao::PayableAccount; +// use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; +// use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; +// use crate::blockchain::blockchain_interface::data_structures::errors::{BlockchainError, PayableTransactionError}; +// use crate::blockchain::blockchain_interface::data_structures::ProcessedPayableFallible; +// +// #[derive(Default)] +// pub struct LowBlockchainIntMock { +// get_transaction_fee_balance_params: Arc>>, +// get_transaction_fee_balance_results: RefCell>>, +// get_masq_balance_params: Arc>>, +// get_masq_balance_results: RefCell>>, +// get_block_number_results: RefCell>>, +// get_transaction_id_params: Arc>>, +// get_transaction_id_results: RefCell>>, +// } +// +// impl LowBlockchainInt for LowBlockchainIntMock { +// fn get_transaction_fee_balance( +// &self, +// _address: Address, +// ) -> Box> { +// unimplemented!("not needed so far") +// } +// +// fn get_service_fee_balance( +// &self, +// _address: Address, +// ) -> Box> { +// unimplemented!("not needed so far") +// } +// +// fn get_gas_price(&self) -> Box> { +// unimplemented!("not needed so far") +// } +// +// fn get_block_number(&self) -> Box> { +// unimplemented!("not needed so far") +// } +// +// fn get_transaction_id( +// &self, +// _address: Address, +// ) -> Box> { +// unimplemented!("not needed so far") +// } +// +// fn get_transaction_receipt_in_batch( +// &self, +// _hash_vec: Vec, +// ) -> Box, Error = BlockchainError>> { +// unimplemented!("not needed so far") +// } +// +// fn get_contract(&self) -> Contract { +// unimplemented!("not needed so far") +// } +// +// fn get_transaction_logs( +// &self, +// _filter: Filter, +// ) -> Box, Error = BlockchainError>> { +// unimplemented!("not needed so far") +// } +// +// fn submit_payables_in_batch( +// &self, +// _logger: Logger, +// _chain: Chain, +// _consuming_wallet: Wallet, +// _fingerprints_recipient: Recipient, +// _affordable_accounts: Vec, +// ) -> Box, Error = PayableTransactionError>> +// { +// unimplemented!("not needed so far") +// } +// } +// +// impl LowBlockchainIntMock { +// pub fn get_transaction_fee_balance_params(mut self, params: &Arc>>) -> Self { +// self.get_transaction_fee_balance_params = params.clone(); +// self +// } +// +// pub fn get_transaction_fee_balance_result(self, result: Result) -> Self { +// self.get_transaction_fee_balance_results +// .borrow_mut() +// .push(result); +// self +// } +// +// pub fn get_masq_balance_params(mut self, params: &Arc>>) -> Self { +// self.get_masq_balance_params = params.clone(); +// self +// } +// +// pub fn get_masq_balance_result(self, result: Result) -> Self { +// self.get_masq_balance_results.borrow_mut().push(result); +// self +// } +// +// pub fn get_block_number_result(self, result: Result) -> Self { +// self.get_block_number_results.borrow_mut().push(result); +// self +// } +// +// pub fn get_transaction_id_params(mut self, params: &Arc>>) -> Self { +// self.get_transaction_id_params = params.clone(); +// self +// } +// +// pub fn get_transaction_id_result(self, result: Result) -> Self { +// self.get_transaction_id_results.borrow_mut().push(result); +// self +// } +// } diff --git a/node/src/blockchain/blockchain_interface_initializer.rs b/node/src/blockchain/blockchain_interface_initializer.rs index aee2f9c92..f93a5f7f9 100644 --- a/node/src/blockchain/blockchain_interface_initializer.rs +++ b/node/src/blockchain/blockchain_interface_initializer.rs @@ -83,14 +83,6 @@ mod tests { .wait() .unwrap(); - // TODO: GH-543 will improve MBCS to be stronger by validating each response via its request parameters. - let mbcs_requests = blockchain_client_server.requests(); - assert_eq! (mbcs_requests, vec! [ - "POST / HTTP/1.1\r\ncontent-type: application/json\r\nuser-agent: web3.rs\r\ncontent-length: 60\r\nhost: 127.0.0.1:32768\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":0}".to_string(), - "POST / HTTP/1.1\r\ncontent-type: application/json\r\nuser-agent: web3.rs\r\ncontent-length: 115\r\nhost: 127.0.0.1:32768\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBalance\",\"params\":[\"0x0000000000000000000000000000000000313233\",\"latest\"],\"id\":1}".to_string(), - "POST / HTTP/1.1\r\ncontent-type: application/json\r\nuser-agent: web3.rs\r\ncontent-length: 200\r\nhost: 127.0.0.1:32768\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"eth_call\",\"params\":[{\"data\":\"0x70a082310000000000000000000000000000000000000000000000000000000000313233\",\"to\":\"0xee9a352f6aac4af1a5b9f467f6a93e0ffbe9dd35\"},\"latest\"],\"id\":2}".to_string(), - "POST / HTTP/1.1\r\ncontent-type: application/json\r\nuser-agent: web3.rs\r\ncontent-length: 125\r\nhost: 127.0.0.1:32768\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\":[\"0x0000000000000000000000000000000000313233\",\"pending\"],\"id\":3}".to_string() - ]); assert_eq!(blockchain_agent.consuming_wallet(), &wallet); assert_eq!(blockchain_agent.agreed_fee_per_computation_unit(), 2); } diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index 44ab853ff..e1dafa3da 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -1,4 +1,7 @@ -// Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. +// Copyright (c) 2024, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. + +// TODO: GH-744: At the end of the review rename this file to: web3_blockchain_interface_utils.rs +// TODO: GH-744: Or we should move this file into blockchain_interface_web3 use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::accountant::db_access_objects::pending_payable_dao::PendingPayable; @@ -329,6 +332,7 @@ pub fn send_payables_within_batch( ); } +// TODO: GH-744: Migrate this to blockchain/blockchain_bridge.rs and remove pub pub fn calculate_fallback_start_block_number(start_block_number: u64, max_block_count: u64) -> u64 { if max_block_count == u64::MAX { start_block_number + 1u64 @@ -341,6 +345,7 @@ pub fn convert_wei_to_gwei(wei: U256) -> u64 { (wei / U256::from(GWEI_UNIT)).as_u64() + 1 } +// TODO: GH-744: This function could be part of the trait BlockchainAgent (so gas_limit_const_part can go away) pub fn create_blockchain_agent_web3( gas_limit_const_part: u64, blockchain_agent_future_result: BlockchainAgentFutureResult, diff --git a/node/src/blockchain/test_utils.rs b/node/src/blockchain/test_utils.rs index 4a36ca87c..3aed63788 100644 --- a/node/src/blockchain/test_utils.rs +++ b/node/src/blockchain/test_utils.rs @@ -15,8 +15,6 @@ use crate::blockchain::blockchain_interface::data_structures::{ ProcessedPayableFallible, RetrievedBlockchainTransactions, }; use crate::blockchain::blockchain_interface::lower_level_interface::LowBlockchainInt; -// use crate::blockchain::blockchain_interface::test_utils::LowBlockchainIntMock; -use crate::blockchain::blockchain_interface::test_utils::LowBlockchainIntMock; use crate::blockchain::blockchain_interface::BlockchainInterface; use crate::set_arbitrary_id_stamp_in_mock_impl; use crate::sub_lib::wallet::Wallet; @@ -63,6 +61,7 @@ pub fn make_meaningless_seed() -> Seed { Seed::new(&mnemonic, "passphrase") } +// TODO: GH-744: Look into removing options form port. and in places were are have defined port as None, just define a port anyway. pub fn make_blockchain_interface_web3(port_opt: Option) -> BlockchainInterfaceWeb3 { let port = port_opt.unwrap_or_else(|| find_free_port()); let chain = Chain::PolyMainnet; @@ -186,7 +185,7 @@ impl ReceiptResponseBuilder { let rpc_response = RpcResponse { json_rpc: "2.0".to_string(), - id: 0, + id: 1, result: transaction_receipt, }; serde_json::to_string(&rpc_response).unwrap() @@ -215,7 +214,7 @@ pub struct BlockchainInterfaceMock { get_transaction_receipt_params: Arc>>, get_transaction_receipt_results: RefCell, BlockchainError>>>, - lower_interface_result: Option>, + lower_interface_result: Option>, arbitrary_id_stamp_opt: Option, get_chain_results: RefCell>, get_batch_web3_results: RefCell>>>, @@ -346,7 +345,7 @@ impl BlockchainInterfaceMock { pub fn lower_interface_results( mut self, - aggregated_results: Box, + aggregated_results: Box, ) -> Self { self.lower_interface_result = Some(aggregated_results); self From 43456e7d65c308e2b2889d1c51332bf63c43874d Mon Sep 17 00:00:00 2001 From: Syther007 Date: Fri, 1 Nov 2024 23:31:34 +1300 Subject: [PATCH 12/56] GH-744: resolved more review comments --- node/src/accountant/scanners/mod.rs | 124 +++++-- node/src/blockchain/blockchain_bridge.rs | 4 +- .../blockchain_interface_web3/mod.rs | 24 +- .../blockchain/blockchain_interface/mod.rs | 3 + .../blockchain/blockchain_interface_utils.rs | 337 ++++++++---------- node/src/blockchain/test_utils.rs | 66 +--- 6 files changed, 262 insertions(+), 296 deletions(-) diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index a97b565be..34ba82720 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -872,28 +872,9 @@ impl Scanner for ReceivableScanner { Ok(payments_and_start_block) => { self.handle_new_received_payments(&payments_and_start_block, msg.timestamp, logger); } - Err(e) => match e { - ReceivedPaymentsError::ExceededBlockScanLimit(max_block_count) => { - debug!(logger, "Writing max_block_count({})", max_block_count); - self.persistent_configuration - .set_max_block_count(Some(max_block_count)) - .map_or_else(|_| { - warning!(logger, "{:?} update max_block_count to {}. Scheduling next scan with that limit.", e, max_block_count); - }, - |e| { - // TODO: GH-744: This should be changed into a panic - warning!(logger, "Writing max_block_count failed: {:?}", e); - }, - ) - } - ReceivedPaymentsError::OtherRPCError(rpc_error) => { - warning!( - logger, - "Attempted to retrieve received payments but failed: {:?}", - rpc_error - ); - } - }, + Err(e) => { + self.handle_new_received_payments_scan_error(e, logger); + } } self.mark_as_ended(logger); @@ -984,6 +965,34 @@ impl ReceivableScanner { } } + fn handle_new_received_payments_scan_error(&mut self, error: ReceivedPaymentsError, logger: &Logger) { + match error { + ReceivedPaymentsError::ExceededBlockScanLimit(max_block_count) => { + match self + .persistent_configuration + .set_max_block_count(Some(max_block_count)) + { + Ok(()) => { + debug!(logger, "Updated max_block_count to {} in database.", max_block_count); + }, + Err(e) => { + panic!( + "Attempt to set new max block to {} failed due to: {:?}", + max_block_count, e + ) + }, + } + } + ReceivedPaymentsError::OtherRPCError(rpc_error) => { + warning!( + logger, + "Attempted to retrieve received payments but failed: {:?}", + rpc_error + ); + } + } + } + pub fn scan_for_delinquencies(&self, timestamp: SystemTime, logger: &Logger) { info!(logger, "Scanning for delinquencies"); self.find_and_ban_delinquents(timestamp, logger); @@ -1176,7 +1185,7 @@ mod tests { use crate::database::rusqlite_wrappers::TransactionSafeWrapper; use crate::database::test_utils::transaction_wrapper_mock::TransactionInnerWrapperMockBuilder; use crate::db_config::mocks::ConfigDaoMock; - use crate::db_config::persistent_configuration::PersistentConfigError; + use crate::db_config::persistent_configuration::{PersistentConfigError, PersistentConfiguration}; use crate::sub_lib::accountant::{ DaoFactories, FinancialStatistics, PaymentThresholds, ScanIntervals, DEFAULT_PAYMENT_THRESHOLDS, @@ -1200,6 +1209,7 @@ mod tests { use std::time::{Duration, SystemTime}; use web3::types::{TransactionReceipt, H256}; use web3::Error; + use crate::accountant::ReceivedPaymentsError::{ExceededBlockScanLimit, OtherRPCError}; use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; #[test] @@ -3127,7 +3137,7 @@ mod tests { #[test] fn receivable_scanner_handles_no_new_payments_found() { init_test_logging(); - let test_name = "receivable_scanner_aborts_scan_if_no_payments_were_supplied"; + let test_name = "receivable_scanner_handles_no_new_payments_found"; let set_start_block_params_arc = Arc::new(Mutex::new(vec![])); let new_start_block = 4321; let persistent_config = PersistentConfigurationMock::new() @@ -3333,6 +3343,72 @@ mod tests { subject.finish_scan(msg, &Logger::new(test_name)); } + #[test] + fn receivable_scanner_receives_exceeded_block_scan_limit_error() { + init_test_logging(); + let test_name = "receivable_scanner_receives_exceeded_block_scan_limit_error"; + let set_max_block_params_arc = Arc::new(Mutex::new(vec![])); + let new_max_block = 100_000u64; + let persistent_config = PersistentConfigurationMock::new() + .set_max_block_count_params(&set_max_block_params_arc) + .set_max_block_count_result(Ok(())); + let mut subject = ReceivableScannerBuilder::new() + .persistent_configuration(persistent_config) + .build(); + let msg = ReceivedPayments { + timestamp: SystemTime::now(), + scan_result: Err(ExceededBlockScanLimit(new_max_block)), + response_skeleton_opt: None, + }; + + let message_opt = subject.finish_scan(msg, &Logger::new(test_name)); + + assert_eq!(message_opt, None); + let set_max_block_params = set_max_block_params_arc.lock().unwrap(); + assert_eq!(*set_max_block_params, vec![Some(new_max_block)]); + TestLogHandler::new().exists_log_containing(&format!( + "DEBUG: {test_name}: Updated max_block_count to 100000 in database." + )); + } + + #[test] + #[should_panic(expected = "Attempt to set new max block to 100000 failed due to: DatabaseError(\"Some bad stuff happened\")")] + fn receivable_scanner_receives_exceeded_block_scan_limit_error_and_database_wright_fails() { + let new_max_block = 100_000u64; + let persistent_config = PersistentConfigurationMock::new() + .set_max_block_count_result(Err(PersistentConfigError::DatabaseError("Some bad stuff happened".to_string()))); + let mut subject = ReceivableScannerBuilder::new() + .persistent_configuration(persistent_config) + .build(); + let msg = ReceivedPayments { + timestamp: SystemTime::now(), + scan_result: Err(ExceededBlockScanLimit(new_max_block)), + response_skeleton_opt: None, + }; + + let _ = subject.finish_scan(msg, &Logger::new("test")); + } + + #[test] + fn receivable_scanner_receives_other_rpc_error() { + init_test_logging(); + let test_name = "receivable_scanner_receives_other_rpc_error"; + let mut subject = ReceivableScannerBuilder::new() + .build(); + let msg = ReceivedPayments { + timestamp: SystemTime::now(), + scan_result: Err(OtherRPCError("Dead RPC".to_string())), + response_skeleton_opt: None, + }; + + let message_opt = subject.finish_scan(msg, &Logger::new(test_name)); + + assert_eq!(message_opt, None); + TestLogHandler::new().exists_log_containing(&format!( + "WARN: {test_name}: Attempted to retrieve received payments but failed: \"Dead RPC\"" + )); + } + #[test] fn signal_scanner_completion_and_log_if_timestamp_is_correct() { init_test_logging(); diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 26d0edf54..fe746ae43 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -316,7 +316,7 @@ impl BlockchainBridge { _ => u64::MAX, }; - let fallback_start_block_number = + let fallback_next_start_block_number = calculate_fallback_start_block_number(start_block_nbr, max_block_count); let start_block = BlockNumber::Number(start_block_nbr.into()); let received_payments_subs_ok_case = self @@ -330,7 +330,7 @@ impl BlockchainBridge { self.blockchain_interface .retrieve_transactions( start_block, - fallback_start_block_number, + fallback_next_start_block_number, msg.recipient.address(), ) .map_err(move |e| { diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 4bb6fce5e..2e57dd27a 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -146,6 +146,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { ) -> Box, Error = BlockchainAgentBuildError>> { let wallet_address = consuming_wallet.address(); let gas_limit_const_part = self.gas_limit_const_part; + // TODO: Would it be better to wrap these 4 calls into a single batch call? let get_gas_price = self.lower_interface().get_gas_price(); let get_transaction_fee_balance = self .lower_interface() @@ -595,7 +596,7 @@ mod tests { ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x178def", 1) + .response("0x400", 1) .raw_response(r#"{"jsonrpc":"2.0","id":2,"result":[{"address":"0xcd6c588e005032dd882cd43bf53a32129be81302","blockHash":"0x1a24b9169cbaec3f6effa1f600b70c7ab9e8e86db44062b49132a4415d26732a","data":"0x0000000000000000000000000000000000000000000000000010000000000000","logIndex":"0x0","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000003f69f9efd4f2592fd70be8c32ecd9dce71c472fc","0x000000000000000000000000adc1853c7859369639eb414b6342b36288fe6092"],"transactionHash":"0x955cec6ac4f832911ab894ce16aa22c3003f46deff3f7165b32700d2f5ff0681","transactionIndex":"0x0"}]}"#.to_string()) .start(); init_test_logging(); @@ -622,7 +623,7 @@ mod tests { assert_eq!( result, Ok(RetrievedBlockchainTransactions { - new_start_block: 1543664, + new_start_block: 1 + end_block_nbr, transactions: vec![] }) ); @@ -632,6 +633,8 @@ mod tests { ); } + // TODO: GH-744: HIGH - We are adding 1 to the fallback start block number twice. why? + // https://github.com/MASQ-Project/Node/pull/456#discussion_r1803865133 #[test] fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one( ) { @@ -656,7 +659,6 @@ mod tests { .wait(); let expected_fallback_start_block = start_block_nbr + 1u64; - assert_eq!( result, Ok(RetrievedBlockchainTransactions { @@ -685,23 +687,23 @@ mod tests { let chain = Chain::PolyMainnet; let wallet = make_wallet("abc"); let subject = make_blockchain_interface_web3(Some(port)); - let transaction_fee_balance = U256::from(65_520); - let masq_balance = U256::from(65_535); - let transaction_id = U256::from(35); let result = subject .build_blockchain_agent(wallet.clone()) .wait() .unwrap(); + let expected_transaction_fee_balance = U256::from(65_520); + let expected_masq_balance = U256::from(65_535); + let expected_transaction_id = U256::from(35); let expected_gas_price_gwei = 2; assert_eq!(result.consuming_wallet(), &wallet); - assert_eq!(result.pending_transaction_id(), transaction_id); + assert_eq!(result.pending_transaction_id(), expected_transaction_id); assert_eq!( result.consuming_wallet_balances(), ConsumingWalletBalances { - transaction_fee_balance_in_minor_units: transaction_fee_balance, - masq_token_balance_in_minor_units: masq_balance + transaction_fee_balance_in_minor_units: expected_transaction_fee_balance, + masq_token_balance_in_minor_units: expected_masq_balance } ); assert_eq!( @@ -718,6 +720,10 @@ mod tests { ) } + + // TODO: GH-744: Migrate test to the place after the helper function below this test. + // You'll find three more tests with a simplified api and I believe that the way it is done will suite also this test. + // Please could do this for better hygiene so that our workspace is cleaner looking forward? #[test] fn build_of_the_blockchain_agent_fails_on_fetching_gas_price() { let port = find_free_port(); diff --git a/node/src/blockchain/blockchain_interface/mod.rs b/node/src/blockchain/blockchain_interface/mod.rs index fe6490c22..2c47a450f 100644 --- a/node/src/blockchain/blockchain_interface/mod.rs +++ b/node/src/blockchain/blockchain_interface/mod.rs @@ -21,6 +21,9 @@ pub trait BlockchainInterface { fn get_chain(&self) -> Chain; + // Initially this lower_interface wasn't wrapped with a box, but under the card GH-744 this design was used to solve lifetime issues + // with the futures. + // The downside to this method is we cant store persistent values, instead its being initialised where ever it being used. fn lower_interface(&self) -> Box; fn retrieve_transactions( diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index e1dafa3da..f0e7d1b00 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -73,7 +73,7 @@ pub fn merged_output_data( .map( |((rpc_result, hash_and_amount), account)| match rpc_result { Ok(_rpc_result) => { - // TODO: This rpc_result should be validated + // TODO: GH-547: This rpc_result should be validated ProcessedPayableFallible::Correct(PendingPayable { recipient_wallet: account.wallet.clone(), hash: hash_and_amount.hash, @@ -128,11 +128,10 @@ pub fn sign_transaction_data(amount: u128, recipient_wallet: Wallet) -> [u8; 68] pub fn gas_limit(data: [u8; 68], chain: Chain) -> U256 { let base_gas_limit = BlockchainInterfaceWeb3::web3_gas_limit_const_part(chain); - let gas_limit = ethereum_types::U256::try_from(data.iter().fold(base_gas_limit, |acc, v| { + ethereum_types::U256::try_from(data.iter().fold(base_gas_limit, |acc, v| { acc + if v == &0u8 { 4 } else { 68 } })) - .expect("Internal error"); - gas_limit + .expect("Internal error") } pub fn sign_transaction( @@ -147,7 +146,7 @@ pub fn sign_transaction( let data = sign_transaction_data(amount, recipient_wallet); let gas_limit = gas_limit(data, chain); let gas_price_in_wei = to_wei(gas_price_in_gwei); - // If you flip gas_price or nonce to None this function will start making RPC calls (Do it at your own risk). + // Warning: If you set gas_price or nonce to None in transaction_parameters, sign_transaction will start making RPC calls which we don't want (Do it at your own risk). let transaction_parameters = TransactionParameters { nonce: Some(nonce), to: Some(chain.rec().contract), @@ -159,7 +158,7 @@ pub fn sign_transaction( }; let key = consuming_wallet .prepare_secp256k1_secret() - .expect("Consuming wallet doesnt contain a secret key"); + .expect("Consuming wallet doesn't contain a secret key"); sign_transaction_locally(web3_batch, transaction_parameters, &key) } @@ -173,10 +172,10 @@ pub fn sign_transaction_locally( || transaction_parameters.chain_id.is_none() || transaction_parameters.gas_price.is_none() { - panic!("Signing should be done locally"); + panic!("We don't want to fetch any values while signing"); } - // This wait call doesn't actually make any RPC call and signing is done locally. + // This wait call doesn't actually make any RPC call as long as nonce, chain_id & gas_price are set. web3_batch .accounts() .sign_transaction(transaction_parameters, key) @@ -184,7 +183,7 @@ pub fn sign_transaction_locally( .expect("Web call wasn't allowed") } -pub fn handle_new_transaction( +pub fn sign_and_append_payment( chain: Chain, web3_batch: Web3>, recipient_wallet: Wallet, @@ -211,7 +210,7 @@ pub fn append_signed_transaction_to_batch(web3_batch: Web3>, raw_tra web3_batch.eth().send_raw_transaction(raw_transaction); } -pub fn sign_and_append_payment( +pub fn handle_new_transaction( chain: Chain, web3_batch: Web3>, consuming_wallet: Wallet, @@ -219,7 +218,7 @@ pub fn sign_and_append_payment( gas_price: u64, account: PayableAccount, ) -> HashAndAmount { - let hash = handle_new_transaction( + let hash = sign_and_append_payment( chain, web3_batch, account.wallet.clone(), @@ -253,7 +252,7 @@ pub fn sign_and_append_multiple_payments( pending_nonce ); - let hash_and_amount = sign_and_append_payment( + let hash_and_amount = handle_new_transaction( chain, web3_batch.clone(), consuming_wallet.clone(), @@ -268,6 +267,9 @@ pub fn sign_and_append_multiple_payments( hash_and_amount_list } +// TODO: GH-744: Use reference to logger, and check other functions are also using a reference to logger. +// TODO: GH-744: check if we can use a reference to web3_batch also. +// TODO: GH-744: same for accounts, can we also use a reference? #[allow(clippy::too_many_arguments)] pub fn send_payables_within_batch( logger: Logger, @@ -461,8 +463,9 @@ mod tests { ); } + // TODO: GH-744: Review this test. with the test above, do we really need both? #[test] - fn handle_new_transaction_works() { + fn sign_and_append_payment_works() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() @@ -483,7 +486,8 @@ mod tests { let consuming_wallet = make_paying_wallet(b"paying_wallet"); let account = make_payable_account(1); let web3_batch = Web3::new(Batch::new(transport)); - let result = handle_new_transaction( + + let result = sign_and_append_payment( chain, web3_batch.clone(), account.wallet, @@ -494,7 +498,6 @@ mod tests { ); let mut batch_result = web3_batch.eth().transport().submit_batch().wait().unwrap(); - assert_eq!( result, H256::from_str("94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2") @@ -508,8 +511,10 @@ mod tests { ); } + + // TODO: GH-744: Review this test and the test below it, do we really need both? #[test] - fn sign_and_append_payment_works() { + fn handle_new_transaction_works() { let port = find_free_port(); let (_event_loop_handle, transport) = Http::with_max_parallel( &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), @@ -524,7 +529,7 @@ mod tests { let account = make_payable_account(1); let amount = account.balance_wei; - let result = sign_and_append_payment( + let result = handle_new_transaction( chain, web3_batch, consuming_wallet, @@ -696,87 +701,7 @@ mod tests { ) } - #[test] - fn send_payables_within_batch_fails_on_submit_batch_call() { - let port = find_free_port(); - let (_event_loop_handle, transport) = Http::with_max_parallel( - &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), - REQUESTS_IN_PARALLEL, - ) - .unwrap(); - let consuming_wallet_secret_raw_bytes = b"okay-wallet"; - let recipient_wallet = make_wallet("blah123"); - let unimportant_recipient = Recorder::new().start().recipient(); - let account = make_payable_account_with_wallet_and_balance_and_timestamp_opt( - recipient_wallet.clone(), - 5000, - None, - ); - let consuming_wallet = make_paying_wallet(consuming_wallet_secret_raw_bytes); - let gas_price = 123; - let nonce = U256::from(1); - let os_code = transport_error_code(); - let os_msg = transport_error_message(); - - let result = send_payables_within_batch( - Logger::new("test"), - TEST_DEFAULT_CHAIN, - Web3::new(Batch::new(transport)), - consuming_wallet, - gas_price, - nonce, - unimportant_recipient, - vec![account], - ) - .wait(); - - assert_eq!( - result, - Err( - Sending { - msg: format!("Transport error: Error(Connect, Os {{ code: {}, kind: ConnectionRefused, message: {:?} }})", os_code, os_msg).to_string(), - hashes: vec![H256::from_str("424c0231591a9879d82f25e0d81e09f39499b2bfd56b3aba708491995e35b4ac").unwrap()] - } - ) - ); - } - - #[test] - fn advance_used_nonce_works() { - let initial_nonce = U256::from(55); - - let result = advance_used_nonce(initial_nonce); - - assert_eq!(result, U256::from(56)) - } - - #[test] - #[should_panic( - expected = "Consuming wallet doesnt contain a secret key: Signature(\"Cannot sign with non-keypair wallet: Address(0x000000000000000000006261645f77616c6c6574).\")" - )] - fn sign_transaction_panics_on_signing_itself() { - let port = find_free_port(); - let (_event_loop_handle, transport) = Http::with_max_parallel( - &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), - REQUESTS_IN_PARALLEL, - ) - .unwrap(); - let recipient_wallet = make_wallet("unlucky man"); - let consuming_wallet = make_wallet("bad_wallet"); - let gas_price = 123; - let nonce = U256::from(1); - - sign_transaction( - Chain::PolyAmoy, - Web3::new(Batch::new(transport)), - recipient_wallet, - consuming_wallet, - 444444, - nonce, - gas_price, - ); - } - + // TODO: GH-744 Change gas_price & nonce from 1 to something else #[test] fn send_payables_within_batch_works() { init_test_logging(); @@ -786,11 +711,11 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .response("rpc_result".to_string(), 7) - .response("rpc_result_2".to_string(), 7) + .response("rpc_result_2".to_string(), 8) .end_batch() .start(); let web3_batch = Web3::new(Batch::new(transport)); @@ -817,37 +742,36 @@ mod tests { new_fingerprints_recipient, accounts.clone(), ) - .wait(); + .wait(); System::current().stop(); system.run(); - let tlh = TestLogHandler::new(); let timestamp_after = SystemTime::now(); - let recording_result = accountant_recording.lock().unwrap(); - let processed_payments = result.unwrap(); - let message = recording_result.get_record::(0); - assert_eq!(recording_result.len(), 1); - assert!(timestamp_before <= message.batch_wide_timestamp); - assert!(timestamp_after >= message.batch_wide_timestamp); + let accountant_recording_result = accountant_recording.lock().unwrap(); + let ppfs_message = accountant_recording_result.get_record::(0); + assert_eq!(accountant_recording_result.len(), 1); + assert!(timestamp_before <= ppfs_message.batch_wide_timestamp); + assert!(timestamp_after >= ppfs_message.batch_wide_timestamp); assert_eq!( - message.hashes_and_balances, + ppfs_message.hashes_and_balances, vec![ HashAndAmount { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap(), + .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap(), + .unwrap(), amount: accounts_2.balance_wei }, ] ); + let processed_payments = result.unwrap(); assert_eq!( processed_payments[0], ProcessedPayableFallible::Correct(PendingPayable { @@ -855,7 +779,7 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap() + .unwrap() }) ); assert_eq!( @@ -865,9 +789,10 @@ mod tests { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap() + .unwrap() }) ); + let tlh = TestLogHandler::new(); tlh.exists_log_containing( &format!("DEBUG: {test_name}: Common attributes of payables to be transacted: sender wallet: {}, contract: {:?}, chain_id: {}, gas_price: {}", consuming_wallet, @@ -882,6 +807,88 @@ mod tests { )); } + #[test] + fn send_payables_within_batch_fails_on_submit_batch_call() { + let port = find_free_port(); + let (_event_loop_handle, transport) = Http::with_max_parallel( + &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), + REQUESTS_IN_PARALLEL, + ) + .unwrap(); + let consuming_wallet_secret_raw_bytes = b"okay-wallet"; + let recipient_wallet = make_wallet("blah123"); + let unimportant_recipient = Recorder::new().start().recipient(); + let account = make_payable_account_with_wallet_and_balance_and_timestamp_opt( + recipient_wallet.clone(), + 5000, + None, + ); + let consuming_wallet = make_paying_wallet(consuming_wallet_secret_raw_bytes); + let gas_price = 123; + let nonce = U256::from(1); + let os_code = transport_error_code(); + let os_msg = transport_error_message(); + + let result = send_payables_within_batch( + Logger::new("test"), + TEST_DEFAULT_CHAIN, + Web3::new(Batch::new(transport)), + consuming_wallet, + gas_price, + nonce, + unimportant_recipient, + vec![account], + ) + .wait(); + + assert_eq!( + result, + Err( + Sending { + msg: format!("Transport error: Error(Connect, Os {{ code: {}, kind: ConnectionRefused, message: {:?} }})", os_code, os_msg).to_string(), + hashes: vec![H256::from_str("424c0231591a9879d82f25e0d81e09f39499b2bfd56b3aba708491995e35b4ac").unwrap()] + } + ) + ); + } + + #[test] + fn advance_used_nonce_works() { + let initial_nonce = U256::from(55); + + let result = advance_used_nonce(initial_nonce); + + assert_eq!(result, U256::from(56)) + } + + #[test] + #[should_panic( + expected = "Consuming wallet doesn't contain a secret key: Signature(\"Cannot sign with non-keypair wallet: Address(0x000000000000000000006261645f77616c6c6574).\")" + )] + fn sign_transaction_panics_due_to_lack_of_secret_key() { + let port = find_free_port(); + let (_event_loop_handle, transport) = Http::with_max_parallel( + &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), + REQUESTS_IN_PARALLEL, + ) + .unwrap(); + let recipient_wallet = make_wallet("unlucky man"); + let consuming_wallet = make_wallet("bad_wallet"); + let gas_price = 123; + let nonce = U256::from(1); + + sign_transaction( + Chain::PolyAmoy, + Web3::new(Batch::new(transport)), + recipient_wallet, + consuming_wallet, + 444444, + nonce, + gas_price, + ); + } + + // TODO: GH-744: Find the tests similar to this one and refactor them to remove duplicated code. #[test] fn send_payables_within_batch_all_payments_fail() { init_test_logging(); @@ -904,7 +911,7 @@ mod tests { 429, "The requests per second (RPS) of your requests are higher than your plan allows." .to_string(), - 7, + 8, ) .end_batch() .start(); @@ -936,16 +943,14 @@ mod tests { System::current().stop(); system.run(); - let tlh = TestLogHandler::new(); let timestamp_after = SystemTime::now(); - let recording_result = accountant_recording.lock().unwrap(); - let processed_payments = result.unwrap(); - let message = recording_result.get_record::(0); - assert_eq!(recording_result.len(), 1); - assert!(timestamp_before <= message.batch_wide_timestamp); - assert!(timestamp_after >= message.batch_wide_timestamp); + let accountant_recording_result = accountant_recording.lock().unwrap(); + let ppfs_message = accountant_recording_result.get_record::(0); + assert_eq!(accountant_recording_result.len(), 1); + assert!(timestamp_before <= ppfs_message.batch_wide_timestamp); + assert!(timestamp_after >= ppfs_message.batch_wide_timestamp); assert_eq!( - message.hashes_and_balances, + ppfs_message.hashes_and_balances, vec![ HashAndAmount { hash: H256::from_str( @@ -963,6 +968,7 @@ mod tests { }, ] ); + let processed_payments = result.unwrap(); assert_eq!(processed_payments[0], Failed(RpcPayableFailure{ rpc_error: Rpc(Error { code: ServerError(429), @@ -981,6 +987,7 @@ mod tests { recipient_wallet: accounts_2.wallet, hash: H256::from_str("7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3").unwrap(), })); + let tlh = TestLogHandler::new(); tlh.exists_log_containing( &format!("DEBUG: {test_name}: Common attributes of payables to be transacted: sender wallet: {}, contract: {:?}, chain_id: {}, gas_price: {}", consuming_wallet, @@ -1017,7 +1024,6 @@ mod tests { .end_batch() .start(); let web3_batch = Web3::new(Batch::new(transport.clone())); - let (accountant, _, accountant_recording) = make_recorder(); let logger = Logger::new(test_name); let chain = DEFAULT_CHAIN; @@ -1045,16 +1051,14 @@ mod tests { System::current().stop(); system.run(); - let tlh = TestLogHandler::new(); let timestamp_after = SystemTime::now(); - let recording_result = accountant_recording.lock().unwrap(); - let processed_payments = result.unwrap(); - let message = recording_result.get_record::(0); - assert_eq!(recording_result.len(), 1); - assert!(timestamp_before <= message.batch_wide_timestamp); - assert!(timestamp_after >= message.batch_wide_timestamp); + let accountant_recording_result = accountant_recording.lock().unwrap(); + let ppfs_message = accountant_recording_result.get_record::(0); + assert_eq!(accountant_recording_result.len(), 1); + assert!(timestamp_before <= ppfs_message.batch_wide_timestamp); + assert!(timestamp_after >= ppfs_message.batch_wide_timestamp); assert_eq!( - message.hashes_and_balances, + ppfs_message.hashes_and_balances, vec![ HashAndAmount { hash: H256::from_str( @@ -1072,6 +1076,7 @@ mod tests { }, ] ); + let processed_payments = result.unwrap(); assert_eq!( processed_payments[0], ProcessedPayableFallible::Correct(PendingPayable { @@ -1091,6 +1096,7 @@ mod tests { recipient_wallet: accounts_2.wallet, hash: H256::from_str("7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3").unwrap(), })); + let tlh = TestLogHandler::new(); tlh.exists_log_containing( &format!("DEBUG: {test_name}: Common attributes of payables to be transacted: sender wallet: {}, contract: {:?}, chain_id: {}, gas_price: {}", consuming_wallet, @@ -1151,36 +1157,7 @@ mod tests { } #[test] - #[should_panic( - expected = "Consuming wallet doesnt contain a secret key: Signature(\"Cannot sign with non-keypair wallet: Address(0x00000000636f6e73756d696e675f77616c6c6574).\")" - )] - fn sign_transaction_panics_on_bad_consuming_wallet() { - let port = find_free_port(); - let (_event_loop_handle, transport) = Http::with_max_parallel( - &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), - REQUESTS_IN_PARALLEL, - ) - .unwrap(); - let chain = DEFAULT_CHAIN; - let amount = 11_222_333_444; - let gas_price_in_gwei = 123000000000_u64; - let nonce = U256::from(5); - let recipient_wallet = make_wallet("recipient_wallet"); - let consuming_wallet = make_wallet("consuming_wallet"); - - let _result = sign_transaction( - chain, - Web3::new(Batch::new(transport)), - recipient_wallet, - consuming_wallet, - amount, - nonce, - gas_price_in_gwei, - ); - } - - #[test] - #[should_panic(expected = "Signing should be done locally")] + #[should_panic(expected = "We don't want to fetch any values while signing")] fn sign_transaction_locally_panics_on_signed_transaction() { let port = find_free_port(); let (_event_loop_handle, transport) = Http::with_max_parallel( @@ -1207,7 +1184,7 @@ mod tests { }; let key = consuming_wallet .prepare_secp256k1_secret() - .expect("Consuming wallet doesnt contain a secret key"); + .expect("Consuming wallet doesn't contain a secret key"); let _result = sign_transaction_locally( Web3::new(Batch::new(transport)), @@ -1216,42 +1193,6 @@ mod tests { ); } - #[test] - fn sign_and_append_payment_just_works() { - let port = find_free_port(); - let (_event_loop_handle, transport) = Http::with_max_parallel( - &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), - REQUESTS_IN_PARALLEL, - ) - .unwrap(); - let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let system = System::new("test"); - let account = make_payable_account_with_wallet_and_balance_and_timestamp_opt( - make_wallet("blah123"), - 9000, - None, - ); - let gas_price = 123; - let nonce = U256::from(1); - - let result = sign_and_append_payment( - TEST_DEFAULT_CHAIN, - Web3::new(Batch::new(transport)), - consuming_wallet, - nonce, - gas_price, - account, - ); - - System::current().stop(); - system.run(); - let expected_hash = - H256::from_str("8d278f82f42ee4f3b9eef2e099cccc91ff117e80c28d6369fec38ec50f5bd2c2") - .unwrap(); - assert_eq!(result.hash, expected_hash); - assert_eq!(result.amount, 9000); - } - //with a real confirmation through a transaction sent with this data to the network #[test] fn web3_interface_signing_a_transaction_works_for_polygon_amoy() { diff --git a/node/src/blockchain/test_utils.rs b/node/src/blockchain/test_utils.rs index 3aed63788..d5838a186 100644 --- a/node/src/blockchain/test_utils.rs +++ b/node/src/blockchain/test_utils.rs @@ -194,32 +194,18 @@ impl ReceiptResponseBuilder { #[derive(Default)] pub struct BlockchainInterfaceMock { + get_chain_results: RefCell>, + lower_interface_result: Option>, retrieve_transactions_parameters: Arc>>, retrieve_transactions_results: RefCell>>, build_blockchain_agent_params: Arc>>, build_blockchain_agent_results: RefCell, BlockchainAgentBuildError>>>, - send_batch_of_payables_params: Arc< - Mutex< - Vec<( - ArbitraryIdStamp, - Recipient, - Vec, - )>, - >, - >, - send_batch_of_payables_results: - RefCell, PayableTransactionError>>>, - get_transaction_receipt_params: Arc>>, - get_transaction_receipt_results: - RefCell, BlockchainError>>>, - lower_interface_result: Option>, arbitrary_id_stamp_opt: Option, - get_chain_results: RefCell>, - get_batch_web3_results: RefCell>>>, } +// TODO: GH-744: There are a few tests using BlockchainInterfaceMock, if we convert them to use MBCS then we can delete BlockchainInterfaceMock impl BlockchainInterface for BlockchainInterfaceMock { fn contract_address(&self) -> Address { unimplemented!("not needed so far") @@ -292,57 +278,11 @@ impl BlockchainInterfaceMock { self } - pub fn send_batch_of_payables_params( - mut self, - params: &Arc< - Mutex< - Vec<( - ArbitraryIdStamp, - Recipient, - Vec, - )>, - >, - >, - ) -> Self { - self.send_batch_of_payables_params = params.clone(); - self - } - - pub fn send_batch_of_payables_result( - self, - result: Result, PayableTransactionError>, - ) -> Self { - self.send_batch_of_payables_results - .borrow_mut() - .push(result); - self - } - pub fn get_chain_result(self, result: Chain) -> Self { self.get_chain_results.borrow_mut().push(result); self } - pub fn get_batch_web3_result(self, result: Web3>) -> Self { - self.get_batch_web3_results.borrow_mut().push(result); - self - } - - pub fn get_transaction_receipt_params(mut self, params: &Arc>>) -> Self { - self.get_transaction_receipt_params = params.clone(); - self - } - - pub fn get_transaction_receipt_result( - self, - result: Result, BlockchainError>, - ) -> Self { - self.get_transaction_receipt_results - .borrow_mut() - .push(result); - self - } - pub fn lower_interface_results( mut self, aggregated_results: Box, From 4d7fa8a4271504d099ddc5c9604aa653fee5b13f Mon Sep 17 00:00:00 2001 From: Syther007 Date: Sat, 2 Nov 2024 00:48:53 +1300 Subject: [PATCH 13/56] GH-744: started converting gas_price units from gwei to wei --- .../payable_scanner/agent_null.rs | 2 +- .../payable_scanner/agent_web3.rs | 26 +++---- .../payable_scanner/blockchain_agent.rs | 2 +- .../payable_scanner/test_utils.rs | 6 +- node/src/blockchain/blockchain_bridge.rs | 4 +- .../lower_level_interface_web3.rs | 3 +- .../blockchain_interface_web3/mod.rs | 10 +-- .../blockchain_interface_initializer.rs | 2 +- .../blockchain/blockchain_interface_utils.rs | 67 +++++++++---------- 9 files changed, 60 insertions(+), 62 deletions(-) diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs index faf7d45cc..5510ec2af 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs @@ -27,7 +27,7 @@ impl BlockchainAgent for BlockchainAgentNull { } } - fn agreed_fee_per_computation_unit(&self) -> u64 { + fn agreed_fee_per_computation_unit(&self) -> u128 { self.log_function_call("agreed_fee_per_computation_unit()"); 0 } diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs index 5f6afa4ad..db5cbf90f 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs @@ -7,18 +7,18 @@ use web3::types::U256; #[derive(Debug, Clone)] pub struct BlockchainAgentWeb3 { - gas_price_gwei: u64, - gas_limit_const_part: u64, - maximum_added_gas_margin: u64, + gas_price_wei: u128, + gas_limit_const_part: u128, + maximum_added_gas_margin: u128, consuming_wallet: Wallet, consuming_wallet_balances: ConsumingWalletBalances, - pending_transaction_id: U256, + pending_transaction_id: U256, // TODO: GH-744: This should be changed from U256 to something more generic } impl BlockchainAgent for BlockchainAgentWeb3 { fn estimated_transaction_fee_total(&self, number_of_transactions: usize) -> u128 { - let gas_price = self.gas_price_gwei as u128; - let max_gas_limit = (self.maximum_added_gas_margin + self.gas_limit_const_part) as u128; + let gas_price = self.gas_price_wei; + let max_gas_limit = (self.maximum_added_gas_margin + self.gas_limit_const_part); number_of_transactions as u128 * gas_price * max_gas_limit } @@ -26,8 +26,8 @@ impl BlockchainAgent for BlockchainAgentWeb3 { self.consuming_wallet_balances } - fn agreed_fee_per_computation_unit(&self) -> u64 { - self.gas_price_gwei + fn agreed_fee_per_computation_unit(&self) -> u128 { + self.gas_price_wei } fn consuming_wallet(&self) -> &Wallet { @@ -41,18 +41,18 @@ impl BlockchainAgent for BlockchainAgentWeb3 { // 64 * (64 - 12) ... std transaction has data of 64 bytes and 12 bytes are never used with us; // each non-zero byte costs 64 units of gas -pub const WEB3_MAXIMAL_GAS_LIMIT_MARGIN: u64 = 3328; +pub const WEB3_MAXIMAL_GAS_LIMIT_MARGIN: u128 = 3328; impl BlockchainAgentWeb3 { pub fn new( - gas_price_gwei: u64, - gas_limit_const_part: u64, + gas_price_wei: u128, + gas_limit_const_part: u128, consuming_wallet: Wallet, consuming_wallet_balances: ConsumingWalletBalances, pending_transaction_id: U256, ) -> Self { Self { - gas_price_gwei, + gas_price_wei, gas_limit_const_part, consuming_wallet, maximum_added_gas_margin: WEB3_MAXIMAL_GAS_LIMIT_MARGIN, @@ -76,7 +76,7 @@ mod tests { #[test] fn constants_are_correct() { - assert_eq!(WEB3_MAXIMAL_GAS_LIMIT_MARGIN, 3328) + assert_eq!(WEB3_MAXIMAL_GAS_LIMIT_MARGIN, 3_328) } #[test] diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs index 3ded6a16b..099035ade 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs @@ -24,7 +24,7 @@ use web3::types::U256; pub trait BlockchainAgent: Send { fn estimated_transaction_fee_total(&self, number_of_transactions: usize) -> u128; fn consuming_wallet_balances(&self) -> ConsumingWalletBalances; - fn agreed_fee_per_computation_unit(&self) -> u64; + fn agreed_fee_per_computation_unit(&self) -> u128; fn consuming_wallet(&self) -> &Wallet; fn pending_transaction_id(&self) -> U256; diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs index 5de2a6b06..a7af418f6 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs @@ -13,7 +13,7 @@ use std::cell::RefCell; #[derive(Default)] pub struct BlockchainAgentMock { consuming_wallet_balances_results: RefCell>, - agreed_fee_per_computation_unit_results: RefCell>, + agreed_fee_per_computation_unit_results: RefCell>, consuming_wallet_result_opt: Option, pending_transaction_id_results: RefCell>, arbitrary_id_stamp_opt: Option, @@ -28,7 +28,7 @@ impl BlockchainAgent for BlockchainAgentMock { todo!("to be implemented by GH-711") } - fn agreed_fee_per_computation_unit(&self) -> u64 { + fn agreed_fee_per_computation_unit(&self) -> u128 { self.agreed_fee_per_computation_unit_results .borrow_mut() .remove(0) @@ -57,7 +57,7 @@ impl BlockchainAgentMock { self } - pub fn agreed_fee_per_computation_unit_result(self, result: u64) -> Self { + pub fn agreed_fee_per_computation_unit_result(self, result: u128) -> Self { self.agreed_fee_per_computation_unit_results .borrow_mut() .push(result); diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index fe746ae43..a8e106e2c 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -730,7 +730,7 @@ mod tests { blockchain_agent_with_context_msg_actual .agent .agreed_fee_per_computation_unit(), - 10 + 9395240960 ); assert_eq!( blockchain_agent_with_context_msg_actual @@ -742,7 +742,7 @@ mod tests { blockchain_agent_with_context_msg_actual .agent .estimated_transaction_fee_total(1), - 733280 + 688_934_229_114_880 ); assert_eq!( blockchain_agent_with_context_msg_actual.response_skeleton_opt, diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index 054ddb48d..a5a7139b0 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -164,13 +164,12 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { get_gas_price .map_err(PayableTransactionError::GasPriceQueryFailed) .and_then(move |gas_price_wei| { - let gas_price = convert_wei_to_gwei(gas_price_wei); send_payables_within_batch( logger, chain, web3_batch, consuming_wallet, - gas_price, + gas_price_wei, pending_nonce, fingerprints_recipient, affordable_accounts, diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 2e57dd27a..b1f204ff9 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -56,7 +56,7 @@ restart the Node with a value for blockchain-service-url"; pub struct BlockchainInterfaceWeb3 { pub logger: Logger, chain: Chain, - gas_limit_const_part: u64, + gas_limit_const_part: u128, // This must not be dropped for Web3 requests to be completed _event_loop_handle: EventLoopHandle, transport: Http, @@ -224,7 +224,7 @@ impl BlockchainInterfaceWeb3 { } } - pub fn web3_gas_limit_const_part(chain: Chain) -> u64 { + pub fn web3_gas_limit_const_part(chain: Chain) -> u128 { match chain { Chain::EthMainnet | Chain::EthRopsten | Chain::Dev => 55_000, Chain::PolyMainnet | Chain::PolyAmoy => 70_000, @@ -696,7 +696,7 @@ mod tests { let expected_transaction_fee_balance = U256::from(65_520); let expected_masq_balance = U256::from(65_535); let expected_transaction_id = U256::from(35); - let expected_gas_price_gwei = 2; + let expected_gas_price_wei = 1_000_000_000; assert_eq!(result.consuming_wallet(), &wallet); assert_eq!(result.pending_transaction_id(), expected_transaction_id); assert_eq!( @@ -708,12 +708,12 @@ mod tests { ); assert_eq!( result.agreed_fee_per_computation_unit(), - expected_gas_price_gwei + expected_gas_price_wei ); let expected_fee_estimation = (3 * (BlockchainInterfaceWeb3::web3_gas_limit_const_part(chain) + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) - * expected_gas_price_gwei) as u128; + * expected_gas_price_wei) as u128; assert_eq!( result.estimated_transaction_fee_total(3), expected_fee_estimation diff --git a/node/src/blockchain/blockchain_interface_initializer.rs b/node/src/blockchain/blockchain_interface_initializer.rs index f93a5f7f9..1ac48920b 100644 --- a/node/src/blockchain/blockchain_interface_initializer.rs +++ b/node/src/blockchain/blockchain_interface_initializer.rs @@ -84,7 +84,7 @@ mod tests { .unwrap(); assert_eq!(blockchain_agent.consuming_wallet(), &wallet); - assert_eq!(blockchain_agent.agreed_fee_per_computation_unit(), 2); + assert_eq!(blockchain_agent.agreed_fee_per_computation_unit(), 1_000_000_000); } #[test] diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index f0e7d1b00..b08aff8bf 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -89,7 +89,7 @@ pub fn merged_output_data( .collect() } -pub fn transmission_log(chain: Chain, accounts: &[PayableAccount], gas_price: u64) -> String { +pub fn transmission_log(chain: Chain, accounts: &[PayableAccount], gas_price_in_wei: u128) -> String { let chain_name = chain .rec() .literal_identifier @@ -102,11 +102,11 @@ pub fn transmission_log(chain: Chain, accounts: &[PayableAccount], gas_price: u6 Paying to creditors...\n\ Transactions in the batch:\n\ \n\ - gas price: {} gwei\n\ + gas price: {} wei\n\ chain: {}\n\ \n\ [wallet address] [payment in wei]\n", - gas_price, chain_name + gas_price_in_wei, chain_name )); let body = accounts.iter().map(|account| { format!( @@ -141,11 +141,10 @@ pub fn sign_transaction( consuming_wallet: Wallet, amount: u128, nonce: U256, - gas_price_in_gwei: u64, + gas_price_in_wei: U256, ) -> SignedTransaction { let data = sign_transaction_data(amount, recipient_wallet); let gas_limit = gas_limit(data, chain); - let gas_price_in_wei = to_wei(gas_price_in_gwei); // Warning: If you set gas_price or nonce to None in transaction_parameters, sign_transaction will start making RPC calls which we don't want (Do it at your own risk). let transaction_parameters = TransactionParameters { nonce: Some(nonce), @@ -190,7 +189,7 @@ pub fn sign_and_append_payment( consuming_wallet: Wallet, amount: u128, nonce: U256, - gas_price: u64, + gas_price_in_wei: U256, ) -> H256 { let signed_tx = sign_transaction( chain, @@ -199,7 +198,7 @@ pub fn sign_and_append_payment( consuming_wallet, amount, nonce, - gas_price, + gas_price_in_wei, ); append_signed_transaction_to_batch(web3_batch, signed_tx.raw_transaction); signed_tx.transaction_hash @@ -215,7 +214,7 @@ pub fn handle_new_transaction( web3_batch: Web3>, consuming_wallet: Wallet, nonce: U256, - gas_price: u64, + gas_price_in_wei: U256, account: PayableAccount, ) -> HashAndAmount { let hash = sign_and_append_payment( @@ -225,7 +224,7 @@ pub fn handle_new_transaction( consuming_wallet, account.balance_wei, nonce, - gas_price, + gas_price_in_wei, ); HashAndAmount { hash, @@ -238,7 +237,7 @@ pub fn sign_and_append_multiple_payments( chain: Chain, web3_batch: Web3>, consuming_wallet: Wallet, - gas_price: u64, + gas_price_in_wei: U256, mut pending_nonce: U256, accounts: Vec, ) -> Vec { @@ -257,7 +256,7 @@ pub fn sign_and_append_multiple_payments( web3_batch.clone(), consuming_wallet.clone(), pending_nonce, - gas_price, + gas_price_in_wei, payable, ); @@ -276,7 +275,7 @@ pub fn send_payables_within_batch( chain: Chain, web3_batch: Web3>, consuming_wallet: Wallet, - gas_price_in_gwei: u64, + gas_price_in_wei: U256, pending_nonce: U256, new_fingerprints_recipient: Recipient, accounts: Vec, @@ -288,7 +287,7 @@ pub fn send_payables_within_batch( consuming_wallet, chain.rec().contract, chain.rec().num_chain_id, - gas_price_in_gwei + gas_price_in_wei ); let hashes_and_paid_amounts = sign_and_append_multiple_payments( @@ -296,7 +295,7 @@ pub fn send_payables_within_batch( chain, web3_batch.clone(), consuming_wallet, - gas_price_in_gwei, + gas_price_in_wei, pending_nonce, accounts.clone(), ); @@ -316,7 +315,7 @@ pub fn send_payables_within_batch( info!( logger, "{}", - transmission_log(chain, &accounts, gas_price_in_gwei) + transmission_log(chain, &accounts, gas_price_in_wei.as_u128()) ); return Box::new( @@ -344,17 +343,17 @@ pub fn calculate_fallback_start_block_number(start_block_number: u64, max_block_ } pub fn convert_wei_to_gwei(wei: U256) -> u64 { - (wei / U256::from(GWEI_UNIT)).as_u64() + 1 + (wei / U256::from(GWEI_UNIT)).as_u64() } // TODO: GH-744: This function could be part of the trait BlockchainAgent (so gas_limit_const_part can go away) pub fn create_blockchain_agent_web3( - gas_limit_const_part: u64, + gas_limit_const_part: u128, blockchain_agent_future_result: BlockchainAgentFutureResult, wallet: Wallet, ) -> Box { Box::new(BlockchainAgentWeb3::new( - convert_wei_to_gwei(blockchain_agent_future_result.gas_price_wei), + blockchain_agent_future_result.gas_price_wei.as_u128(), gas_limit_const_part, wallet, ConsumingWalletBalances { @@ -448,7 +447,7 @@ mod tests { consuming_wallet, account.balance_wei, pending_nonce.into(), - gas_price, + U256::from(gas_price * 1_000_000_000), ); append_signed_transaction_to_batch(web3_batch.clone(), signed_transaction.raw_transaction); @@ -494,7 +493,7 @@ mod tests { consuming_wallet, account.balance_wei, pending_nonce.into(), - gas_price, + U256::from(gas_price * 1_000_000_000), ); let mut batch_result = web3_batch.eth().transport().submit_batch().wait().unwrap(); @@ -534,7 +533,7 @@ mod tests { web3_batch, consuming_wallet, pending_nonce.into(), - gas_price, + U256::from(gas_price * 1_000_000_000), account, ); @@ -571,7 +570,7 @@ mod tests { chain, web3_batch, consuming_wallet, - gas_price, + U256::from(gas_price * 1_000_000_000), pending_nonce.into(), accounts, ); @@ -723,7 +722,7 @@ mod tests { let logger = Logger::new(test_name); let chain = DEFAULT_CHAIN; let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let gas_price = 1u64; + let gas_price = U256::from(1_000_000_000); let pending_nonce: U256 = 1.into(); let new_fingerprints_recipient = accountant.start().recipient(); let accounts_1 = make_payable_account(1); @@ -803,7 +802,7 @@ mod tests { ); tlh.exists_log_containing(&format!( "INFO: {test_name}: {}", - transmission_log(chain, &accounts, gas_price) + transmission_log(chain, &accounts, gas_price.as_u128()) )); } @@ -824,7 +823,7 @@ mod tests { None, ); let consuming_wallet = make_paying_wallet(consuming_wallet_secret_raw_bytes); - let gas_price = 123; + let gas_price = U256::from(123_000_000_000u64); let nonce = U256::from(1); let os_code = transport_error_code(); let os_msg = transport_error_message(); @@ -874,7 +873,7 @@ mod tests { .unwrap(); let recipient_wallet = make_wallet("unlucky man"); let consuming_wallet = make_wallet("bad_wallet"); - let gas_price = 123; + let gas_price = U256::from(123_000_000_000u64); let nonce = U256::from(1); sign_transaction( @@ -920,7 +919,7 @@ mod tests { let logger = Logger::new(test_name); let chain = DEFAULT_CHAIN; let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let gas_price = 1u64; + let gas_price = U256::from(1_000_000_000); let pending_nonce: U256 = 1.into(); let new_fingerprints_recipient = accountant.start().recipient(); let accounts_1 = make_payable_account(1); @@ -998,7 +997,7 @@ mod tests { ); tlh.exists_log_containing(&format!( "INFO: {test_name}: {}", - transmission_log(chain, &accounts, gas_price) + transmission_log(chain, &accounts, gas_price.as_u128()) )); } @@ -1028,7 +1027,7 @@ mod tests { let logger = Logger::new(test_name); let chain = DEFAULT_CHAIN; let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let gas_price = 1u64; + let gas_price = U256::from(1_000_000_000); let pending_nonce: U256 = 1.into(); let new_fingerprints_recipient = accountant.start().recipient(); let accounts_1 = make_payable_account(1); @@ -1107,7 +1106,7 @@ mod tests { ); tlh.exists_log_containing(&format!( "INFO: {test_name}: {}", - transmission_log(chain, &accounts, gas_price) + transmission_log(chain, &accounts, gas_price.as_u128()) )); } @@ -1122,7 +1121,7 @@ mod tests { let web3 = Web3::new(transport.clone()); let chain = DEFAULT_CHAIN; let amount = 11_222_333_444; - let gas_price_in_gwei = 123000000000_u64; + let gas_price_in_wei = U256::from(123_000_000_000_000_000_000u128); let nonce = U256::from(5); let recipient_wallet = make_wallet("recipient_wallet"); let consuming_wallet = make_paying_wallet(b"consuming_wallet"); @@ -1132,7 +1131,7 @@ mod tests { nonce: Some(nonce), to: Some(chain.rec().contract), gas: gas_limit(data, chain), - gas_price: Some(to_wei(gas_price_in_gwei)), + gas_price: Some(gas_price_in_wei), value: U256::zero(), data: Bytes(data.to_vec()), chain_id: Some(chain.rec().num_chain_id), @@ -1144,7 +1143,7 @@ mod tests { consuming_wallet, amount, nonce, - gas_price_in_gwei, + gas_price_in_wei, ); let expected_tx_result = web3 @@ -1328,7 +1327,7 @@ mod tests { consuming_wallet, payable_account.balance_wei, nonce_correct_type, - gas_price, + U256::from(gas_price * 1_000_000_000), ); let byte_set_to_compare = signed_transaction.raw_transaction.0; From 6a3ceafbd39eb892dfd0d7dadea12f89d9b2fe5e Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 4 Nov 2024 20:32:47 +1300 Subject: [PATCH 14/56] GH-744: finish converting gas price from gwei to wei --- node/src/accountant/mod.rs | 16 ++++++++-------- node/src/blockchain/blockchain_bridge.rs | 12 ++++++------ .../src/blockchain/blockchain_interface_utils.rs | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index 6607c622b..f39788f67 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -3439,10 +3439,10 @@ mod tests { init_test_logging(); let port = find_free_port(); let pending_tx_hash_1 = - H256::from_str("d89f74084be2601c816fb85b8eac6541437223ad4851d12e9eb3d6f74570b8ae") + H256::from_str("713332975a17b82439312ddff602d254f21b7d312dce3a8fbfd83587fe361e15") .unwrap(); let pending_tx_hash_2 = - H256::from_str("05981aa8d6c8ca1661f56a42e6e0c1aa56c9c9d0ecf26755b4388826aad55811") + H256::from_str("caefcf3d42b45f948e8e823e4ae959811e50b219640c3f1580d4471e9b501f1b") .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) // Blockchain Agent Gas Price @@ -3774,16 +3774,16 @@ mod tests { ); let log_handler = TestLogHandler::new(); log_handler.exists_log_containing( - "WARN: Accountant: Broken transactions 0xd89f74084be2601c816fb85b8eac6541437223ad4\ - 851d12e9eb3d6f74570b8ae marked as an error. You should take over the care of those to make sure \ + "WARN: Accountant: Broken transactions 0x713332975a17b82439312ddff602d254f21b7d312\ + dce3a8fbfd83587fe361e15 marked as an error. You should take over the care of those to make sure \ your debts are going to be settled properly. At the moment, there is no automated process \ fixing that without your assistance"); - log_handler.exists_log_matching("INFO: Accountant: Transaction 0x05981aa8d6c8ca1661f56a42e6e\ - 0c1aa56c9c9d0ecf26755b4388826aad55811 has been added to the blockchain; detected locally at \ + log_handler.exists_log_matching("INFO: Accountant: Transaction 0xcaefcf3d42b45f948e8e823e4ae\ + 959811e50b219640c3f1580d4471e9b501f1b has been added to the blockchain; detected locally at \ attempt 4 at \\d{2,}ms after its sending"); log_handler.exists_log_containing( - "INFO: Accountant: Transactions 0x05981aa8d6c8ca1661f56a42e6e0c1aa56c9c9d0e\ - cf26755b4388826aad55811 completed their confirmation process succeeding", + "INFO: Accountant: Transactions 0xcaefcf3d42b45f948e8e823e4ae959811e50b2\ + 19640c3f1580d4471e9b501f1b completed their confirmation process succeeding", ); } diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index a8e106e2c..70b08dd9a 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -878,7 +878,7 @@ mod tests { payment_procedure_result: Ok(vec![Correct(PendingPayable { recipient_wallet: accounts[0].wallet.clone(), hash: H256::from_str( - "43d39b06f417183f925e1726d25c147cdb947dea3d437f898655b7dcb4d29fef" + "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) .unwrap() })]), @@ -894,7 +894,7 @@ mod tests { pending_payable_fingerprint_seeds_msg.hashes_and_balances, vec![HashAndAmount { hash: H256::from_str( - "43d39b06f417183f925e1726d25c147cdb947dea3d437f898655b7dcb4d29fef" + "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) .unwrap(), amount: accounts[0].balance_wei @@ -968,7 +968,7 @@ mod tests { pending_payable_fingerprint_seeds_msg.hashes_and_balances, vec![HashAndAmount { hash: H256::from_str( - "43d39b06f417183f925e1726d25c147cdb947dea3d437f898655b7dcb4d29fef" + "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) .unwrap(), amount: accounts[0].balance_wei @@ -983,7 +983,7 @@ mod tests { context_id: 4321 }), msg: format!( - "ReportAccountsPayable: Sending phase: \"Transport error: Error(IncompleteMessage)\". Signed and hashed transactions: 0x43d39b06f417183f925e1726d25c147cdb947dea3d437f898655b7dcb4d29fef" + "ReportAccountsPayable: Sending phase: \"Transport error: Error(IncompleteMessage)\". Signed and hashed transactions: 0x36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) } ); @@ -1033,7 +1033,7 @@ mod tests { Correct(PendingPayable { recipient_wallet: accounts_1.wallet, hash: H256::from_str( - "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" + "cc73f3d5fe9fc3dac28b510ddeb157b0f8030b201e809014967396cdf365488a" ) .unwrap() }) @@ -1043,7 +1043,7 @@ mod tests { Correct(PendingPayable { recipient_wallet: accounts_2.wallet, hash: H256::from_str( - "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" + "891d9ffa838aedc0bb2f6f7e9737128ce98bb33d07b4c8aa5645871e20d6cd13" ) .unwrap() }) diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index b08aff8bf..ad0b7a364 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -633,7 +633,7 @@ mod tests { "INFO: transmission_log_just_works: Paying to creditors...\n\ Transactions in the batch:\n\ \n\ - gas price: 120 gwei\n\ + gas price: 120 wei\n\ chain: ropsten\n\ \n\ [wallet address] [payment in wei]\n\ From 8f131bba7b1d698e2841a21aeb6a1b7a8500c1e5 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 4 Nov 2024 20:50:23 +1300 Subject: [PATCH 15/56] GH-744: Formating & removed warnings --- .../payable_scanner/agent_web3.rs | 2 +- node/src/accountant/scanners/mod.rs | 45 +++++++++++-------- .../lower_level_interface_web3.rs | 4 +- .../blockchain_interface_web3/mod.rs | 5 +-- .../lower_level_interface.rs | 4 +- .../blockchain_interface_initializer.rs | 9 ++-- .../blockchain/blockchain_interface_utils.rs | 42 ++++++++--------- node/src/blockchain/test_utils.rs | 12 ++--- node/src/neighborhood/mod.rs | 4 +- 9 files changed, 64 insertions(+), 63 deletions(-) diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs index db5cbf90f..4fffa91c7 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs @@ -18,7 +18,7 @@ pub struct BlockchainAgentWeb3 { impl BlockchainAgent for BlockchainAgentWeb3 { fn estimated_transaction_fee_total(&self, number_of_transactions: usize) -> u128 { let gas_price = self.gas_price_wei; - let max_gas_limit = (self.maximum_added_gas_margin + self.gas_limit_const_part); + let max_gas_limit = self.maximum_added_gas_margin + self.gas_limit_const_part; number_of_transactions as u128 * gas_price * max_gas_limit } diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index 34ba82720..026c4a049 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -497,7 +497,7 @@ impl PayableScanner { ) { if let Some(err) = err_opt { match err { - LocallyCausedError(PayableTransactionError::Sending {hashes, ..}) + LocallyCausedError(PayableTransactionError::Sending { hashes, .. }) | RemotelyCausedErrors(hashes) => { self.discard_failed_transactions_with_possible_fingerprints(hashes, logger) } @@ -965,7 +965,11 @@ impl ReceivableScanner { } } - fn handle_new_received_payments_scan_error(&mut self, error: ReceivedPaymentsError, logger: &Logger) { + fn handle_new_received_payments_scan_error( + &mut self, + error: ReceivedPaymentsError, + logger: &Logger, + ) { match error { ReceivedPaymentsError::ExceededBlockScanLimit(max_block_count) => { match self @@ -973,22 +977,25 @@ impl ReceivableScanner { .set_max_block_count(Some(max_block_count)) { Ok(()) => { - debug!(logger, "Updated max_block_count to {} in database.", max_block_count); - }, + debug!( + logger, + "Updated max_block_count to {} in database.", max_block_count + ); + } Err(e) => { panic!( "Attempt to set new max block to {} failed due to: {:?}", max_block_count, e ) - }, + } } } ReceivedPaymentsError::OtherRPCError(rpc_error) => { warning!( - logger, - "Attempted to retrieve received payments but failed: {:?}", - rpc_error - ); + logger, + "Attempted to retrieve received payments but failed: {:?}", + rpc_error + ); } } } @@ -1185,7 +1192,7 @@ mod tests { use crate::database::rusqlite_wrappers::TransactionSafeWrapper; use crate::database::test_utils::transaction_wrapper_mock::TransactionInnerWrapperMockBuilder; use crate::db_config::mocks::ConfigDaoMock; - use crate::db_config::persistent_configuration::{PersistentConfigError, PersistentConfiguration}; + use crate::db_config::persistent_configuration::{PersistentConfigError}; use crate::sub_lib::accountant::{ DaoFactories, FinancialStatistics, PaymentThresholds, ScanIntervals, DEFAULT_PAYMENT_THRESHOLDS, @@ -1875,7 +1882,7 @@ mod tests { &format!("WARN: {test_name}: \ Deleting fingerprints for failed transactions 0x00000000000000000000000000000000000000000000000000000000000015b3, \ 0x0000000000000000000000000000000000000000000000000000000000003039", - )); + )); // we haven't supplied any result for mark_pending_payable() and so it's proved uncalled } @@ -2463,7 +2470,7 @@ mod tests { 00000000000000000000000237 has exceeded the maximum pending time \\({}sec\\) with the age \ \\d+sec and the confirmation process is going to be aborted now at the final attempt 1; manual \ resolution is required from the user to complete the transaction" - ,test_name, DEFAULT_PENDING_TOO_LONG_SEC, ),elapsed_after,capture_regex) + , test_name, DEFAULT_PENDING_TOO_LONG_SEC, ), elapsed_after, capture_regex) } #[test] @@ -2491,7 +2498,7 @@ mod tests { } ); let capture_regex = r#"\s(\d+)ms"#; - assert_log_msg_and_elapsed_time_in_log_makes_sense (&format!( + assert_log_msg_and_elapsed_time_in_log_makes_sense(&format!( "INFO: {test_name}: Pending transaction 0x0000000000000000000000000000000000000000000000000\ 00000000000007b couldn't be confirmed at attempt 1 at \\d+ms after its sending"), elapsed_after_ms, capture_regex); } @@ -3372,11 +3379,14 @@ mod tests { } #[test] - #[should_panic(expected = "Attempt to set new max block to 100000 failed due to: DatabaseError(\"Some bad stuff happened\")")] + #[should_panic( + expected = "Attempt to set new max block to 100000 failed due to: DatabaseError(\"Some bad stuff happened\")" + )] fn receivable_scanner_receives_exceeded_block_scan_limit_error_and_database_wright_fails() { let new_max_block = 100_000u64; - let persistent_config = PersistentConfigurationMock::new() - .set_max_block_count_result(Err(PersistentConfigError::DatabaseError("Some bad stuff happened".to_string()))); + let persistent_config = PersistentConfigurationMock::new().set_max_block_count_result(Err( + PersistentConfigError::DatabaseError("Some bad stuff happened".to_string()), + )); let mut subject = ReceivableScannerBuilder::new() .persistent_configuration(persistent_config) .build(); @@ -3393,8 +3403,7 @@ mod tests { fn receivable_scanner_receives_other_rpc_error() { init_test_logging(); let test_name = "receivable_scanner_receives_other_rpc_error"; - let mut subject = ReceivableScannerBuilder::new() - .build(); + let mut subject = ReceivableScannerBuilder::new().build(); let msg = ReceivedPayments { timestamp: SystemTime::now(), scan_result: Err(OtherRPCError("Dead RPC".to_string())), diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index a5a7139b0..8141124ce 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -9,9 +9,7 @@ use crate::blockchain::blockchain_interface::data_structures::errors::{ }; use crate::blockchain::blockchain_interface::data_structures::ProcessedPayableFallible; use crate::blockchain::blockchain_interface::lower_level_interface::LowBlockchainInt; -use crate::blockchain::blockchain_interface_utils::{ - convert_wei_to_gwei, send_payables_within_batch, -}; +use crate::blockchain::blockchain_interface_utils::send_payables_within_batch; use crate::sub_lib::wallet::Wallet; use actix::Recipient; use ethereum_types::{H256, U256, U64}; diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index b1f204ff9..04e2a0ff4 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -513,7 +513,6 @@ mod tests { }) ); - // TODO: GH-543: Improve MBCS so we can confirm the calls we make are the correct ones. // Example of older code // let requests = test_server.requests_so_far(); @@ -535,8 +534,7 @@ mod tests { #[test] #[should_panic(expected = "No address for an uninitialized wallet!")] - fn retrieving_address_of_uninitialised_wallet_panics( - ) { + fn retrieving_address_of_uninitialised_wallet_panics() { let subject = Wallet::new("0x3f69f9efd4f2592fd70beecd9dce71c472fc"); subject.address(); @@ -720,7 +718,6 @@ mod tests { ) } - // TODO: GH-744: Migrate test to the place after the helper function below this test. // You'll find three more tests with a simplified api and I believe that the way it is done will suite also this test. // Please could do this for better hygiene so that our workspace is cleaner looking forward? diff --git a/node/src/blockchain/blockchain_interface/lower_level_interface.rs b/node/src/blockchain/blockchain_interface/lower_level_interface.rs index 9109159d3..8208c4b11 100644 --- a/node/src/blockchain/blockchain_interface/lower_level_interface.rs +++ b/node/src/blockchain/blockchain_interface/lower_level_interface.rs @@ -40,8 +40,8 @@ pub trait LowBlockchainInt { ) -> Box>; fn get_transaction_receipt_in_batch( - &self, - hash_vec: Vec, + &self, + hash_vec: Vec, ) -> Box, Error = BlockchainError>>; fn get_contract(&self) -> Contract; diff --git a/node/src/blockchain/blockchain_interface_initializer.rs b/node/src/blockchain/blockchain_interface_initializer.rs index 1ac48920b..06fbf491b 100644 --- a/node/src/blockchain/blockchain_interface_initializer.rs +++ b/node/src/blockchain/blockchain_interface_initializer.rs @@ -62,8 +62,8 @@ mod tests { #[test] fn initialize_web3_interface_works() { let port = find_free_port(); - let blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0)// gas_price = 10000000000 + let _blockchain_client_server = MBCSBuilder::new(port) + .response("0x3B9ACA00".to_string(), 0) // gas_price = 10000000000 .response("0xFF40".to_string(), 0) .response( "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), @@ -84,7 +84,10 @@ mod tests { .unwrap(); assert_eq!(blockchain_agent.consuming_wallet(), &wallet); - assert_eq!(blockchain_agent.agreed_fee_per_computation_unit(), 1_000_000_000); + assert_eq!( + blockchain_agent.agreed_fee_per_computation_unit(), + 1_000_000_000 + ); } #[test] diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index ad0b7a364..6411cd180 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -9,7 +9,7 @@ use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::agent_w use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; use crate::blockchain::blockchain_interface::blockchain_interface_web3::{ - to_wei, BlockchainInterfaceWeb3, HashAndAmount, TRANSFER_METHOD_ID, + BlockchainInterfaceWeb3, HashAndAmount, TRANSFER_METHOD_ID, }; use crate::blockchain::blockchain_interface::data_structures::errors::PayableTransactionError; use crate::blockchain::blockchain_interface::data_structures::{ @@ -31,8 +31,6 @@ use web3::types::{Bytes, SignedTransaction, TransactionParameters, H256, U256}; use web3::Error as Web3Error; use web3::Web3; -const GWEI_UNIT: u64 = 1_000_000_000; // 1 Gwei = 1e9 Wei - #[derive(Debug)] pub struct BlockchainAgentFutureResult { pub gas_price_wei: U256, @@ -89,7 +87,11 @@ pub fn merged_output_data( .collect() } -pub fn transmission_log(chain: Chain, accounts: &[PayableAccount], gas_price_in_wei: u128) -> String { +pub fn transmission_log( + chain: Chain, + accounts: &[PayableAccount], + gas_price_in_wei: u128, +) -> String { let chain_name = chain .rec() .literal_identifier @@ -342,10 +344,6 @@ pub fn calculate_fallback_start_block_number(start_block_number: u64, max_block_ } } -pub fn convert_wei_to_gwei(wei: U256) -> u64 { - (wei / U256::from(GWEI_UNIT)).as_u64() -} - // TODO: GH-744: This function could be part of the trait BlockchainAgent (so gas_limit_const_part can go away) pub fn create_blockchain_agent_web3( gas_limit_const_part: u128, @@ -510,7 +508,6 @@ mod tests { ); } - // TODO: GH-744: Review this test and the test below it, do we really need both? #[test] fn handle_new_transaction_works() { @@ -710,7 +707,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .response("rpc_result".to_string(), 7) @@ -741,13 +738,14 @@ mod tests { new_fingerprints_recipient, accounts.clone(), ) - .wait(); + .wait(); System::current().stop(); system.run(); let timestamp_after = SystemTime::now(); let accountant_recording_result = accountant_recording.lock().unwrap(); - let ppfs_message = accountant_recording_result.get_record::(0); + let ppfs_message = + accountant_recording_result.get_record::(0); assert_eq!(accountant_recording_result.len(), 1); assert!(timestamp_before <= ppfs_message.batch_wide_timestamp); assert!(timestamp_after >= ppfs_message.batch_wide_timestamp); @@ -758,14 +756,14 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap(), + .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap(), + .unwrap(), amount: accounts_2.balance_wei }, ] @@ -778,7 +776,7 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap() + .unwrap() }) ); assert_eq!( @@ -788,7 +786,7 @@ mod tests { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap() + .unwrap() }) ); let tlh = TestLogHandler::new(); @@ -944,7 +942,8 @@ mod tests { system.run(); let timestamp_after = SystemTime::now(); let accountant_recording_result = accountant_recording.lock().unwrap(); - let ppfs_message = accountant_recording_result.get_record::(0); + let ppfs_message = + accountant_recording_result.get_record::(0); assert_eq!(accountant_recording_result.len(), 1); assert!(timestamp_before <= ppfs_message.batch_wide_timestamp); assert!(timestamp_after >= ppfs_message.batch_wide_timestamp); @@ -968,7 +967,7 @@ mod tests { ] ); let processed_payments = result.unwrap(); - assert_eq!(processed_payments[0], Failed(RpcPayableFailure{ + assert_eq!(processed_payments[0], Failed(RpcPayableFailure { rpc_error: Rpc(Error { code: ServerError(429), message: "The requests per second (RPS) of your requests are higher than your plan allows.".to_string(), @@ -977,7 +976,7 @@ mod tests { recipient_wallet: accounts_1.wallet, hash: H256::from_str("35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4").unwrap(), })); - assert_eq!(processed_payments[1], Failed(RpcPayableFailure{ + assert_eq!(processed_payments[1], Failed(RpcPayableFailure { rpc_error: Rpc(Error { code: ServerError(429), message: "The requests per second (RPS) of your requests are higher than your plan allows.".to_string(), @@ -1052,7 +1051,8 @@ mod tests { system.run(); let timestamp_after = SystemTime::now(); let accountant_recording_result = accountant_recording.lock().unwrap(); - let ppfs_message = accountant_recording_result.get_record::(0); + let ppfs_message = + accountant_recording_result.get_record::(0); assert_eq!(accountant_recording_result.len(), 1); assert!(timestamp_before <= ppfs_message.batch_wide_timestamp); assert!(timestamp_after >= ppfs_message.batch_wide_timestamp); @@ -1086,7 +1086,7 @@ mod tests { .unwrap() }) ); - assert_eq!(processed_payments[1], ProcessedPayableFallible::Failed(RpcPayableFailure{ + assert_eq!(processed_payments[1], ProcessedPayableFallible::Failed(RpcPayableFailure { rpc_error: Rpc(Error { code: ServerError(429), message: "The requests per second (RPS) of your requests are higher than your plan allows.".to_string(), diff --git a/node/src/blockchain/test_utils.rs b/node/src/blockchain/test_utils.rs index d5838a186..2110f80b3 100644 --- a/node/src/blockchain/test_utils.rs +++ b/node/src/blockchain/test_utils.rs @@ -2,24 +2,19 @@ #![cfg(test)] -use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; -use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; use crate::blockchain::blockchain_interface::blockchain_interface_web3::{ BlockchainInterfaceWeb3, REQUESTS_IN_PARALLEL, }; use crate::blockchain::blockchain_interface::data_structures::errors::{ - BlockchainAgentBuildError, BlockchainError, PayableTransactionError, -}; -use crate::blockchain::blockchain_interface::data_structures::{ - ProcessedPayableFallible, RetrievedBlockchainTransactions, + BlockchainAgentBuildError, BlockchainError, }; +use crate::blockchain::blockchain_interface::data_structures::RetrievedBlockchainTransactions; use crate::blockchain::blockchain_interface::lower_level_interface::LowBlockchainInt; use crate::blockchain::blockchain_interface::BlockchainInterface; use crate::set_arbitrary_id_stamp_in_mock_impl; use crate::sub_lib::wallet::Wallet; use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp; -use actix::Recipient; use bip39::{Language, Mnemonic, Seed}; use ethabi::Hash; use ethereum_types::{BigEndianHash, H160, H256, U64}; @@ -34,11 +29,10 @@ use std::cell::RefCell; use std::fmt::Debug; use std::net::Ipv4Addr; use std::sync::{Arc, Mutex}; -use web3::transports::{Batch, EventLoopHandle, Http}; +use web3::transports::{EventLoopHandle, Http}; use web3::types::{ Address, BlockNumber, Index, Log, SignedTransaction, TransactionReceipt, H2048, U256, }; -use web3::Web3; lazy_static! { static ref BIG_MEANINGLESS_PHRASE: Vec<&'static str> = vec![ diff --git a/node/src/neighborhood/mod.rs b/node/src/neighborhood/mod.rs index 8c3c2d522..c229bb10b 100644 --- a/node/src/neighborhood/mod.rs +++ b/node/src/neighborhood/mod.rs @@ -508,8 +508,8 @@ impl Neighborhood { fn handle_route_query_message(&mut self, msg: RouteQueryMessage) -> Option { if let Some(ref url) = msg.hostname_opt { - if let Ok(ip) = url.parse::() { - if ip == IpAddr::V4(Ipv4Addr::new(0,0,0,0)) { + if let Ok(ip) = url.parse::() { + if ip == IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)) { error!(self.logger, "Request to wildcard IP detected 0.0.0.0. Most likely because Blockchain Service URL is not set"); return None; } From 67a978603628994ab44a194f266463a9c5019b75 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Tue, 5 Nov 2024 23:16:22 +1300 Subject: [PATCH 16/56] GH-744: Added TransactionFailed to TransactionReceiptResult --- node/src/accountant/mod.rs | 84 +++++------ node/src/accountant/scanners/mod.rs | 81 ++--------- .../src/accountant/scanners/scanners_utils.rs | 9 +- node/src/blockchain/blockchain_bridge.rs | 66 +++++---- .../lower_level_interface_web3.rs | 106 ++++++++++---- .../blockchain_interface_web3/mod.rs | 46 +++--- .../blockchain/blockchain_interface/mod.rs | 5 +- .../blockchain_interface/test_utils.rs | 133 ------------------ 8 files changed, 193 insertions(+), 337 deletions(-) delete mode 100644 node/src/blockchain/blockchain_interface/test_utils.rs diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index f39788f67..f7b0a5b6b 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -501,9 +501,9 @@ impl Accountant { if !self.our_wallet(wallet) { match self.receivable_dao .as_ref() - .more_money_receivable(timestamp,wallet, total_charge) { + .more_money_receivable(timestamp, wallet, total_charge) { Ok(_) => (), - Err(ReceivableDaoError::SignConversion(_)) => error! ( + Err(ReceivableDaoError::SignConversion(_)) => error!( self.logger, "Overflow error recording service provided for {}: service rate {}, byte rate {}, payload size {}. Skipping", wallet, @@ -511,7 +511,7 @@ impl Accountant { byte_rate, payload_size ), - Err(e)=> panic!("Recording services provided for {} but has hit fatal database error: {:?}", wallet, e) + Err(e) => panic!("Recording services provided for {} but has hit fatal database error: {:?}", wallet, e) }; } else { warning!( @@ -535,9 +535,9 @@ impl Accountant { if !self.our_wallet(wallet) { match self.payable_dao .as_ref() - .more_money_payable(timestamp, wallet,total_charge){ + .more_money_payable(timestamp, wallet, total_charge) { Ok(_) => (), - Err(PayableDaoError::SignConversion(_)) => error! ( + Err(PayableDaoError::SignConversion(_)) => error!( self.logger, "Overflow error recording consumed services from {}: total charge {}, service rate {}, byte rate {}, payload size {}. Skipping", wallet, @@ -743,7 +743,7 @@ impl Accountant { stats_opt, query_results_opt, } - .tmb(context_id) + .tmb(context_id) } fn request_payable_accounts_by_specific_mode( @@ -1032,11 +1032,11 @@ pub fn checked_conversion>(num: T) -> S { politely_checked_conversion(num).unwrap_or_else(|msg| panic!("{}", msg)) } -pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { +pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { (T::from(gwei)).mul(T::from(WEIS_IN_GWEI as u32)) } -pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { +pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { checked_conversion::(wei.div(S::from(WEIS_IN_GWEI as u32))) } @@ -1364,7 +1364,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Receivables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1456,7 +1456,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Payables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1523,8 +1523,7 @@ mod tests { } #[test] - fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge( - ) { + fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge() { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1616,8 +1615,7 @@ mod tests { } #[test] - fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge( - ) { + fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge() { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1765,7 +1763,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1820,7 +1818,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; let second_message = first_message.clone(); let peer_actors = peer_actors_builder() @@ -2011,8 +2009,7 @@ mod tests { } #[test] - fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block( - ) { + fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block() { let more_money_received_params_arc = Arc::new(Mutex::new(vec![])); let commit_params_arc = Arc::new(Mutex::new(vec![])); let set_by_guest_transaction_params_arc = Arc::new(Mutex::new(vec![])); @@ -2711,7 +2708,7 @@ mod tests { addr.try_send(ScanForPayables { response_skeleton_opt: None, }) - .unwrap(); + .unwrap(); // We ignored the second ScanForPayables message because the first message meant a scan // was already in progress; now let's make it look like that scan has ended so that we @@ -2724,7 +2721,7 @@ mod tests { .mark_as_ended(&Logger::new("irrelevant")) }), }) - .unwrap(); + .unwrap(); addr.try_send(message_after.clone()).unwrap(); system.run(); let recording = blockchain_bridge_recording.lock().unwrap(); @@ -3736,7 +3733,7 @@ mod tests { vec![ vec![rowid_for_account_1, rowid_for_account_2], vec![rowid_for_account_1, rowid_for_account_2], - vec![rowid_for_account_2] + vec![rowid_for_account_2], ] ); let mark_failure_params = mark_failure_params_arc.lock().unwrap(); @@ -3774,7 +3771,7 @@ mod tests { ); let log_handler = TestLogHandler::new(); log_handler.exists_log_containing( - "WARN: Accountant: Broken transactions 0x713332975a17b82439312ddff602d254f21b7d312\ + "WARN: Accountant: Broken transactions 0x713332975a17b82439312ddff602d254f21b7d312\ dce3a8fbfd83587fe361e15 marked as an error. You should take over the care of those to make sure \ your debts are going to be settled properly. At the moment, there is no automated process \ fixing that without your assistance"); @@ -4033,7 +4030,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4117,7 +4114,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4180,7 +4177,7 @@ mod tests { }), query_results_opt: None } - .tmb(context_id) + .tmb(context_id) ) } @@ -4257,12 +4254,12 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 58, pending_payable_hash_opt: None - },]), + }, ]), receivable_opt: Some(vec![UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), age_s: extracted_receivable_ages[0], balance_gwei: 3_788_455 - },]) + }, ]) }), } ); @@ -4423,7 +4420,7 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 5, pending_payable_hash_opt: None - },]), + }, ]), receivable_opt: Some(vec![ UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), @@ -4612,8 +4609,7 @@ mod tests { expected = "Broken code: PayableAccount with less than 1 gwei passed through db query \ constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 8686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei( - ) { + fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei() { let payable_accounts_retrieved = vec![PayableAccount { wallet: make_wallet("abcd123"), balance_wei: 8_686_005, @@ -4649,8 +4645,7 @@ mod tests { expected = "Broken code: ReceivableAccount with balance between 1 and 0 gwei passed through \ db query constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 7686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei( - ) { + fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei() { let receivable_accounts_retrieved = vec![ReceivableAccount { wallet: make_wallet("abcd123"), balance_wei: 7_686_005, @@ -4736,7 +4731,7 @@ mod tests { fn checked_conversion_without_panic() { let result = politely_checked_conversion::(u128::MAX); - assert_eq!(result,Err("Overflow detected with 340282366920938463463374607431768211455: cannot be converted from u128 to i128".to_string())) + assert_eq!(result, Err("Overflow detected with 340282366920938463463374607431768211455: cannot be converted from u128 to i128".to_string())) } #[test] @@ -4889,11 +4884,10 @@ pub mod exportable_test_parts { } } - fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao( - ) -> ShouldWeRunTheTest { + fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao() -> ShouldWeRunTheTest { fn skip_down_to_first_line_saying_new_delinquencies( - previous: impl Iterator, - ) -> impl Iterator { + previous: impl Iterator, + ) -> impl Iterator { previous .skip_while(|line| { let adjusted_line: String = line @@ -4904,7 +4898,7 @@ pub mod exportable_test_parts { }) .skip(1) } - fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { + fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { fn yield_if_contains_semicolon(line: &str) -> Option { line.contains(';').then(|| line.to_string()) } @@ -4943,13 +4937,13 @@ pub mod exportable_test_parts { skip_down_to_first_line_saying_new_delinquencies( lines_with_cut_fn_trait_definition, ) - .take_while(|line| { - let adjusted_line: String = line - .chars() - .skip_while(|char| char.is_whitespace()) - .collect(); - !adjusted_line.starts_with("fn") - }); + .take_while(|line| { + let adjusted_line: String = line + .chars() + .skip_while(|char| char.is_whitespace()) + .collect(); + !adjusted_line.starts_with("fn") + }); assert_is_not_trait_definition(assumed_implemented_function_body) } fn user_defined_functions_detected(line_undivided_fn_body: &str) -> bool { diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index 026c4a049..cf0f2f15f 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -321,7 +321,7 @@ impl PayableScanner { logger: &Logger, ) -> Vec { fn pass_payables_and_drop_points( - qp_tp: impl Iterator, + qp_tp: impl Iterator, ) -> Vec { let (payables, _) = qp_tp.unzip::<_, _, Vec, Vec<_>>(); payables @@ -677,9 +677,13 @@ impl PendingPayableScanner { msg.fingerprints_with_receipts.into_iter().fold( scan_report, |scan_report_so_far, (receipt_result, fingerprint)| match receipt_result { - TransactionReceiptResult::Found(receipt) => self.interpret_transaction_receipt( + TransactionReceiptResult::Found(_receipt) => handle_status_with_success( + scan_report_so_far, + fingerprint, + logger, + ), + TransactionReceiptResult::TransactionFailed(_receipt) => handle_status_with_failure( scan_report_so_far, - &receipt, fingerprint, logger, ), @@ -699,41 +703,6 @@ impl PendingPayableScanner { ) } - fn interpret_transaction_receipt( - &self, - scan_report: PendingPayableScanReport, - receipt: &TransactionReceipt, - fingerprint: PendingPayableFingerprint, - logger: &Logger, - ) -> PendingPayableScanReport { - const WEB3_SUCCESS: u64 = 1; - const WEB3_FAILURE: u64 = 0; - - match receipt.status { - None => handle_none_status( - scan_report, - fingerprint, - self.when_pending_too_long_sec, - logger, - ), - Some(status_code) => { - let code = status_code.as_u64(); - //TODO: failures handling is going to need enhancement suggested by GH-693 - if code == WEB3_FAILURE { - handle_status_with_failure(scan_report, fingerprint, logger) - } else if code == WEB3_SUCCESS { - handle_status_with_success(scan_report, fingerprint, logger) - } else { - unreachable!( - "tx receipt for pending {:?}: status code other than 0 or 1 \ - shouldn't be possible, but was {}", - fingerprint.hash, code - ) - } - } - } - } - fn process_transactions_by_reported_state( &mut self, scan_report: PendingPayableScanReport, @@ -1166,7 +1135,7 @@ mod tests { use crate::accountant::db_access_objects::utils::{from_time_t, to_time_t}; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::msgs::QualifiedPayablesMessage; use crate::accountant::scanners::scanners_utils::payable_scanner_utils::PendingPayableMetadata; - use crate::accountant::scanners::scanners_utils::pending_payable_scanner_utils::PendingPayableScanReport; + use crate::accountant::scanners::scanners_utils::pending_payable_scanner_utils::{handle_none_status, handle_status_with_failure, PendingPayableScanReport}; use crate::accountant::scanners::test_utils::{ make_empty_payments_and_start_block, protect_payables_in_test, }; @@ -1666,9 +1635,9 @@ mod tests { (vals.intruder_for_hash_2, 5), (vals.common_hash_3, 6), ] - .iter() - .map(|(hash, _rowid)| *hash) - .collect::>(); + .iter() + .map(|(hash, _rowid)| *hash) + .collect::>(); let result = PayableScanner::is_symmetrical( pending_payables_ref_from_blockchain_bridge, @@ -2406,7 +2375,7 @@ mod tests { let logger = Logger::new(test_name); let scan_report = PendingPayableScanReport::default(); - subject.interpret_transaction_receipt(scan_report, &tx_receipt, fingerprint, &logger) + handle_none_status(scan_report, fingerprint, when_pending_too_long_sec, &logger) } fn assert_log_msg_and_elapsed_time_in_log_makes_sense( @@ -2441,8 +2410,7 @@ mod tests { } #[test] - fn interpret_transaction_receipt_when_transaction_status_is_none_and_outside_waiting_interval() - { + fn interpret_transaction_receipt_when_transaction_status_is_none_and_outside_waiting_interval() { let test_name = "interpret_transaction_receipt_when_transaction_status_is_none_and_outside_waiting_interval"; let hash = make_tx_hash(0x237); let rowid = 466; @@ -2534,24 +2502,6 @@ mod tests { ), elapsed_after_ms, capture_regex); } - #[test] - #[should_panic( - expected = "tx receipt for pending 0x000000000000000000000000000000000000000000000000000000000000007b: \ - status code other than 0 or 1 shouldn't be possible, but was 456" - )] - fn interpret_transaction_receipt_panics_at_undefined_status_code() { - let mut tx_receipt = TransactionReceipt::default(); - tx_receipt.status = Some(U64::from(456)); - let mut fingerprint = make_pending_payable_fingerprint(); - fingerprint.hash = make_tx_hash(0x7b); - let subject = PendingPayableScannerBuilder::new().build(); - let scan_report = PendingPayableScanReport::default(); - let logger = Logger::new("test"); - - let _ = - subject.interpret_transaction_receipt(scan_report, &tx_receipt, fingerprint, &logger); - } - #[test] fn interpret_transaction_receipt_when_transaction_status_is_a_failure() { init_test_logging(); @@ -2571,14 +2521,13 @@ mod tests { let logger = Logger::new(test_name); let scan_report = PendingPayableScanReport::default(); - let result = - subject.interpret_transaction_receipt(scan_report, &tx_receipt, fingerprint, &logger); + let result = handle_status_with_failure(scan_report, fingerprint, &logger); assert_eq!( result, PendingPayableScanReport { still_pending: vec![], - failures: vec![PendingPayableId::new(777777, hash,)], + failures: vec![PendingPayableId::new(777777, hash, )], confirmed: vec![] } ); diff --git a/node/src/accountant/scanners/scanners_utils.rs b/node/src/accountant/scanners/scanners_utils.rs index 429a36b05..e730bba08 100644 --- a/node/src/accountant/scanners/scanners_utils.rs +++ b/node/src/accountant/scanners/scanners_utils.rs @@ -156,10 +156,10 @@ pub mod payable_scanner_utils { add_pending_payable(acc, pending_payable) } ProcessedPayableFallible::Failed(RpcPayableFailure { - rpc_error, - recipient_wallet, - hash, - }) => { + rpc_error, + recipient_wallet, + hash, + }) => { warning!(logger, "Remote transaction failure: '{}' for payment to {} and transaction hash {:?}. \ Please check your blockchain service URL configuration.", rpc_error, recipient_wallet, hash ); @@ -383,6 +383,7 @@ pub mod pending_payable_scanner_utils { scan_report } + //TODO: failures handling is going to need enhancement suggested by GH-693 pub fn handle_status_with_failure( mut scan_report: PendingPayableScanReport, fingerprint: PendingPayableFingerprint, diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 70b08dd9a..2fe81e565 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -246,7 +246,7 @@ impl BlockchainBridge { fn handle_qualified_payable_msg( &mut self, incoming_message: QualifiedPayablesMessage, - ) -> Box> { + ) -> Box> { // TODO rewrite this into a batch call as soon as GH-629 gets into master let accountant_recipient = self.payable_payments_setup_subs_opt.clone(); return Box::new( @@ -271,7 +271,7 @@ impl BlockchainBridge { fn handle_outbound_payments_instructions( &mut self, msg: OutboundPaymentsInstructions, - ) -> Box> { + ) -> Box> { let skeleton_opt = msg.response_skeleton_opt; let sent_payable_subs = self .sent_payable_subs_opt @@ -306,11 +306,11 @@ impl BlockchainBridge { fn handle_retrieve_transactions( &mut self, msg: RetrieveTransactions, - ) -> Box> { + ) -> Box> { let start_block_nbr = match self.persistent_config.start_block() { - Ok (sb) => sb, - Err (e) => panic! ("Cannot retrieve start block from database; payments to you may not be processed: {:?}", e) - }; + Ok(sb) => sb, + Err(e) => panic!("Cannot retrieve start block from database; payments to you may not be processed: {:?}", e) + }; let max_block_count = match self.persistent_config.max_block_count() { Ok(Some(mbc)) => mbc, _ => u64::MAX, @@ -377,7 +377,7 @@ impl BlockchainBridge { fn handle_request_transaction_receipts( &mut self, msg: RequestTransactionReceipts, - ) -> Box> { + ) -> Box> { let accountant_recipient = self .pending_payable_confirmation .report_transaction_receipts_sub_opt @@ -427,7 +427,7 @@ impl BlockchainBridge { fn handle_scan_future(&mut self, handler: F, scan_type: ScanType, msg: M) where - F: FnOnce(&mut BlockchainBridge, M) -> Box>, + F: FnOnce(&mut BlockchainBridge, M) -> Box>, M: SkeletonOptHolder, { let skeleton_opt = msg.skeleton_opt(); @@ -436,6 +436,9 @@ impl BlockchainBridge { let future = handler(self, msg).map_err(move |e| { warning!(logger, "{}", e); // TODO: This ScanError needs to be removed, And added into OutboundPaymentsInstructions & QualifiedPayablesMessage + // There are certain cases when its a partial error and we are triggering errors that will send ScanError messages. + // In case we dont send this message at all and instead we use the above two mentioned messages to send total failure and partial failure. + // BlockchainBridge wont segregate the messages and Accountant can later on deal with success, partial failures and total failures accordingly. scan_error_subs_opt .as_ref() .expect("Accountant not bound") @@ -454,7 +457,7 @@ impl BlockchainBridge { &self, agent: Box, affordable_accounts: Vec, - ) -> Box, Error = PayableTransactionError>> + ) -> Box, Error=PayableTransactionError>> { let new_fingerprints_recipient = self.new_fingerprints_recipient(); let logger = self.logger.clone(); @@ -600,7 +603,7 @@ mod tests { addr.try_send(BindMessage { peer_actors: peer_actors_builder().build(), }) - .unwrap(); + .unwrap(); System::current().stop(); system.run(); @@ -643,10 +646,9 @@ mod tests { } #[test] - fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant( - ) { + fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant() { let system = System::new( - "qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant", + "qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant", ); let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) @@ -811,8 +813,7 @@ mod tests { } #[test] - fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant( - ) { + fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant() { let system = System::new( "handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant", ); @@ -880,7 +881,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap() + .unwrap() })]), response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, @@ -896,7 +897,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -970,7 +971,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -1035,7 +1036,7 @@ mod tests { hash: H256::from_str( "cc73f3d5fe9fc3dac28b510ddeb157b0f8030b201e809014967396cdf365488a" ) - .unwrap() + .unwrap() }) ); assert_eq!( @@ -1045,7 +1046,7 @@ mod tests { hash: H256::from_str( "891d9ffa838aedc0bb2f6f7e9737128ce98bb33d07b4c8aa5645871e20d6cd13" ) - .unwrap() + .unwrap() }) ); let recording = accountant_recording.lock().unwrap(); @@ -1162,6 +1163,7 @@ mod tests { process_error: None, }; let first_response = ReceiptResponseBuilder::default() + .status(U64::from(1)) .transaction_hash(hash_1) .build(); let port = find_free_port(); @@ -1204,6 +1206,7 @@ mod tests { let scan_error_message = accountant_recording.get_record::(1); let mut expected_receipt = TransactionReceipt::default(); expected_receipt.transaction_hash = hash_1; + expected_receipt.status = Some(U64::from(1)); assert_eq!( report_transaction_receipt_message, &ReportTransactionReceipts { @@ -1280,12 +1283,12 @@ mod tests { ); let message_2 = recording.get_record::(1); assert_eq!( - message_2, - &ScanError { - scan_type: ScanType::Receivables, - response_skeleton_opt: None, - msg: "Error while retrieving transactions: OtherRPCError(\"Attempted to retrieve received payments but failed: QueryFailed(\\\"Transport error: Error(IncompleteMessage)\\\")\")".to_string() - } + message_2, + &ScanError { + scan_type: ScanType::Receivables, + response_skeleton_opt: None, + msg: "Error while retrieving transactions: OtherRPCError(\"Attempted to retrieve received payments but failed: QueryFailed(\\\"Transport error: Error(IncompleteMessage)\\\")\")".to_string() + } ); assert_eq!(recording.len(), 2); TestLogHandler::new().exists_log_containing( @@ -1294,14 +1297,14 @@ mod tests { } #[test] - fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort( - ) { + fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort() { init_test_logging(); let port = find_free_port(); let block_number = U64::from(4545454); let contract_address = H160::from_low_u64_be(887766); let tx_receipt_response = ReceiptResponseBuilder::default() .block_number(block_number) + .status(U64::from(1)) .contract_address(contract_address) .build(); let _blockchain_client_server = MBCSBuilder::new(port) @@ -1357,6 +1360,7 @@ mod tests { let mut transaction_receipt = TransactionReceipt::default(); transaction_receipt.block_number = Some(block_number); transaction_receipt.contract_address = Some(contract_address); + transaction_receipt.status = Some(U64::from(1)); let blockchain_interface = make_blockchain_interface_web3(Some(port)); let system = System::new("test_transaction_receipts"); let mut subject = BlockchainBridge::new( @@ -1652,7 +1656,7 @@ mod tests { let earning_wallet = make_wallet("earning_wallet"); let amount = 996000000; let expected_transactions = RetrievedBlockchainTransactions { - new_start_block: 1000000001, + new_start_block: 1000000000, transactions: vec![BlockchainTransaction { block_number: 2000, from: earning_wallet.clone(), @@ -1742,7 +1746,7 @@ mod tests { blockchain_interface.logger = logger; let persistent_config = PersistentConfigurationMock::new() .start_block_result(Ok(6)) - .max_block_count_result(Err(PersistentConfigError::NotPresent)); + .max_block_count_result(Err(PersistentConfigError::DatabaseError("my tummy hurts".to_string()))); let subject = BlockchainBridge::new( Box::new(blockchain_interface), Box::new(persistent_config), @@ -2043,7 +2047,7 @@ pub mod exportable_test_parts { use crate::test_utils::unshared_test_utils::SubsFactoryTestAddrLeaker; impl SubsFactory - for SubsFactoryTestAddrLeaker + for SubsFactoryTestAddrLeaker { fn make(&self, addr: &Addr) -> BlockchainBridgeSubs { self.send_leaker_msg_and_return_meaningless_subs( diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index 8141124ce..c21f802dc 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -26,6 +26,7 @@ use web3::Web3; pub enum TransactionReceiptResult { NotPresent, Found(TransactionReceipt), + TransactionFailed(TransactionReceipt), Error(String), } @@ -40,7 +41,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_fee_balance( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.web3 .eth() @@ -52,7 +53,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_service_fee_balance( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.contract .query("balanceOf", address, None, Options::default(), None) @@ -60,7 +61,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } - fn get_gas_price(&self) -> Box> { + fn get_gas_price(&self) -> Box> { Box::new( self.web3 .eth() @@ -69,7 +70,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } - fn get_block_number(&self) -> Box> { + fn get_block_number(&self) -> Box> { Box::new( self.web3 .eth() @@ -81,7 +82,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_id( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.web3 .eth() @@ -93,7 +94,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_receipt_in_batch( &self, hash_vec: Vec, - ) -> Box, Error = BlockchainError>> { + ) -> Box, Error=BlockchainError>> { let _ = hash_vec.into_iter().map(|hash| { self.web3_batch.eth().transaction_receipt(hash); }); @@ -108,7 +109,20 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { .map(|response| match response { Ok(result) => { match serde_json::from_value::(result) { - Ok(receipt) => TransactionReceiptResult::Found(receipt), + Ok(receipt) => { + match receipt.status { + None => { + TransactionReceiptResult::NotPresent + } + Some(status) => { + if status == U64::from(1) { + TransactionReceiptResult::Found(receipt) + } else { + TransactionReceiptResult::TransactionFailed(receipt) + } + } + } + } Err(e) => { if e.to_string().contains("invalid type: null") { TransactionReceiptResult::NotPresent @@ -133,7 +147,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_logs( &self, filter: Filter, - ) -> Box, Error = BlockchainError>> { + ) -> Box, Error=BlockchainError>> { Box::new( self.web3 .eth() @@ -149,10 +163,12 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { consuming_wallet: Wallet, fingerprints_recipient: Recipient, affordable_accounts: Vec, - ) -> Box, Error = PayableTransactionError>> + ) -> Box, Error=PayableTransactionError>> { let web3_batch = self.web3_batch.clone(); let get_transaction_id = self.get_transaction_id(consuming_wallet.address()); + // We are not relying on Database and fetching the values straight from the blockchain. + // Modify according to the Payment adjusters new design let get_gas_price = self.get_gas_price(); Box::new( @@ -201,6 +217,7 @@ mod tests { use std::str::FromStr; use ethereum_types::{H256, U64}; use futures::Future; + use trust_dns_proto::rr::DNSClass::NONE; use web3::types::{BlockNumber, Bytes, FilterBuilder, H2048, Log, TransactionReceipt, U256}; use masq_lib::test_utils::mock_blockchain_client_server::MBCSBuilder; use crate::blockchain::blockchain_interface::blockchain_interface_web3::TRANSACTION_LITERAL; @@ -227,8 +244,7 @@ mod tests { } #[test] - fn get_transaction_fee_balance_returns_an_error_for_unintelligible_response_to_requesting_eth_balance( - ) { + fn get_transaction_fee_balance_returns_an_error_for_unintelligible_response_to_requesting_eth_balance() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0xFFFQ".to_string(), 0) @@ -432,23 +448,36 @@ mod tests { let tx_hash_4 = H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0b") .unwrap(); - let tx_hash_vec = vec![tx_hash_1, tx_hash_2, tx_hash_3, tx_hash_4]; + let tx_hash_5 = + H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0c") + .unwrap(); + + let tx_hash_6 = + H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0d") + .unwrap(); + let tx_hash_vec = vec![tx_hash_1, tx_hash_2, tx_hash_3, tx_hash_4, tx_hash_5, tx_hash_6]; let block_hash = H256::from_str("6d0abccae617442c26104c2bc63d1bc05e1e002e555aec4ab62a46e826b18f18") .unwrap(); let block_number = U64::from_str("b0328d").unwrap(); let cumulative_gas_used = U256::from_str("60ef").unwrap(); let gas_used = U256::from_str("60ef").unwrap(); - let status = U64::from(0); - let logs_bloom = H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000").unwrap(); - let tx_receipt_response = ReceiptResponseBuilder::default() - .transaction_hash(tx_hash_1) + let status = U64::from(1); + let status_failed = U64::from(0); + let tx_receipt_response_not_present = ReceiptResponseBuilder::default() + .transaction_hash(tx_hash_4) + .build(); + let tx_receipt_response_failed = ReceiptResponseBuilder::default() + .transaction_hash(tx_hash_5) + .status(status_failed) + .build(); + let tx_receipt_response_success = ReceiptResponseBuilder::default() + .transaction_hash(tx_hash_6) .block_hash(block_hash) .block_number(block_number) .cumulative_gas_used(cumulative_gas_used) .gas_used(gas_used) .status(status) - .logs_bloom(logs_bloom) .build(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() @@ -459,8 +488,10 @@ mod tests { 7, ) .raw_response(r#"{ "jsonrpc": "2.0", "id": 1, "result": null }"#.to_string()) - .raw_response(tx_receipt_response) .response("trash".to_string(), 0) + .raw_response(tx_receipt_response_not_present) + .raw_response(tx_receipt_response_failed) + .raw_response(tx_receipt_response_success) .end_batch() .start(); let subject = make_blockchain_interface_web3(Some(port)); @@ -475,8 +506,31 @@ mod tests { assert_eq!(result[1], TransactionReceiptResult::NotPresent); assert_eq!( result[2], + TransactionReceiptResult::Error( + "invalid type: string \"trash\", expected struct Receipt".to_string() + ) + ); + assert_eq!(result[3], TransactionReceiptResult::NotPresent); + assert_eq!( + result[4], + TransactionReceiptResult::TransactionFailed(TransactionReceipt { + transaction_hash: tx_hash_5, + transaction_index: Default::default(), + block_hash: None, + block_number: None, + cumulative_gas_used: U256::from(0), + gas_used: None, + contract_address: None, + logs: vec![], + status: Some(status_failed), + root: None, + logs_bloom: H2048::default() + }) + ); + assert_eq!( + result[5], TransactionReceiptResult::Found(TransactionReceipt { - transaction_hash: tx_hash_1, + transaction_hash: tx_hash_6, transaction_index: Default::default(), block_hash: Some(block_hash), block_number: Some(block_number), @@ -486,15 +540,9 @@ mod tests { logs: vec![], status: Some(status), root: None, - logs_bloom + logs_bloom: H2048::default() }) ); - assert_eq!( - result[3], - TransactionReceiptResult::Error( - "invalid type: string \"trash\", expected struct Receipt".to_string() - ) - ); } #[test] @@ -590,7 +638,7 @@ mod tests { topics: vec![H256::from_str( "241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80" ) - .unwrap()], + .unwrap()], data: Bytes(vec![ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 51, 16, 114, 0, 88, 197, 31, 13, 228, 86, 226, 115, 198, 38, 205, 211 @@ -599,14 +647,14 @@ mod tests { H256::from_str( "7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70" ) - .unwrap() + .unwrap() ), block_number: Some(U64::from(6040059)), transaction_hash: Some( H256::from_str( "3dc91b98249fa9f2c5c37486a2427a3a7825be240c1c84961dfb3063d9c04d50" ) - .unwrap() + .unwrap() ), transaction_index: Some(U64::from(29)), log_index: Some(U256::from(29)), diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 04e2a0ff4..0f52b95ec 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -83,12 +83,12 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { start_block: BlockNumber, fallback_start_block_number: u64, recipient: Address, - ) -> Box> { + ) -> Box> { let lower_level_interface = self.lower_interface(); let logger = self.logger.clone(); let contract_address = lower_level_interface.get_contract().address(); let num_chain_id = self.chain.rec().num_chain_id; - return Box::new( + Box::new( lower_level_interface.get_block_number().then(move |response_block_number_result| { let response_block_number = match response_block_number_result { Ok(block_number) => { @@ -134,16 +134,16 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { }, ) }) - }, + }, ) - ); + ) } fn build_blockchain_agent( &self, // TODO: Change wallet to address in the future consuming_wallet: Wallet, - ) -> Box, Error = BlockchainAgentBuildError>> { + ) -> Box, Error=BlockchainAgentBuildError>> { let wallet_address = consuming_wallet.address(); let gas_limit_const_part = self.gas_limit_const_part; // TODO: Would it be better to wrap these 4 calls into a single batch call? @@ -300,7 +300,7 @@ impl BlockchainInterfaceWeb3 { ); Ok(RetrievedBlockchainTransactions { - new_start_block: 1u64 + transaction_max_block_number, + new_start_block: transaction_max_block_number, transactions, }) } @@ -448,7 +448,7 @@ mod tests { assert_eq!( result, RetrievedBlockchainTransactions { - new_start_block: 0x4be664, + new_start_block: 0x4be663, transactions: vec![ BlockchainTransaction { block_number: 0x4be663, @@ -508,7 +508,7 @@ mod tests { assert_eq!( result, Ok(RetrievedBlockchainTransactions { - new_start_block: 1543664, + new_start_block: 1543663, transactions: vec![] }) ); @@ -541,8 +541,7 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned( - ) { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -567,8 +566,7 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned( - ) { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -590,8 +588,7 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number( - ) { + fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x400", 1) @@ -602,7 +599,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let end_block_nbr = 1024u64; let subject = @@ -621,7 +618,7 @@ mod tests { assert_eq!( result, Ok(RetrievedBlockchainTransactions { - new_start_block: 1 + end_block_nbr, + new_start_block: end_block_nbr, transactions: vec![] }) ); @@ -631,11 +628,8 @@ mod tests { ); } - // TODO: GH-744: HIGH - We are adding 1 to the fallback start block number twice. why? - // https://github.com/MASQ-Project/Node/pull/456#discussion_r1803865133 #[test] - fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one( - ) { + fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("trash", 1) @@ -660,7 +654,7 @@ mod tests { assert_eq!( result, Ok(RetrievedBlockchainTransactions { - new_start_block: 1 + expected_fallback_start_block, + new_start_block: expected_fallback_start_block, transactions: vec![] }) ); @@ -710,7 +704,7 @@ mod tests { ); let expected_fee_estimation = (3 * (BlockchainInterfaceWeb3::web3_gas_limit_const_part(chain) - + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) + + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) * expected_gas_price_wei) as u128; assert_eq!( result.estimated_transaction_fee_total(3), @@ -933,9 +927,9 @@ mod tests { .zip(0usize..2) .fold(String::new(), |so_far, actual| [ so_far, - compose(actual.0 .0, actual.0 .1) + compose(actual.0.0, actual.0.1) ] - .join(if actual.1 == 0 { "" } else { ", " })) + .join(if actual.1 == 0 { "" } else { ", " })) ); let txs: Vec<(TestRawTransaction, Signing)> = serde_json::from_str(&all_transactions).unwrap(); @@ -969,8 +963,8 @@ mod tests { Bip32EncryptionKeyProvider::from_raw_secret(&signed.private_key.0.as_ref()) .unwrap(), ) - .prepare_secp256k1_secret() - .unwrap(); + .prepare_secp256k1_secret() + .unwrap(); let tx_params = from_raw_transaction_to_transaction_parameters(tx, chain); let web3 = Web3::new(subject.transport.clone()); let sign = web3 diff --git a/node/src/blockchain/blockchain_interface/mod.rs b/node/src/blockchain/blockchain_interface/mod.rs index 2c47a450f..eafba9e9f 100644 --- a/node/src/blockchain/blockchain_interface/mod.rs +++ b/node/src/blockchain/blockchain_interface/mod.rs @@ -3,7 +3,6 @@ pub mod blockchain_interface_web3; pub mod data_structures; pub mod lower_level_interface; -pub mod test_utils; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; use crate::blockchain::blockchain_interface::data_structures::errors::{ @@ -31,12 +30,12 @@ pub trait BlockchainInterface { start_block: BlockNumber, fallback_start_block_number: u64, recipient: Address, - ) -> Box>; + ) -> Box>; fn build_blockchain_agent( &self, consuming_wallet: Wallet, - ) -> Box, Error = BlockchainAgentBuildError>>; + ) -> Box, Error=BlockchainAgentBuildError>>; as_any_ref_in_trait!(); } diff --git a/node/src/blockchain/blockchain_interface/test_utils.rs b/node/src/blockchain/blockchain_interface/test_utils.rs deleted file mode 100644 index 936b29070..000000000 --- a/node/src/blockchain/blockchain_interface/test_utils.rs +++ /dev/null @@ -1,133 +0,0 @@ -// // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -// -// #![cfg(test)] -// use crate::blockchain::blockchain_interface::lower_level_interface::{ -// LowBlockchainInt, -// }; -// use crate::sub_lib::wallet::Wallet; -// use std::cell::RefCell; -// use std::sync::{Arc, Mutex}; -// use actix::Recipient; -// use ethereum_types::{H256, U256, U64}; -// use futures::Future; -// use web3::contract::Contract; -// use web3::transports::Http; -// use web3::types::{Address, Filter, Log}; -// use masq_lib::blockchains::chains::Chain; -// use masq_lib::logger::Logger; -// use crate::accountant::db_access_objects::payable_dao::PayableAccount; -// use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; -// use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; -// use crate::blockchain::blockchain_interface::data_structures::errors::{BlockchainError, PayableTransactionError}; -// use crate::blockchain::blockchain_interface::data_structures::ProcessedPayableFallible; -// -// #[derive(Default)] -// pub struct LowBlockchainIntMock { -// get_transaction_fee_balance_params: Arc>>, -// get_transaction_fee_balance_results: RefCell>>, -// get_masq_balance_params: Arc>>, -// get_masq_balance_results: RefCell>>, -// get_block_number_results: RefCell>>, -// get_transaction_id_params: Arc>>, -// get_transaction_id_results: RefCell>>, -// } -// -// impl LowBlockchainInt for LowBlockchainIntMock { -// fn get_transaction_fee_balance( -// &self, -// _address: Address, -// ) -> Box> { -// unimplemented!("not needed so far") -// } -// -// fn get_service_fee_balance( -// &self, -// _address: Address, -// ) -> Box> { -// unimplemented!("not needed so far") -// } -// -// fn get_gas_price(&self) -> Box> { -// unimplemented!("not needed so far") -// } -// -// fn get_block_number(&self) -> Box> { -// unimplemented!("not needed so far") -// } -// -// fn get_transaction_id( -// &self, -// _address: Address, -// ) -> Box> { -// unimplemented!("not needed so far") -// } -// -// fn get_transaction_receipt_in_batch( -// &self, -// _hash_vec: Vec, -// ) -> Box, Error = BlockchainError>> { -// unimplemented!("not needed so far") -// } -// -// fn get_contract(&self) -> Contract { -// unimplemented!("not needed so far") -// } -// -// fn get_transaction_logs( -// &self, -// _filter: Filter, -// ) -> Box, Error = BlockchainError>> { -// unimplemented!("not needed so far") -// } -// -// fn submit_payables_in_batch( -// &self, -// _logger: Logger, -// _chain: Chain, -// _consuming_wallet: Wallet, -// _fingerprints_recipient: Recipient, -// _affordable_accounts: Vec, -// ) -> Box, Error = PayableTransactionError>> -// { -// unimplemented!("not needed so far") -// } -// } -// -// impl LowBlockchainIntMock { -// pub fn get_transaction_fee_balance_params(mut self, params: &Arc>>) -> Self { -// self.get_transaction_fee_balance_params = params.clone(); -// self -// } -// -// pub fn get_transaction_fee_balance_result(self, result: Result) -> Self { -// self.get_transaction_fee_balance_results -// .borrow_mut() -// .push(result); -// self -// } -// -// pub fn get_masq_balance_params(mut self, params: &Arc>>) -> Self { -// self.get_masq_balance_params = params.clone(); -// self -// } -// -// pub fn get_masq_balance_result(self, result: Result) -> Self { -// self.get_masq_balance_results.borrow_mut().push(result); -// self -// } -// -// pub fn get_block_number_result(self, result: Result) -> Self { -// self.get_block_number_results.borrow_mut().push(result); -// self -// } -// -// pub fn get_transaction_id_params(mut self, params: &Arc>>) -> Self { -// self.get_transaction_id_params = params.clone(); -// self -// } -// -// pub fn get_transaction_id_result(self, result: Result) -> Self { -// self.get_transaction_id_results.borrow_mut().push(result); -// self -// } -// } From 0caf9450adc613a6c603dc958421cc3f6e07d88c Mon Sep 17 00:00:00 2001 From: MASQrauder <60554948+masqrauder@users.noreply.github.com> Date: Tue, 5 Nov 2024 19:42:03 -0500 Subject: [PATCH 17/56] GH-606: Initialize start_block to none to use latest block (#374) * GH-606: Initialize start_block to none to use latest block * GH-606: Apply PR feedback changes * GH-606: Apply PR feedback changes * GH-606: Apply PR feedback changes * GH-606: Apply PR review 4 feedback changes * GH-606: Squashing commits - Save start_block_nbr if no msg but send as non-Option - Always commit - Reduce logging levels and simplify - Follow the Option naming pattern * GH-600: set_start_block only called in accountant/scanners/mod.rs * GH-606: PR Feedback - parameterize a test * GH-606: Address PR feedback * GH-606: Implement parameterized test without crate macro --- masq/src/commands/configuration_command.rs | 13 +- .../src/commands/set_configuration_command.rs | 41 ++- masq_lib/src/messages.rs | 2 +- .../docker/blockchain/Dockerfile | 4 +- .../docker/blockchain/entrypoint.sh | 7 +- multinode_integration_tests/src/main.rs | 16 +- .../src/mock_blockchain_client_server.rs | 14 +- .../tests/verify_bill_payment.rs | 13 +- node/src/accountant/mod.rs | 13 +- node/src/accountant/scanners/mod.rs | 42 +-- node/src/blockchain/blockchain_bridge.rs | 251 +++++++++++++++--- .../blockchain_interface_web3/mod.rs | 71 +++-- .../data_structures/mod.rs | 6 +- node/src/database/config_dumper.rs | 30 +-- node/src/database/db_initializer.rs | 18 +- node/src/db_config/config_dao.rs | 11 +- .../src/db_config/persistent_configuration.rs | 83 +++--- node/src/node_configurator/configurator.rs | 87 ++++-- node/src/test_utils/database_utils.rs | 2 +- .../persistent_configuration_mock.rs | 18 +- 20 files changed, 524 insertions(+), 218 deletions(-) diff --git a/masq/src/commands/configuration_command.rs b/masq/src/commands/configuration_command.rs index f9e72d5d4..62d2b4650 100644 --- a/masq/src/commands/configuration_command.rs +++ b/masq/src/commands/configuration_command.rs @@ -131,7 +131,10 @@ impl ConfigurationCommand { dump_parameter_line( stream, "Start block:", - &configuration.start_block.to_string(), + &configuration + .start_block_opt + .map(|m| m.separate_with_commas()) + .unwrap_or_else(|| "[Latest]".to_string()), ); Self::dump_value_list(stream, "Past neighbors:", &configuration.past_neighbors); let payment_thresholds = Self::preprocess_combined_parameters({ @@ -333,7 +336,7 @@ mod tests { exit_byte_rate: 129000000, exit_service_rate: 160000000, }, - start_block: 3456, + start_block_opt: None, scan_intervals: UiScanIntervals { pending_payable_sec: 150500, payable_sec: 155000, @@ -378,7 +381,7 @@ mod tests { |Max block count: [Unlimited]\n\ |Neighborhood mode: standard\n\ |Port mapping protocol: PCP\n\ -|Start block: 3456\n\ +|Start block: [Latest]\n\ |Past neighbors: neighbor 1\n\ | neighbor 2\n\ |Payment thresholds: \n\ @@ -433,7 +436,7 @@ mod tests { exit_byte_rate: 20, exit_service_rate: 30, }, - start_block: 3456, + start_block_opt: Some(1234567890u64), scan_intervals: UiScanIntervals { pending_payable_sec: 1000, payable_sec: 1000, @@ -476,7 +479,7 @@ mod tests { |Max block count: 100,000\n\ |Neighborhood mode: zero-hop\n\ |Port mapping protocol: PCP\n\ -|Start block: 3456\n\ +|Start block: 1,234,567,890\n\ |Past neighbors: [?]\n\ |Payment thresholds: \n\ | Debt threshold: 2,500 gwei\n\ diff --git a/masq/src/commands/set_configuration_command.rs b/masq/src/commands/set_configuration_command.rs index 99d979f07..6f822f1f3 100644 --- a/masq/src/commands/set_configuration_command.rs +++ b/masq/src/commands/set_configuration_command.rs @@ -7,6 +7,7 @@ use masq_lib::shared_schema::gas_price_arg; use masq_lib::shared_schema::min_hops_arg; use masq_lib::short_writeln; use masq_lib::utils::ExpectValue; +use std::num::IntErrorKind; #[derive(Debug, PartialEq, Eq)] pub struct SetConfigurationCommand { @@ -35,9 +36,17 @@ impl SetConfigurationCommand { } fn validate_start_block(start_block: String) -> Result<(), String> { - match start_block.parse::() { - Ok(_) => Ok(()), - _ => Err(start_block), + if "latest".eq_ignore_ascii_case(&start_block) || "none".eq_ignore_ascii_case(&start_block) { + Ok(()) + } else { + match start_block.parse::() { + Ok(_) => Ok(()), + Err(e) if e.kind() == &IntErrorKind::PosOverflow => Err( + format!("Unable to parse '{}' into a starting block number or provide 'none' or 'latest' for the latest block number: digits exceed {}.", + start_block, u64::MAX), + ), + Err(e) => Err(format!("Unable to parse '{}' into a starting block number or provide 'none' or 'latest' for the latest block number: {}.", start_block, e)) + } } } @@ -59,7 +68,7 @@ impl Command for SetConfigurationCommand { const SET_CONFIGURATION_ABOUT: &str = "Sets Node configuration parameters being enabled for this operation when the Node is running."; const START_BLOCK_HELP: &str = - "Ordinal number of the Ethereum block where scanning for transactions will start."; + "Ordinal number of the Ethereum block where scanning for transactions will start. Use 'latest' or 'none' for Latest block."; pub fn set_configurationify<'a>(shared_schema_arg: Arg<'a, 'a>) -> Arg<'a, 'a> { shared_schema_arg.takes_value(true).min_values(1) @@ -103,7 +112,7 @@ mod tests { ); assert_eq!( START_BLOCK_HELP, - "Ordinal number of the Ethereum block where scanning for transactions will start." + "Ordinal number of the Ethereum block where scanning for transactions will start. Use 'latest' or 'none' for Latest block." ); } @@ -122,10 +131,28 @@ mod tests { assert!(result.contains("cannot be used with one or more of the other specified arguments")); } + #[test] + fn validate_start_block_catches_invalid_values() { + assert_eq!(validate_start_block("abc".to_string()), Err("Unable to parse 'abc' into a starting block number or provide 'none' or 'latest' for the latest block number: invalid digit found in string.".to_string())); + assert_eq!(validate_start_block("918446744073709551615".to_string()), Err("Unable to parse '918446744073709551615' into a starting block number or provide 'none' or 'latest' for the latest block number: digits exceed 18446744073709551615.".to_string())); + assert_eq!(validate_start_block("123,456,789".to_string()), Err("Unable to parse '123,456,789' into a starting block number or provide 'none' or 'latest' for the latest block number: invalid digit found in string.".to_string())); + assert_eq!(validate_start_block("123'456'789".to_string()), Err("Unable to parse '123'456'789' into a starting block number or provide 'none' or 'latest' for the latest block number: invalid digit found in string.".to_string())); + } #[test] fn validate_start_block_works() { - assert!(validate_start_block("abc".to_string()).is_err()); - assert!(validate_start_block("1566".to_string()).is_ok()); + assert_eq!( + validate_start_block("18446744073709551615".to_string()), + Ok(()) + ); + assert_eq!(validate_start_block("1566".to_string()), Ok(())); + assert_eq!(validate_start_block("none".to_string()), Ok(())); + assert_eq!(validate_start_block("None".to_string()), Ok(())); + assert_eq!(validate_start_block("NONE".to_string()), Ok(())); + assert_eq!(validate_start_block("nOnE".to_string()), Ok(())); + assert_eq!(validate_start_block("latest".to_string()), Ok(())); + assert_eq!(validate_start_block("LATEST".to_string()), Ok(())); + assert_eq!(validate_start_block("LaTeST".to_string()), Ok(())); + assert_eq!(validate_start_block("lATEst".to_string()), Ok(())); } #[test] diff --git a/masq_lib/src/messages.rs b/masq_lib/src/messages.rs index 59522171e..45842e419 100644 --- a/masq_lib/src/messages.rs +++ b/masq_lib/src/messages.rs @@ -492,7 +492,7 @@ pub struct UiConfigurationResponse { #[serde(rename = "portMappingProtocol")] pub port_mapping_protocol_opt: Option, #[serde(rename = "startBlock")] - pub start_block: u64, + pub start_block_opt: Option, #[serde(rename = "consumingWalletPrivateKeyOpt")] pub consuming_wallet_private_key_opt: Option, // This item is calculated from the private key, not stored in the database, so that diff --git a/multinode_integration_tests/docker/blockchain/Dockerfile b/multinode_integration_tests/docker/blockchain/Dockerfile index 027eb7a27..7ff65ea16 100644 --- a/multinode_integration_tests/docker/blockchain/Dockerfile +++ b/multinode_integration_tests/docker/blockchain/Dockerfile @@ -1,8 +1,8 @@ # Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -FROM trufflesuite/ganache-cli:v6.7.0 +FROM trufflesuite/ganache-cli:v6.12.2 ADD ./entrypoint.sh /app/ EXPOSE 18545 -ENTRYPOINT /app/entrypoint.sh +ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/multinode_integration_tests/docker/blockchain/entrypoint.sh b/multinode_integration_tests/docker/blockchain/entrypoint.sh index f9d6cc220..c184cbb50 100755 --- a/multinode_integration_tests/docker/blockchain/entrypoint.sh +++ b/multinode_integration_tests/docker/blockchain/entrypoint.sh @@ -1,3 +1,8 @@ #!/bin/sh -node /app/ganache-core.docker.cli.js -p 18545 --networkId 2 --verbose --mnemonic "timber cage wide hawk phone shaft pattern movie army dizzy hen tackle lamp absent write kind term toddler sphere ripple idle dragon curious hold" +node /app/ganache-core.docker.cli.js \ + -h 0.0.0.0 \ + -p 18545 \ + --networkId 2 \ + --verbose \ + --mnemonic "timber cage wide hawk phone shaft pattern movie army dizzy hen tackle lamp absent write kind term toddler sphere ripple idle dragon curious hold" diff --git a/multinode_integration_tests/src/main.rs b/multinode_integration_tests/src/main.rs index d78421672..8f705fed9 100644 --- a/multinode_integration_tests/src/main.rs +++ b/multinode_integration_tests/src/main.rs @@ -1,11 +1,10 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -use self::sub_lib::utils::indicates_dead_stream; use masq_lib::command::{Command, StdStreams}; use masq_lib::constants::{HIGHEST_USABLE_PORT, LOWEST_USABLE_INSECURE_PORT}; -use node_lib::sub_lib; use node_lib::sub_lib::framer::Framer; use node_lib::sub_lib::node_addr::NodeAddr; +use node_lib::sub_lib::utils::indicates_dead_stream; use node_lib::test_utils::data_hunk::DataHunk; use node_lib::test_utils::data_hunk_framer::DataHunkFramer; use std::borrow::BorrowMut; @@ -14,10 +13,9 @@ use std::env; use std::io; use std::io::Read; use std::io::Write; -use std::net::Shutdown; -use std::net::SocketAddr; use std::net::TcpListener; use std::net::TcpStream; +use std::net::{Shutdown, SocketAddr}; use std::process; use std::str::FromStr; use std::sync::{Arc, Mutex, MutexGuard}; @@ -223,10 +221,10 @@ impl MockNode { } fn usage(stderr: &mut dyn Write) -> u8 { - writeln! (stderr, "Usage: MockNode ://... where is the address MockNode is running on and is between {} and {}", - LOWEST_USABLE_INSECURE_PORT, - HIGHEST_USABLE_PORT, - ).unwrap (); + writeln!(stderr, "Usage: MockNode ://... where is the address MockNode is running on and is between {} and {}", + LOWEST_USABLE_INSECURE_PORT, + HIGHEST_USABLE_PORT, + ).unwrap(); 1 } @@ -369,7 +367,7 @@ mod tests { assert_eq!(result, 1); let stderr = holder.stderr; - assert_eq! (stderr.get_string (), String::from ("Usage: MockNode ://... where is the address MockNode is running on and is between 1025 and 65535\n\n")); + assert_eq!(stderr.get_string(), String::from("Usage: MockNode ://... where is the address MockNode is running on and is between 1025 and 65535\n\n")); } #[test] diff --git a/multinode_integration_tests/src/mock_blockchain_client_server.rs b/multinode_integration_tests/src/mock_blockchain_client_server.rs index 24031b2cc..a40543808 100644 --- a/multinode_integration_tests/src/mock_blockchain_client_server.rs +++ b/multinode_integration_tests/src/mock_blockchain_client_server.rs @@ -241,8 +241,10 @@ impl MockBlockchainClientServer { let mut requests = requests_arc.lock().unwrap(); requests.push(body); } - let response = responses.remove(0); - Self::send_body(conn_state, response); + if !responses.is_empty() { + let response = responses.remove(0); + Self::send_body(conn_state, response); + } let _ = notifier_tx.send(()); // receiver doesn't exist if test didn't set it up } None => (), @@ -437,7 +439,7 @@ mod tests { .response("Thank you and good night", 40) .start(); let mut client = connect(port); - client.write (b"POST /biddle HTTP/1.1\r\nContent-Length: 5\r\n\r\nfirstPOST /biddle HTTP/1.1\r\nContent-Length: 6\r\n\r\nsecond").unwrap(); + client.write(b"POST /biddle HTTP/1.1\r\nContent-Length: 5\r\n\r\nfirstPOST /biddle HTTP/1.1\r\nContent-Length: 6\r\n\r\nsecond").unwrap(); let (_, body) = receive_response(&mut client); assert_eq!( @@ -567,7 +569,7 @@ mod tests { assert_eq!(notified.try_recv().is_err(), true); let requests = subject.requests(); - assert_eq! (requests, vec! [ + assert_eq!(requests, vec![ "POST /biddle HTTP/1.1\r\nContent-Type: application-json\r\nContent-Length: 82\r\n\r\n{\"jsonrpc\": \"2.0\", \"method\": \"first\", \"params\": [\"biddle\", \"de\", \"bee\"], \"id\": 40}".to_string(), "POST /biddle HTTP/1.1\r\nContent-Type: application-json\r\nContent-Length: 48\r\n\r\n{\"jsonrpc\": \"2.0\", \"method\": \"second\", \"id\": 42}".to_string(), "POST /biddle HTTP/1.1\r\nContent-Type: application-json\r\nContent-Length: 47\r\n\r\n{\"jsonrpc\": \"2.0\", \"method\": \"third\", \"id\": 42}".to_string(), @@ -600,7 +602,7 @@ mod tests { r#"{"jsonrpc": "2.0", "result": {"name":"Billy","age":15}, "id": 42}"# ); let requests = subject.requests(); - assert_eq! (requests, vec! [ + assert_eq!(requests, vec![ "POST / HTTP/1.1\r\ncontent-type: application/json\r\nuser-agent: web3.rs\r\nhost: 172.18.0.1:32768\r\ncontent-length: 308\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"eth_getLogs\",\"params\":[{\"address\":\"0x59882e4a8f5d24643d4dda422922a870f1b3e664\",\"fromBlock\":\"0x3e8\",\"toBlock\":\"latest\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",null,\"0x00000000000000000000000027d9a2ac83b493f88ce9b4532edcf74e95b9788d\"]}],\"id\":0}".to_string() ]) } @@ -704,6 +706,6 @@ mod tests { body.len(), body ) - .into_bytes() + .into_bytes() } } diff --git a/multinode_integration_tests/tests/verify_bill_payment.rs b/multinode_integration_tests/tests/verify_bill_payment.rs index 5e9b50347..1240deb58 100644 --- a/multinode_integration_tests/tests/verify_bill_payment.rs +++ b/multinode_integration_tests/tests/verify_bill_payment.rs @@ -38,10 +38,7 @@ use web3::Web3; #[test] fn verify_bill_payment() { - let mut cluster = match MASQNodeCluster::start() { - Ok(cluster) => cluster, - Err(e) => panic!("{}", e), - }; + let mut cluster = MASQNodeCluster::start().unwrap(); let blockchain_server = BlockchainServer { name: "ganache-cli", }; @@ -64,7 +61,7 @@ fn verify_bill_payment() { assert_balances( &contract_owner_wallet, &blockchain_interface, - "99998043204000000000", + "99998381140000000000", "472000000000000000000000000", ); let payment_thresholds = PaymentThresholds { @@ -189,7 +186,7 @@ fn verify_bill_payment() { assert_balances( &contract_owner_wallet, &blockchain_interface, - "99998043204000000000", + "99998381140000000000", "472000000000000000000000000", ); @@ -235,7 +232,7 @@ fn verify_bill_payment() { assert_balances( &contract_owner_wallet, &blockchain_interface, - "99997886466000000000", + "99998223682000000000", "471999999700000000000000000", ); @@ -330,7 +327,7 @@ fn assert_balances( assert_eq!( format!("{}", eth_balance), String::from(expected_eth_balance), - "Actual EthBalance {} doesn't much with expected {}", + "Actual EthBalance {} doesn't match with expected {}", eth_balance, expected_eth_balance ); diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index cd7381622..e76b15a0d 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -1056,6 +1056,7 @@ mod tests { use crate::blockchain::test_utils::{make_tx_hash, BlockchainInterfaceMock}; use crate::database::rusqlite_wrappers::TransactionSafeWrapper; use crate::database::test_utils::transaction_wrapper_mock::TransactionInnerWrapperMockBuilder; + use crate::db_config::config_dao::ConfigDaoRecord; use crate::db_config::mocks::ConfigDaoMock; use crate::match_every_type_id; use crate::sub_lib::accountant::{ @@ -1373,7 +1374,11 @@ mod tests { config.suppress_initial_scans = true; let subject = AccountantBuilder::default() .bootstrapper_config(config) - .config_dao(ConfigDaoMock::new().set_result(Ok(()))) + .config_dao( + ConfigDaoMock::new() + .get_result(Ok(ConfigDaoRecord::new("start_block", None, false))) + .set_result(Ok(())), + ) .build(); let (ui_gateway, _, ui_gateway_recording_arc) = make_recorder(); let subject_addr = subject.start(); @@ -1991,6 +1996,7 @@ mod tests { ) { let more_money_received_params_arc = Arc::new(Mutex::new(vec![])); let commit_params_arc = Arc::new(Mutex::new(vec![])); + let get_params_arc = Arc::new(Mutex::new(vec![])); let set_by_guest_transaction_params_arc = Arc::new(Mutex::new(vec![])); let now = SystemTime::now(); let earning_wallet = make_wallet("earner3000"); @@ -2014,6 +2020,8 @@ mod tests { .more_money_received_params(&more_money_received_params_arc) .more_money_received_result(wrapped_transaction); let config_dao = ConfigDaoMock::new() + .get_params(&get_params_arc) + .get_result(Ok(ConfigDaoRecord::new("start_block", None, false))) .set_by_guest_transaction_params(&set_by_guest_transaction_params_arc) .set_by_guest_transaction_result(Ok(())); let accountant = AccountantBuilder::default() @@ -2028,7 +2036,7 @@ mod tests { .try_send(ReceivedPayments { timestamp: now, payments: vec![expected_receivable_1.clone(), expected_receivable_2.clone()], - new_start_block: 123456789, + new_start_block: 123456789u64, response_skeleton_opt: None, }) .expect("unexpected actix error"); @@ -4774,6 +4782,7 @@ mod tests { let factory = Accountant::dao_factory(data_dir); factory.make(); }; + assert_on_initialization_with_panic_on_migration(&data_dir, &act); } } diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index f8bc4b163..fc5f5ce91 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -862,7 +862,7 @@ impl Scanner for ReceivableScanner { match self .persistent_configuration - .set_start_block(msg.new_start_block) + .set_start_block(Some(msg.new_start_block)) { Ok(()) => debug!(logger, "Start block updated to {}", msg.new_start_block), Err(e) => panic!( @@ -914,7 +914,7 @@ impl ReceivableScanner { let new_start_block = msg.new_start_block; match self .persistent_configuration - .set_start_block_from_txn(new_start_block, &mut txn) + .set_start_block_from_txn(Some(new_start_block), &mut txn) { Ok(()) => (), Err(e) => panic!( @@ -1243,7 +1243,7 @@ mod tests { assert_eq!(receivable_scanner.common.initiated_at_opt.is_some(), false); receivable_scanner .persistent_configuration - .set_start_block(136890) + .set_start_block(Some(136890)) .unwrap(); let set_params = set_params_arc.lock().unwrap(); assert_eq!( @@ -1631,7 +1631,7 @@ mod tests { .iter() .map(|ppayable| ppayable.hash) .collect::>(); - // Not in an ascending order + // Not in ascending order let rowids_and_hashes_from_fingerprints = vec![(hash_1, 3), (hash_3, 5), (hash_2, 6)] .iter() .map(|(hash, _id)| *hash) @@ -1883,7 +1883,7 @@ mod tests { 00000000000000000000000000000000000000000315 failed due to RecordDeletion(\"Gosh, I overslept \ without an alarm set\")"); let log_handler = TestLogHandler::new(); - // There is a possible situation when we stumble over missing fingerprints and so we log it. + // There is a possible situation when we stumble over missing fingerprints, so we log it. // Here we don't and so any ERROR log shouldn't turn up log_handler.exists_no_log_containing(&format!("ERROR: {}", test_name)) } @@ -3070,6 +3070,7 @@ mod tests { let set_start_block_params_arc = Arc::new(Mutex::new(vec![])); let new_start_block = 4321; let persistent_config = PersistentConfigurationMock::new() + .start_block_result(Ok(None)) .set_start_block_params(&set_start_block_params_arc) .set_start_block_result(Ok(())); let mut subject = ReceivableScannerBuilder::new() @@ -3086,7 +3087,7 @@ mod tests { assert_eq!(message_opt, None); let set_start_block_params = set_start_block_params_arc.lock().unwrap(); - assert_eq!(*set_start_block_params, vec![4321]); + assert_eq!(*set_start_block_params, vec![Some(4321)]); TestLogHandler::new().exists_log_containing(&format!( "INFO: {test_name}: No newly received payments were detected during the scanning process." )); @@ -3099,16 +3100,21 @@ mod tests { init_test_logging(); let test_name = "no_transactions_received_but_start_block_setting_fails"; let now = SystemTime::now(); - let persistent_config = PersistentConfigurationMock::new().set_start_block_result(Err( - PersistentConfigError::UninterpretableValue("Illiterate database manager".to_string()), - )); + let set_start_block_params_arc = Arc::new(Mutex::new(vec![])); + let new_start_block = 6709u64; + let persistent_config = PersistentConfigurationMock::new() + .start_block_result(Ok(None)) + .set_start_block_params(&set_start_block_params_arc) + .set_start_block_result(Err(PersistentConfigError::UninterpretableValue( + "Illiterate database manager".to_string(), + ))); let mut subject = ReceivableScannerBuilder::new() .persistent_configuration(persistent_config) .build(); let msg = ReceivedPayments { timestamp: now, payments: vec![], - new_start_block: 6709, + new_start_block, response_skeleton_opt: None, }; // Not necessary, rather for preciseness @@ -3132,6 +3138,7 @@ mod tests { .set_arbitrary_id_stamp(transaction_id); let transaction = TransactionSafeWrapper::new_with_builder(txn_inner_builder); let persistent_config = PersistentConfigurationMock::new() + .start_block_result(Ok(None)) .set_start_block_from_txn_params(&set_start_block_from_txn_params_arc) .set_start_block_from_txn_result(Ok(())); let receivable_dao = ReceivableDaoMock::new() @@ -3178,7 +3185,7 @@ mod tests { let set_by_guest_transaction_params = set_start_block_from_txn_params_arc.lock().unwrap(); assert_eq!( *set_by_guest_transaction_params, - vec![(7890123, transaction_id)] + vec![(Some(7890123u64), transaction_id)] ); let commit_params = commit_params_arc.lock().unwrap(); assert_eq!(*commit_params, vec![()]); @@ -3196,9 +3203,11 @@ mod tests { let now = SystemTime::now(); let txn_inner_builder = TransactionInnerWrapperMockBuilder::default(); let transaction = TransactionSafeWrapper::new_with_builder(txn_inner_builder); - let persistent_config = PersistentConfigurationMock::new().set_start_block_from_txn_result( - Err(PersistentConfigError::DatabaseError("Fatigue".to_string())), - ); + let persistent_config = PersistentConfigurationMock::new() + .start_block_result(Ok(None)) + .set_start_block_from_txn_result(Err(PersistentConfigError::DatabaseError( + "Fatigue".to_string(), + ))); let receivable_dao = ReceivableDaoMock::new().more_money_received_result(transaction); let mut subject = ReceivableScannerBuilder::new() .receivable_dao(receivable_dao) @@ -3240,8 +3249,9 @@ mod tests { let txn_inner_builder = TransactionInnerWrapperMockBuilder::default().commit_result(commit_err); let transaction = TransactionSafeWrapper::new_with_builder(txn_inner_builder); - let persistent_config = - PersistentConfigurationMock::new().set_start_block_from_txn_result(Ok(())); + let persistent_config = PersistentConfigurationMock::new() + .start_block_result(Ok(None)) + .set_start_block_from_txn_result(Ok(())); let receivable_dao = ReceivableDaoMock::new().more_money_received_result(transaction); let mut subject = ReceivableScannerBuilder::new() .receivable_dao(receivable_dao) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 0bb34fbfd..eadfc40d3 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -281,67 +281,82 @@ impl BlockchainBridge { fn handle_retrieve_transactions(&mut self, msg: RetrieveTransactions) -> Result<(), String> { let start_block_nbr = match self.persistent_config.start_block() { - Ok (sb) => sb, - Err (e) => panic! ("Cannot retrieve start block from database; payments to you may not be processed: {:?}", e) + Ok(Some(sb)) => sb, + Ok(None) => u64::MAX, + Err(e) => panic!("Cannot retrieve start block from database; payments to you may not be processed: {:?}", e) }; let max_block_count = match self.persistent_config.max_block_count() { Ok(Some(mbc)) => mbc, _ => u64::MAX, }; + let use_unlimited_block_count_range = u64::MAX == max_block_count; + let use_latest_block = u64::MAX == start_block_nbr; let end_block = match self .blockchain_interface .lower_interface() .get_block_number() { Ok(eb) => { - if u64::MAX == max_block_count { + if use_unlimited_block_count_range || use_latest_block { BlockNumber::Number(eb) } else { BlockNumber::Number(eb.as_u64().min(start_block_nbr + max_block_count).into()) } } Err(e) => { - info!( - self.logger, - "Using 'latest' block number instead of a literal number. {:?}", e - ); - if max_block_count == u64::MAX { + if use_unlimited_block_count_range || use_latest_block { + debug!( + self.logger, + "Using 'latest' block number instead of a literal number. {:?}", e + ); BlockNumber::Latest } else { + debug!( + self.logger, + "Using '{}' ending block number. {:?}", + start_block_nbr + max_block_count, + e + ); BlockNumber::Number((start_block_nbr + max_block_count).into()) } } }; - let start_block = BlockNumber::Number(start_block_nbr.into()); + let start_block = if use_latest_block { + end_block + } else { + BlockNumber::Number(start_block_nbr.into()) + }; let retrieved_transactions = self.blockchain_interface .retrieve_transactions(start_block, end_block, &msg.recipient); match retrieved_transactions { Ok(transactions) => { - if transactions.transactions.is_empty() { - debug!(self.logger, "No new receivable detected"); + if let BlockNumber::Number(new_start_block_number) = transactions.new_start_block { + if transactions.transactions.is_empty() { + debug!(self.logger, "No new receivable detected"); + } + self.received_payments_subs_opt + .as_ref() + .expect("Accountant is unbound") + .try_send(ReceivedPayments { + timestamp: SystemTime::now(), + payments: transactions.transactions, + new_start_block: new_start_block_number.as_u64(), + response_skeleton_opt: msg.response_skeleton_opt, + }) + .expect("Accountant is dead."); } - self.received_payments_subs_opt - .as_ref() - .expect("Accountant is unbound") - .try_send(ReceivedPayments { - timestamp: SystemTime::now(), - payments: transactions.transactions, - new_start_block: transactions.new_start_block, - response_skeleton_opt: msg.response_skeleton_opt, - }) - .expect("Accountant is dead."); Ok(()) } Err(e) => { if let Some(max_block_count) = self.extract_max_block_count(e.clone()) { - debug!(self.logger, "Writing max_block_count({})", max_block_count); + debug!(self.logger, "Writing max_block_count({})", &max_block_count); self.persistent_config .set_max_block_count(Some(max_block_count)) .map_or_else( |_| { - warning!(self.logger, "{} update max_block_count to {}. Scheduling next scan with that limit.", e, max_block_count); - Err(format!("{} updated max_block_count to {}. Scheduling next scan with that limit.", e, max_block_count)) + warning!(self.logger, "{} update max_block_count to {}. Scheduling next scan with that limit.", e, &max_block_count); + Err(format!("{} updated max_block_count to {}. Scheduling next scan with that limit.", e, &max_block_count)) }, |e| { warning!(self.logger, "Writing max_block_count failed: {:?}", e); @@ -1005,7 +1020,7 @@ mod tests { .lower_interface_results(Box::new(lower_interface)); let persistent_config = PersistentConfigurationMock::new() .max_block_count_result(Ok(Some(100_000))) - .start_block_result(Ok(5)); // no set_start_block_result: set_start_block() must not be called + .start_block_result(Ok(Some(5))); // no set_start_block_result: set_start_block() must not be called let mut subject = BlockchainBridge::new( Box::new(blockchain_interface), Box::new(persistent_config), @@ -1273,7 +1288,7 @@ mod tests { let amount = 42; let amount2 = 55; let expected_transactions = RetrievedBlockchainTransactions { - new_start_block: 8675309u64, + new_start_block: BlockNumber::Number(8675309u64.into()), transactions: vec![ BlockchainTransaction { block_number: 7, @@ -1296,8 +1311,8 @@ mod tests { .retrieve_transactions_result(Ok(expected_transactions.clone())) .lower_interface_results(Box::new(lower_interface)); let persistent_config = PersistentConfigurationMock::new() - .max_block_count_result(Ok(Some(10000u64))) - .start_block_result(Ok(6)); + .max_block_count_result(Ok(None)) + .start_block_result(Ok(Some(6))); let subject = BlockchainBridge::new( Box::new(blockchain_interface_mock), Box::new(persistent_config), @@ -1326,7 +1341,7 @@ mod tests { *retrieve_transactions_params, vec![( BlockNumber::Number(6u64.into()), - BlockNumber::Number(10006u64.into()), + BlockNumber::Latest, earning_wallet )] ); @@ -1346,7 +1361,175 @@ mod tests { }), } ); - TestLogHandler::new().exists_log_containing("INFO: BlockchainBridge: Using 'latest' block number instead of a literal number. QueryFailed(\"Failed to read the latest block number\")"); + TestLogHandler::new().exists_log_containing("DEBUG: BlockchainBridge: Using 'latest' block number instead of a literal number. QueryFailed(\"Failed to read the latest block number\")"); + } + + #[test] + fn handle_retrieve_transactions_when_start_block_number_starts_undefined_in_a_brand_new_database( + ) { + let retrieve_transactions_params_arc = Arc::new(Mutex::new(vec![])); + let system = System::new( + "handle_retrieve_transactions_when_start_block_number_starts_undefined_in_a_brand_new_database", + ); + let (accountant, _, accountant_recording_arc) = make_recorder(); + let earning_wallet = make_wallet("somewallet"); + let amount = 42; + let amount2 = 55; + let expected_transactions = RetrievedBlockchainTransactions { + new_start_block: BlockNumber::Number(8675309u64.into()), + transactions: vec![ + BlockchainTransaction { + block_number: 8675308u64, + from: earning_wallet.clone(), + wei_amount: amount, + }, + BlockchainTransaction { + block_number: 8675309u64, + from: earning_wallet.clone(), + wei_amount: amount2, + }, + ], + }; + let lower_interface = LowBlockchainIntMock::default().get_block_number_result( + LatestBlockNumber::Err(BlockchainError::QueryFailed( + "\"Failed to read the latest block number\"".to_string(), + )), + ); + let blockchain_interface_mock = BlockchainInterfaceMock::default() + .retrieve_transactions_params(&retrieve_transactions_params_arc) + .retrieve_transactions_result(Ok(expected_transactions.clone())) + .lower_interface_results(Box::new(lower_interface)); + let persistent_config = PersistentConfigurationMock::new() + .max_block_count_result(Ok(None)) + .start_block_result(Ok(None)); + let subject = BlockchainBridge::new( + Box::new(blockchain_interface_mock), + Box::new(persistent_config), + false, + ); + let addr = subject.start(); + let subject_subs = BlockchainBridge::make_subs_from(&addr); + let peer_actors = peer_actors_builder().accountant(accountant).build(); + send_bind_message!(subject_subs, peer_actors); + let retrieve_transactions = RetrieveTransactions { + recipient: earning_wallet.clone(), + response_skeleton_opt: Some(ResponseSkeleton { + client_id: 1234, + context_id: 4321, + }), + }; + let before = SystemTime::now(); + + let _ = addr.try_send(retrieve_transactions).unwrap(); + + System::current().stop(); + system.run(); + let after = SystemTime::now(); + let retrieve_transactions_params = retrieve_transactions_params_arc.lock().unwrap(); + assert_eq!( + *retrieve_transactions_params, + vec![(BlockNumber::Latest, BlockNumber::Latest, earning_wallet)] + ); + let accountant_received_payment = accountant_recording_arc.lock().unwrap(); + assert_eq!(accountant_received_payment.len(), 1); + let received_payments = accountant_received_payment.get_record::(0); + check_timestamp(before, received_payments.timestamp, after); + assert_eq!( + received_payments, + &ReceivedPayments { + timestamp: received_payments.timestamp, + payments: expected_transactions.transactions, + new_start_block: 8675309u64, + response_skeleton_opt: Some(ResponseSkeleton { + client_id: 1234, + context_id: 4321 + }), + } + ); + } + + #[test] + fn handle_retrieve_transactions_with_latest_for_start_and_end_block_is_supported() { + let retrieve_transactions_params_arc = Arc::new(Mutex::new(vec![])); + let earning_wallet = make_wallet("somewallet"); + let amount = 42; + let amount2 = 55; + let expected_transactions = RetrievedBlockchainTransactions { + new_start_block: BlockNumber::Number(98765u64.into()), + transactions: vec![ + BlockchainTransaction { + block_number: 77, + from: earning_wallet.clone(), + wei_amount: amount, + }, + BlockchainTransaction { + block_number: 99, + from: earning_wallet.clone(), + wei_amount: amount2, + }, + ], + }; + + let system = System::new( + "handle_retrieve_transactions_with_latest_for_start_and_end_block_is_supported", + ); + let (accountant, _, accountant_recording_arc) = make_recorder(); + let persistent_config = PersistentConfigurationMock::new() + .max_block_count_result(Ok(None)) + .start_block_result(Ok(None)); + let latest_block_number = LatestBlockNumber::Err(BlockchainError::QueryFailed( + "Failed to read from block chain service".to_string(), + )); + let lower_interface = + LowBlockchainIntMock::default().get_block_number_result(latest_block_number); + let blockchain_interface = BlockchainInterfaceMock::default() + .retrieve_transactions_params(&retrieve_transactions_params_arc) + .retrieve_transactions_result(Ok(expected_transactions.clone())) + .lower_interface_results(Box::new(lower_interface)); + let subject = BlockchainBridge::new( + Box::new(blockchain_interface), + Box::new(persistent_config), + false, + ); + let addr = subject.start(); + let subject_subs = BlockchainBridge::make_subs_from(&addr); + let peer_actors = peer_actors_builder().accountant(accountant).build(); + send_bind_message!(subject_subs, peer_actors); + let retrieve_transactions = RetrieveTransactions { + recipient: earning_wallet.clone(), + response_skeleton_opt: Some(ResponseSkeleton { + client_id: 1234, + context_id: 4321, + }), + }; + let before = SystemTime::now(); + + let _ = addr.try_send(retrieve_transactions).unwrap(); + + System::current().stop(); + system.run(); + let after = SystemTime::now(); + let retrieve_transactions_params = retrieve_transactions_params_arc.lock().unwrap(); + assert_eq!( + *retrieve_transactions_params, + vec![(BlockNumber::Latest, BlockNumber::Latest, earning_wallet)] + ); + let accountant_received_payment = accountant_recording_arc.lock().unwrap(); + assert_eq!(accountant_received_payment.len(), 1); + let received_payments = accountant_received_payment.get_record::(0); + check_timestamp(before, received_payments.timestamp, after); + assert_eq!( + received_payments, + &ReceivedPayments { + timestamp: received_payments.timestamp, + payments: expected_transactions.transactions, + new_start_block: 98765, + response_skeleton_opt: Some(ResponseSkeleton { + client_id: 1234, + context_id: 4321 + }), + } + ); } #[test] @@ -1359,7 +1542,7 @@ mod tests { let amount = 42; let amount2 = 55; let expected_transactions = RetrievedBlockchainTransactions { - new_start_block: 9876, + new_start_block: BlockNumber::Number(9876.into()), transactions: vec![ BlockchainTransaction { block_number: 7, @@ -1382,7 +1565,7 @@ mod tests { .lower_interface_results(Box::new(lower_interface)); let persistent_config = PersistentConfigurationMock::new() .max_block_count_result(Ok(Some(10000u64))) - .start_block_result(Ok(6)); + .start_block_result(Ok(Some(6))); let subject = BlockchainBridge::new( Box::new(blockchain_interface_mock), Box::new(persistent_config), @@ -1440,13 +1623,13 @@ mod tests { LowBlockchainIntMock::default().get_block_number_result(Ok(0u64.into())); let blockchain_interface_mock = BlockchainInterfaceMock::default() .retrieve_transactions_result(Ok(RetrievedBlockchainTransactions { - new_start_block: 7, + new_start_block: BlockNumber::Number(7.into()), transactions: vec![], })) .lower_interface_results(Box::new(lower_interface)); let persistent_config = PersistentConfigurationMock::new() .max_block_count_result(Ok(Some(10000u64))) - .start_block_result(Ok(6)); + .start_block_result(Ok(Some(6))); let (accountant, _, accountant_recording_arc) = make_recorder(); let system = System::new( "processing_of_received_payments_continues_even_if_no_payments_are_detected", diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index b9bfa37bf..a4425a82f 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -119,12 +119,12 @@ where .build(); let fallback_start_block_number = match end_block { - BlockNumber::Number(eb) => eb.as_u64(), + BlockNumber::Number(eb) => Some(eb.as_u64()), _ => { if let BlockNumber::Number(start_block_number) = start_block { - start_block_number.as_u64() + 1u64 + Some(start_block_number.as_u64() + 1u64) } else { - panic!("start_block of Latest, Earliest, and Pending are not supported"); + None } } }; @@ -134,15 +134,15 @@ where let logger = self.logger.clone(); match self.web3_batch.transport().submit_batch().wait() { Ok(_) => { - let response_block_number = match block_request.wait() { + let response_block_number_opt = match block_request.wait() { Ok(block_nbr) => { debug!(logger, "Latest block number: {}", block_nbr.as_u64()); - block_nbr.as_u64() + Some(block_nbr.as_u64()) } Err(_) => { debug!( logger, - "Using fallback block number: {}", fallback_start_block_number + "Using fallback block number: {:?}", fallback_start_block_number ); fallback_start_block_number } @@ -178,16 +178,18 @@ where // was not successful. let transaction_max_block_number = self .find_largest_transaction_block_number( - response_block_number, + response_block_number_opt, &transactions, ); debug!( logger, - "Discovered transaction max block nbr: {}", + "Discovered transaction max block nbr: {:?}", transaction_max_block_number ); Ok(RetrievedBlockchainTransactions { - new_start_block: 1u64 + transaction_max_block_number, + new_start_block: transaction_max_block_number + .map(|nsb| BlockNumber::Number((1u64 + nsb).into())) + .unwrap_or(BlockNumber::Latest), transactions, }) } @@ -603,15 +605,18 @@ where fn find_largest_transaction_block_number( &self, - response_block_number: u64, + response_block_number: Option, transactions: &[BlockchainTransaction], - ) -> u64 { + ) -> Option { if transactions.is_empty() { response_block_number } else { transactions .iter() - .fold(response_block_number, |a, b| a.max(b.block_number)) + .fold(response_block_number.unwrap_or(0u64), |a, b| { + a.max(b.block_number) + }) + .into() } } } @@ -833,7 +838,7 @@ mod tests { assert_eq!( result, RetrievedBlockchainTransactions { - new_start_block: 0x4be664, + new_start_block: BlockNumber::Number(0x4be664.into()), transactions: vec![ BlockchainTransaction { block_number: 0x4be663, @@ -895,7 +900,7 @@ mod tests { assert_eq!( result, RetrievedBlockchainTransactions { - new_start_block: 1 + end_block_nbr, + new_start_block: BlockNumber::Number((1 + end_block_nbr).into()), transactions: vec![] } ); @@ -1004,7 +1009,7 @@ mod tests { assert_eq!( result, Ok(RetrievedBlockchainTransactions { - new_start_block: 1 + end_block_nbr, + new_start_block: BlockNumber::Number((1 + end_block_nbr).into()), transactions: vec![] }) ); @@ -1046,7 +1051,39 @@ mod tests { assert_eq!( result, Ok(RetrievedBlockchainTransactions { - new_start_block: 1 + expected_fallback_start_block, + new_start_block: BlockNumber::Number((1 + expected_fallback_start_block).into()), + transactions: vec![] + }) + ); + } + + #[test] + fn blockchain_interface_retrieve_transactions_start_and_end_blocks_can_be_latest() { + let port = find_free_port(); + let contains_error_causing_to_pick_fallback_value = br#"[{"jsonrpc":"2.0","id":1,"result":"error"},{"jsonrpc":"2.0","id":2,"result":[{"address":"0xcd6c588e005032dd882cd43bf53a32129be81302","blockHash":"0x1a24b9169cbaec3f6effa1f600b70c7ab9e8e86db44062b49132a4415d26732a","data":"0x0000000000000000000000000000000000000000000000000010000000000000","logIndex":"0x0","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000003f69f9efd4f2592fd70be8c32ecd9dce71c472fc","0x000000000000000000000000adc1853c7859369639eb414b6342b36288fe6092"],"transactionHash":"0x955cec6ac4f832911ab894ce16aa22c3003f46deff3f7165b32700d2f5ff0681","transactionIndex":"0x0"}]}]"#; + let _test_server = TestServer::start( + port, + vec![contains_error_causing_to_pick_fallback_value.to_vec()], + ); + let (event_loop_handle, transport) = Http::with_max_parallel( + &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), + REQUESTS_IN_PARALLEL, + ) + .unwrap(); + let chain = TEST_DEFAULT_CHAIN; + let subject = BlockchainInterfaceWeb3::new(transport, event_loop_handle, chain); + + let result = subject.retrieve_transactions( + BlockNumber::Latest, + BlockNumber::Latest, + &make_wallet("earning-wallet"), + ); + + let expected_new_start_block = BlockNumber::Latest; + assert_eq!( + result, + Ok(RetrievedBlockchainTransactions { + new_start_block: expected_new_start_block, transactions: vec![] }) ); @@ -1221,7 +1258,7 @@ mod tests { //exercising also the layer of web3 functions, but the transport layer is mocked init_test_logging(); let send_batch_params_arc = Arc::new(Mutex::new(vec![])); - //we compute the hashes ourselves during the batch preparation and so we don't care about + //we compute the hashes ourselves during the batch preparation, and so we don't care about //the same ones coming back with the response; we use the returned OKs as indicators of success only. //Any eventual rpc errors brought back are processed as well... let expected_batch_responses = vec![ diff --git a/node/src/blockchain/blockchain_interface/data_structures/mod.rs b/node/src/blockchain/blockchain_interface/data_structures/mod.rs index d1d785aae..d8b86d5d9 100644 --- a/node/src/blockchain/blockchain_interface/data_structures/mod.rs +++ b/node/src/blockchain/blockchain_interface/data_structures/mod.rs @@ -3,7 +3,7 @@ pub mod errors; use crate::accountant::db_access_objects::pending_payable_dao::PendingPayable; use crate::sub_lib::wallet::Wallet; -use web3::types::H256; +use web3::types::{BlockNumber, H256}; use web3::Error; #[derive(Clone, Debug, Eq, PartialEq)] @@ -13,9 +13,9 @@ pub struct BlockchainTransaction { pub wei_amount: u128, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq)] pub struct RetrievedBlockchainTransactions { - pub new_start_block: u64, + pub new_start_block: BlockNumber, pub transactions: Vec, } diff --git a/node/src/database/config_dumper.rs b/node/src/database/config_dumper.rs index 78f23ade7..17e24899e 100644 --- a/node/src/database/config_dumper.rs +++ b/node/src/database/config_dumper.rs @@ -353,11 +353,7 @@ mod tests { ); assert_value("neighborhoodMode", "zero-hop", &map); assert_value("schemaVersion", &CURRENT_SCHEMA_VERSION.to_string(), &map); - assert_value( - "startBlock", - &Chain::PolyMainnet.rec().contract_creation_block.to_string(), - &map, - ); + assert_null("startBlock", &map); assert_value( "exampleEncrypted", &dao.get("example_encrypted").unwrap().value_opt.unwrap(), @@ -503,11 +499,7 @@ mod tests { assert_value("pastNeighbors", "masq://polygon-mainnet:QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU@1.2.3.4:1234,masq://polygon-mainnet:QkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY@2.3.4.5:2345", &map); assert_value("neighborhoodMode", "consume-only", &map); assert_value("schemaVersion", &CURRENT_SCHEMA_VERSION.to_string(), &map); - assert_value( - "startBlock", - &Chain::PolyMainnet.rec().contract_creation_block.to_string(), - &map, - ); + assert_null("startBlock", &map); let expected_ee_entry = dao.get("example_encrypted").unwrap().value_opt.unwrap(); let expected_ee_decrypted = Bip39::decrypt_bytes(&expected_ee_entry, "password").unwrap(); let expected_ee_string = encode_bytes(Some(expected_ee_decrypted)).unwrap().unwrap(); @@ -620,11 +612,7 @@ mod tests { ); assert_value("neighborhoodMode", "standard", &map); assert_value("schemaVersion", &CURRENT_SCHEMA_VERSION.to_string(), &map); - assert_value( - "startBlock", - &Chain::PolyMainnet.rec().contract_creation_block.to_string(), - &map, - ); + assert_null("startBlock", &map); assert_value( "exampleEncrypted", &dao.get("example_encrypted").unwrap().value_opt.unwrap(), @@ -679,6 +667,18 @@ mod tests { assert_eq!(actual_value, expected_value); } + fn assert_null(key: &str, map: &Map) { + assert!(map.contains_key(key)); + let value = map + .get(key) + .unwrap_or_else(|| panic!("record for {} is missing", key)); + assert!( + value.is_null(), + "Expecting {} to be null, but it wasn't", + value + ) + } + fn assert_encrypted_value( key: &str, expected_value: &str, diff --git a/node/src/database/db_initializer.rs b/node/src/database/db_initializer.rs index 8bfb9c1eb..bcb9a3a0a 100644 --- a/node/src/database/db_initializer.rs +++ b/node/src/database/db_initializer.rs @@ -205,13 +205,7 @@ impl DbInitializerReal { Self::set_config_value( conn, "start_block", - Some( - &external_params - .chain - .rec() - .contract_creation_block - .to_string(), - ), + None, false, &format!( "{} start block", @@ -967,15 +961,7 @@ mod tests { Some(&CURRENT_SCHEMA_VERSION.to_string()), false, ); - verify( - &mut config_vec, - "start_block", - Some(&format!( - "{}", - &TEST_DEFAULT_CHAIN.rec().contract_creation_block.to_string() - )), - false, - ); + verify(&mut config_vec, "start_block", None, false); assert_eq!(config_vec, vec![]); } diff --git a/node/src/db_config/config_dao.rs b/node/src/db_config/config_dao.rs index 759440c42..36798dd05 100644 --- a/node/src/db_config/config_dao.rs +++ b/node/src/db_config/config_dao.rs @@ -180,7 +180,7 @@ mod tests { use crate::database::db_initializer::{DbInitializer, DbInitializerReal}; use crate::database::test_utils::ConnectionWrapperMock; use crate::test_utils::assert_contains; - use masq_lib::constants::{CURRENT_SCHEMA_VERSION, ETH_ROPSTEN_CONTRACT_CREATION_BLOCK}; + use masq_lib::constants::CURRENT_SCHEMA_VERSION; use masq_lib::test_utils::utils::ensure_node_home_directory_exists; use rusqlite::Connection; use std::path::Path; @@ -201,14 +201,7 @@ mod tests { false, ), ); - assert_contains( - &result, - &ConfigDaoRecord::new( - "start_block", - Some(Ð_ROPSTEN_CONTRACT_CREATION_BLOCK.to_string()), - false, - ), - ); + assert_contains(&result, &ConfigDaoRecord::new("start_block", None, false)); assert_contains( &result, &ConfigDaoRecord::new("consuming_wallet_private_key", None, true), diff --git a/node/src/db_config/persistent_configuration.rs b/node/src/db_config/persistent_configuration.rs index da3fa1583..532048a34 100644 --- a/node/src/db_config/persistent_configuration.rs +++ b/node/src/db_config/persistent_configuration.rs @@ -113,7 +113,7 @@ pub trait PersistentConfiguration { fn mapping_protocol(&self) -> Result, PersistentConfigError>; fn set_mapping_protocol( &mut self, - value: Option, + value_opt: Option, ) -> Result<(), PersistentConfigError>; fn min_hops(&self) -> Result; fn set_min_hops(&mut self, value: Hops) -> Result<(), PersistentConfigError>; @@ -131,13 +131,13 @@ pub trait PersistentConfiguration { node_descriptors_opt: Option>, db_password: &str, ) -> Result<(), PersistentConfigError>; - fn start_block(&self) -> Result; - fn set_start_block(&mut self, value: u64) -> Result<(), PersistentConfigError>; + fn start_block(&self) -> Result, PersistentConfigError>; + fn set_start_block(&mut self, value_opt: Option) -> Result<(), PersistentConfigError>; fn max_block_count(&self) -> Result, PersistentConfigError>; - fn set_max_block_count(&mut self, value: Option) -> Result<(), PersistentConfigError>; + fn set_max_block_count(&mut self, value_opt: Option) -> Result<(), PersistentConfigError>; fn set_start_block_from_txn( &mut self, - value: u64, + value_opt: Option, transaction: &mut TransactionSafeWrapper, ) -> Result<(), PersistentConfigError>; fn set_wallet_info( @@ -335,9 +335,9 @@ impl PersistentConfiguration for PersistentConfigurationReal { fn set_mapping_protocol( &mut self, - value: Option, + value_opt: Option, ) -> Result<(), PersistentConfigError> { - Ok(self.dao.set("mapping_protocol", value.map(to_string))?) + Ok(self.dao.set("mapping_protocol", value_opt.map(to_string))?) } fn min_hops(&self) -> Result { @@ -406,28 +406,28 @@ impl PersistentConfiguration for PersistentConfigurationReal { )?) } - fn start_block(&self) -> Result { - self.simple_get_method(decode_u64, "start_block") + fn start_block(&self) -> Result, PersistentConfigError> { + Ok(decode_u64(self.get("start_block")?)?) } - fn set_start_block(&mut self, value: u64) -> Result<(), PersistentConfigError> { - self.simple_set_method("start_block", value) + fn set_start_block(&mut self, value_opt: Option) -> Result<(), PersistentConfigError> { + Ok(self.dao.set("start_block", encode_u64(value_opt)?)?) } fn max_block_count(&self) -> Result, PersistentConfigError> { Ok(decode_u64(self.get("max_block_count")?)?) } - fn set_max_block_count(&mut self, value: Option) -> Result<(), PersistentConfigError> { - Ok(self.dao.set("max_block_count", encode_u64(value)?)?) + fn set_max_block_count(&mut self, value_opt: Option) -> Result<(), PersistentConfigError> { + Ok(self.dao.set("max_block_count", encode_u64(value_opt)?)?) } fn set_start_block_from_txn( &mut self, - value: u64, + value_opt: Option, transaction: &mut TransactionSafeWrapper, ) -> Result<(), PersistentConfigError> { - self.simple_set_method_from_provided_txn("start_block", value, transaction) + self.simple_set_method_from_provided_txn("start_block", value_opt, transaction) } fn set_wallet_info( @@ -568,23 +568,14 @@ impl PersistentConfigurationReal { fn simple_set_method_from_provided_txn( &mut self, parameter_name: &str, - value: T, + value_opt: Option, txn: &mut TransactionSafeWrapper, ) -> Result<(), PersistentConfigError> { - Ok(self - .dao - .set_by_guest_transaction(txn, parameter_name, Some(value.to_string()))?) - } - - fn simple_get_method( - &self, - decoder: fn(Option) -> Result, TypedConfigLayerError>, - parameter: &str, - ) -> Result { - match decoder(self.get(parameter)?)? { - None => Self::missing_value_panic(parameter), - Some(value) => Ok(value), - } + Ok(self.dao.set_by_guest_transaction( + txn, + parameter_name, + value_opt.map(|v| v.to_string()), + )?) } fn combined_params_get_method<'a, T, C>( @@ -1503,12 +1494,11 @@ mod tests { let start_block = subject.start_block().unwrap(); - assert_eq!(start_block, 6); + assert_eq!(start_block, Some(6)); } #[test] - #[should_panic(expected = "ever-supplied value missing: start_block; database is corrupt!")] - fn start_block_does_not_tolerate_optional_output() { + fn start_block_can_be_none() { let config_dao = Box::new(ConfigDaoMock::new().get_result(Ok(ConfigDaoRecord::new( "start_block", None, @@ -1516,11 +1506,13 @@ mod tests { )))); let subject = PersistentConfigurationReal::new(config_dao); - let _ = subject.start_block(); + let start_block = subject.start_block(); + + assert_eq!(start_block, Ok(None)); } #[test] - fn set_start_block_success() { + fn set_start_block_success_with_some() { let set_params_arc = Arc::new(Mutex::new(vec![])); let config_dao = Box::new( ConfigDaoMock::new() @@ -1529,7 +1521,7 @@ mod tests { ); let mut subject = PersistentConfigurationReal::new(config_dao); - let result = subject.set_start_block(1234); + let result = subject.set_start_block(Some(1234)); assert_eq!(result, Ok(())); let set_params = set_params_arc.lock().unwrap(); @@ -1553,7 +1545,7 @@ mod tests { let mut txn = TransactionSafeWrapper::new_with_builder(txn_inner_builder); let mut subject = PersistentConfigurationReal::new(config_dao); - let result = subject.set_start_block_from_txn(1234, &mut txn); + let result = subject.set_start_block_from_txn(Some(1234), &mut txn); assert_eq!(result, Ok(())); let set_params = set_params_arc.lock().unwrap(); @@ -1563,6 +1555,23 @@ mod tests { ) } + #[test] + fn set_start_block_success_with_none() { + let set_params_arc = Arc::new(Mutex::new(vec![])); + let config_dao = Box::new( + ConfigDaoMock::new() + .set_params(&set_params_arc) + .set_result(Ok(())), + ); + let mut subject = PersistentConfigurationReal::new(config_dao); + + let result = subject.set_start_block(None); + + assert_eq!(result, Ok(())); + let set_params = set_params_arc.lock().unwrap(); + assert_eq!(*set_params, vec![("start_block".to_string(), None)]) + } + #[test] fn gas_price() { let config_dao = Box::new(ConfigDaoMock::new().get_result(Ok(ConfigDaoRecord::new( diff --git a/node/src/node_configurator/configurator.rs b/node/src/node_configurator/configurator.rs index 30f0eed57..19b0b958a 100644 --- a/node/src/node_configurator/configurator.rs +++ b/node/src/node_configurator/configurator.rs @@ -551,7 +551,8 @@ impl Configurator { persistent_config.earning_wallet_address(), "earningWalletAddressOpt", )?; - let start_block = Self::value_required(persistent_config.start_block(), "startBlock")?; + let start_block_opt = + Self::value_not_required(persistent_config.start_block(), "startBlock")?; let max_block_count_opt = match persistent_config.max_block_count() { Ok(value) => value, Err(e) => panic!( @@ -649,7 +650,7 @@ impl Configurator { exit_byte_rate, exit_service_rate, }, - start_block, + start_block_opt, scan_intervals: UiScanIntervals { pending_payable_sec, payable_sec, @@ -786,11 +787,15 @@ impl Configurator { } fn set_start_block(&mut self, string_number: String) -> Result<(), (u64, String)> { - let block_number = match string_number.parse::() { - Ok(num) => num, - Err(e) => return Err((NON_PARSABLE_VALUE, format!("start block: {:?}", e))), + let block_number_opt = if "none".eq_ignore_ascii_case(&string_number) { + None + } else { + match string_number.parse::() { + Ok(num) => Some(num), + Err(e) => return Err((NON_PARSABLE_VALUE, format!("start block: {:?}", e))), + } }; - match self.persistent_config.set_start_block(block_number) { + match self.persistent_config.set_start_block(block_number_opt) { Ok(_) => Ok(()), Err(e) => Err((CONFIGURATOR_WRITE_ERROR, format!("start block: {:?}", e))), } @@ -2118,11 +2123,54 @@ mod tests { let (_, context_id) = UiSetConfigurationResponse::fmb(response.body.clone()).unwrap(); assert_eq!(context_id, 4444); let check_start_block_params = set_start_block_params_arc.lock().unwrap(); - assert_eq!(*check_start_block_params, vec![166666]); - TestLogHandler::new().exists_log_containing(&format!( - "DEBUG: {}: A request from UI received: {:?} from context id: {}", - test_name, msg, context_id - )); + assert_eq!(*check_start_block_params, vec![Some(166666)]); + } + + #[test] + fn handle_none_cases() { + vec!["none", "None", "nOnE", "NoNe", "NONE"] + .iter() + .for_each(|value| handle_set_configuration_accepts_none_to_unset_start_block(value)); + } + + fn handle_set_configuration_accepts_none_to_unset_start_block(cfg_value: &str) { + init_test_logging(); + let test_name = format!( + "handle_set_configuration_accepts_{}_to_unset_start_block", + &cfg_value + ); + let set_start_block_params_arc = Arc::new(Mutex::new(vec![])); + let (ui_gateway, _, ui_gateway_recording_arc) = make_recorder(); + let persistent_config = PersistentConfigurationMock::new() + .set_start_block_params(&set_start_block_params_arc) + .set_start_block_result(Ok(())); + let mut subject = make_subject(Some(persistent_config)); + subject.logger = Logger::new(test_name.as_str()); + let subject_addr = subject.start(); + let peer_actors = peer_actors_builder().ui_gateway(ui_gateway).build(); + subject_addr.try_send(BindMessage { peer_actors }).unwrap(); + let msg = UiSetConfigurationRequest { + name: "start-block".to_string(), + value: cfg_value.to_string(), + }; + let context_id = 4444; + + subject_addr + .try_send(NodeFromUiMessage { + client_id: 1234, + body: msg.clone().tmb(context_id), + }) + .unwrap(); + + let system = System::new("test"); + System::current().stop(); + system.run(); + let ui_gateway_recording = ui_gateway_recording_arc.lock().unwrap(); + let response = ui_gateway_recording.get_record::(0); + let (_, context_id) = UiSetConfigurationResponse::fmb(response.body.clone()).unwrap(); + assert_eq!(context_id, 4444); + let check_start_block_params = set_start_block_params_arc.lock().unwrap(); + assert_eq!(*check_start_block_params, vec![None]); } #[test] @@ -2498,7 +2546,7 @@ mod tests { .neighborhood_mode_result(Ok(NeighborhoodModeLight::Standard)) .past_neighbors_result(Ok(Some(vec![node_descriptor.clone()]))) .earning_wallet_address_result(Ok(Some(earning_wallet_address.clone()))) - .start_block_result(Ok(3456)); + .start_block_result(Ok(Some(3456))); let persistent_config = payment_thresholds_scan_intervals_rate_pack(persistent_config); let mut subject = make_subject(Some(persistent_config)); @@ -2541,7 +2589,7 @@ mod tests { exit_byte_rate: 10, exit_service_rate: 13 }, - start_block: 3456, + start_block_opt: Some(3456), scan_intervals: UiScanIntervals { pending_payable_sec: 122, payable_sec: 125, @@ -2629,8 +2677,7 @@ mod tests { .past_neighbors_params(&past_neighbors_params_arc) .past_neighbors_result(Ok(Some(vec![node_descriptor.clone()]))) .earning_wallet_address_result(Ok(Some(earning_wallet_address.clone()))) - .start_block_result(Ok(3456)) - .start_block_result(Ok(3456)); + .start_block_result(Ok(Some(3456))); let persistent_config = payment_thresholds_scan_intervals_rate_pack(persistent_config); let mut subject = make_subject(Some(persistent_config)); @@ -2673,7 +2720,7 @@ mod tests { exit_byte_rate: 10, exit_service_rate: 13 }, - start_block: 3456, + start_block_opt: Some(3456), scan_intervals: UiScanIntervals { pending_payable_sec: 122, payable_sec: 125, @@ -2700,7 +2747,7 @@ mod tests { .chain_name_result("ropsten".to_string()) .gas_price_result(Ok(2345)) .earning_wallet_address_result(Ok(None)) - .start_block_result(Ok(3456)) + .start_block_result(Ok(Some(3456))) .max_block_count_result(Ok(None)) .neighborhood_mode_result(Ok(NeighborhoodModeLight::ZeroHop)) .mapping_protocol_result(Ok(None)) @@ -2766,7 +2813,7 @@ mod tests { exit_byte_rate: 0, exit_service_rate: 0 }, - start_block: 3456, + start_block_opt: Some(3456), scan_intervals: UiScanIntervals { pending_payable_sec: 0, payable_sec: 0, @@ -2789,7 +2836,7 @@ mod tests { .chain_name_result("ropsten".to_string()) .gas_price_result(Ok(2345)) .earning_wallet_address_result(Ok(Some("4a5e43b54c6C56Ebf7".to_string()))) - .start_block_result(Ok(3456)) + .start_block_result(Ok(Some(3456))) .max_block_count_result(Err(PersistentConfigError::DatabaseError( "Corruption".to_string(), ))); @@ -2839,7 +2886,7 @@ mod tests { .earning_wallet_address_result(Ok(Some( "0x0123456789012345678901234567890123456789".to_string(), ))) - .start_block_result(Ok(3456)) + .start_block_result(Ok(Some(3456))) .max_block_count_result(Ok(Some(100000))) .neighborhood_mode_result(Ok(NeighborhoodModeLight::ConsumeOnly)) .mapping_protocol_result(Ok(Some(AutomapProtocol::Igdp))) diff --git a/node/src/test_utils/database_utils.rs b/node/src/test_utils/database_utils.rs index 2005166c0..02ba441a4 100644 --- a/node/src/test_utils/database_utils.rs +++ b/node/src/test_utils/database_utils.rs @@ -196,7 +196,7 @@ fn contains_particular_list_of_key_words( found += 1 } }); - assert_eq!(found,1, "We found {} occurrences of the searched line in the tested sql although only a one is considered correct", found) + assert_eq!(found, 1, "We found {} occurrences of the searched line in the tested sql although only a one is considered correct", found) } fn prepare_expected_vectors_of_words_including_sorting( diff --git a/node/src/test_utils/persistent_configuration_mock.rs b/node/src/test_utils/persistent_configuration_mock.rs index 7b7ace61d..d50613392 100644 --- a/node/src/test_utils/persistent_configuration_mock.rs +++ b/node/src/test_utils/persistent_configuration_mock.rs @@ -58,14 +58,14 @@ pub struct PersistentConfigurationMock { set_past_neighbors_params: Arc>, String)>>>, set_past_neighbors_results: RefCell>>, start_block_params: Arc>>, - start_block_results: RefCell>>, - set_start_block_params: Arc>>, + start_block_results: RefCell, PersistentConfigError>>>, + set_start_block_params: Arc>>>, set_start_block_results: RefCell>>, max_block_count_params: Arc>>, max_block_count_results: RefCell, PersistentConfigError>>>, set_max_block_count_params: Arc>>>, set_max_block_count_results: RefCell>>, - set_start_block_from_txn_params: Arc>>, + set_start_block_from_txn_params: Arc, ArbitraryIdStamp)>>>, set_start_block_from_txn_results: RefCell>>, payment_thresholds_results: RefCell>>, set_payment_thresholds_params: Arc>>, @@ -230,12 +230,12 @@ impl PersistentConfiguration for PersistentConfigurationMock { self.set_past_neighbors_results.borrow_mut().remove(0) } - fn start_block(&self) -> Result { + fn start_block(&self) -> Result, PersistentConfigError> { self.start_block_params.lock().unwrap().push(()); Self::result_from(&self.start_block_results) } - fn set_start_block(&mut self, value: u64) -> Result<(), PersistentConfigError> { + fn set_start_block(&mut self, value: Option) -> Result<(), PersistentConfigError> { self.set_start_block_params.lock().unwrap().push(value); Self::result_from(&self.set_start_block_results) } @@ -252,7 +252,7 @@ impl PersistentConfiguration for PersistentConfigurationMock { fn set_start_block_from_txn( &mut self, - value: u64, + value: Option, transaction: &mut TransactionSafeWrapper, ) -> Result<(), PersistentConfigError> { self.set_start_block_from_txn_params @@ -546,12 +546,12 @@ impl PersistentConfigurationMock { self } - pub fn start_block_result(self, result: Result) -> Self { + pub fn start_block_result(self, result: Result, PersistentConfigError>) -> Self { self.start_block_results.borrow_mut().push(result); self } - pub fn set_start_block_params(mut self, params: &Arc>>) -> Self { + pub fn set_start_block_params(mut self, params: &Arc>>>) -> Self { self.set_start_block_params = params.clone(); self } @@ -586,7 +586,7 @@ impl PersistentConfigurationMock { pub fn set_start_block_from_txn_params( mut self, - params: &Arc>>, + params: &Arc, ArbitraryIdStamp)>>>, ) -> Self { self.set_start_block_from_txn_params = params.clone(); self From 4db1f910b60c47f81a1515cad9077dd4344e2d36 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Fri, 8 Nov 2024 21:21:17 +1300 Subject: [PATCH 18/56] GH-744: Migrated the guts of get_transaction_receipt_in_batch to process_transaction_receipts --- node/src/blockchain/blockchain_bridge.rs | 3 +- .../lower_level_interface_web3.rs | 183 ++-------- .../blockchain_interface_web3/mod.rs | 328 +++++++++--------- .../lower_level_interface.rs | 18 +- .../blockchain/blockchain_interface/mod.rs | 7 + node/src/blockchain/test_utils.rs | 11 +- 6 files changed, 221 insertions(+), 329 deletions(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 2fe81e565..4ccacff93 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -392,8 +392,7 @@ impl BlockchainBridge { Box::new( self.blockchain_interface - .lower_interface() - .get_transaction_receipt_in_batch(transaction_hashes) + .process_transaction_receipts(transaction_hashes) .map_err(move |e| e.to_string()) .and_then(move |transaction_receipts_results| { let length = transaction_receipts_results.len(); diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index c21f802dc..98608bae7 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -14,12 +14,13 @@ use crate::sub_lib::wallet::Wallet; use actix::Recipient; use ethereum_types::{H256, U256, U64}; use futures::Future; +use serde_json::Value; use masq_lib::blockchains::chains::Chain; use masq_lib::logger::Logger; use web3::contract::{Contract, Options}; use web3::transports::{Batch, Http}; use web3::types::{Address, BlockNumber, Filter, Log, TransactionReceipt}; -use web3::Web3; +use web3::{Error, Web3}; #[derive(Debug, PartialEq, Clone)] #[allow(clippy::large_enum_variant)] @@ -94,7 +95,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_receipt_in_batch( &self, hash_vec: Vec, - ) -> Box, Error=BlockchainError>> { + ) -> Box>, Error=BlockchainError>> { let _ = hash_vec.into_iter().map(|hash| { self.web3_batch.eth().transaction_receipt(hash); }); @@ -103,39 +104,39 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { .transport() .submit_batch() .map_err(|e| QueryFailed(e.to_string())) - .and_then(move |batch_response| { - Ok(batch_response - .into_iter() - .map(|response| match response { - Ok(result) => { - match serde_json::from_value::(result) { - Ok(receipt) => { - match receipt.status { - None => { - TransactionReceiptResult::NotPresent - } - Some(status) => { - if status == U64::from(1) { - TransactionReceiptResult::Found(receipt) - } else { - TransactionReceiptResult::TransactionFailed(receipt) - } - } - } - } - Err(e) => { - if e.to_string().contains("invalid type: null") { - TransactionReceiptResult::NotPresent - } else { - TransactionReceiptResult::Error(e.to_string()) - } - } - } - } - Err(e) => TransactionReceiptResult::Error(e.to_string()), - }) - .collect::>()) - }), + // .and_then(move |batch_response| { + // Ok(batch_response + // .into_iter() + // .map(|response| match response { + // Ok(result) => { + // match serde_json::from_value::(result) { + // Ok(receipt) => { + // match receipt.status { + // None => { + // TransactionReceiptResult::NotPresent + // } + // Some(status) => { + // if status == U64::from(1) { + // TransactionReceiptResult::Found(receipt) + // } else { + // TransactionReceiptResult::TransactionFailed(receipt) + // } + // } + // } + // } + // Err(e) => { + // if e.to_string().contains("invalid type: null") { + // TransactionReceiptResult::NotPresent + // } else { + // TransactionReceiptResult::Error(e.to_string()) + // } + // } + // } + // } + // Err(e) => TransactionReceiptResult::Error(e.to_string()), + // }) + // .collect::>()) + // }), ) } @@ -433,118 +434,6 @@ mod tests { ) } - #[test] - fn transaction_receipt_batch_works() { - let port = find_free_port(); - let tx_hash_1 = - H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0e") - .unwrap(); - let tx_hash_2 = - H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0f") - .unwrap(); - let tx_hash_3 = - H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0a") - .unwrap(); - let tx_hash_4 = - H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0b") - .unwrap(); - let tx_hash_5 = - H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0c") - .unwrap(); - - let tx_hash_6 = - H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0d") - .unwrap(); - let tx_hash_vec = vec![tx_hash_1, tx_hash_2, tx_hash_3, tx_hash_4, tx_hash_5, tx_hash_6]; - let block_hash = - H256::from_str("6d0abccae617442c26104c2bc63d1bc05e1e002e555aec4ab62a46e826b18f18") - .unwrap(); - let block_number = U64::from_str("b0328d").unwrap(); - let cumulative_gas_used = U256::from_str("60ef").unwrap(); - let gas_used = U256::from_str("60ef").unwrap(); - let status = U64::from(1); - let status_failed = U64::from(0); - let tx_receipt_response_not_present = ReceiptResponseBuilder::default() - .transaction_hash(tx_hash_4) - .build(); - let tx_receipt_response_failed = ReceiptResponseBuilder::default() - .transaction_hash(tx_hash_5) - .status(status_failed) - .build(); - let tx_receipt_response_success = ReceiptResponseBuilder::default() - .transaction_hash(tx_hash_6) - .block_hash(block_hash) - .block_number(block_number) - .cumulative_gas_used(cumulative_gas_used) - .gas_used(gas_used) - .status(status) - .build(); - let _blockchain_client_server = MBCSBuilder::new(port) - .begin_batch() - .err_response( - 429, - "The requests per second (RPS) of your requests are higher than your plan allows." - .to_string(), - 7, - ) - .raw_response(r#"{ "jsonrpc": "2.0", "id": 1, "result": null }"#.to_string()) - .response("trash".to_string(), 0) - .raw_response(tx_receipt_response_not_present) - .raw_response(tx_receipt_response_failed) - .raw_response(tx_receipt_response_success) - .end_batch() - .start(); - let subject = make_blockchain_interface_web3(Some(port)); - - let result = subject - .lower_interface() - .get_transaction_receipt_in_batch(tx_hash_vec) - .wait() - .unwrap(); - - assert_eq!(result[0], TransactionReceiptResult::Error("RPC error: Error { code: ServerError(429), message: \"The requests per second (RPS) of your requests are higher than your plan allows.\", data: None }".to_string())); - assert_eq!(result[1], TransactionReceiptResult::NotPresent); - assert_eq!( - result[2], - TransactionReceiptResult::Error( - "invalid type: string \"trash\", expected struct Receipt".to_string() - ) - ); - assert_eq!(result[3], TransactionReceiptResult::NotPresent); - assert_eq!( - result[4], - TransactionReceiptResult::TransactionFailed(TransactionReceipt { - transaction_hash: tx_hash_5, - transaction_index: Default::default(), - block_hash: None, - block_number: None, - cumulative_gas_used: U256::from(0), - gas_used: None, - contract_address: None, - logs: vec![], - status: Some(status_failed), - root: None, - logs_bloom: H2048::default() - }) - ); - assert_eq!( - result[5], - TransactionReceiptResult::Found(TransactionReceipt { - transaction_hash: tx_hash_6, - transaction_index: Default::default(), - block_hash: Some(block_hash), - block_number: Some(block_number), - cumulative_gas_used, - gas_used: Some(gas_used), - contract_address: None, - logs: vec![], - status: Some(status), - root: None, - logs_bloom: H2048::default() - }) - ); - } - #[test] fn transaction_receipt_batch_fails_on_submit_batch() { let port = find_free_port(); diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 0f52b95ec..ea33d6948 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -16,8 +16,8 @@ use std::convert::{From, TryInto}; use std::fmt::Debug; use ethereum_types::U64; use web3::transports::{EventLoopHandle, Http}; -use web3::types::{Address, BlockNumber, Log, H256, U256, FilterBuilder}; -use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::LowBlockchainIntWeb3; +use web3::types::{Address, BlockNumber, Log, H256, U256, FilterBuilder, TransactionReceipt}; +use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{LowBlockchainIntWeb3, TransactionReceiptResult}; use crate::blockchain::blockchain_interface_utils::{create_blockchain_agent_web3, BlockchainAgentFutureResult}; const CONTRACT_ABI: &str = indoc!( @@ -203,6 +203,46 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { self.contract_address(), )) } + + fn process_transaction_receipts(&self, transaction_hashes: Vec) -> Box, Error=BlockchainError>> { + Box::new( + self.lower_interface().get_transaction_receipt_in_batch(transaction_hashes) + .map_err(|e| e) + .and_then(move |batch_response| { + Ok(batch_response + .into_iter() + .map(|response| match response { + Ok(result) => { + match serde_json::from_value::(result) { + Ok(receipt) => { + match receipt.status { + None => { + TransactionReceiptResult::NotPresent + } + Some(status) => { + if status == U64::from(1) { + TransactionReceiptResult::Found(receipt) + } else { + TransactionReceiptResult::TransactionFailed(receipt) + } + } + } + } + Err(e) => { + if e.to_string().contains("invalid type: null") { + TransactionReceiptResult::NotPresent + } else { + TransactionReceiptResult::Error(e.to_string()) + } + } + } + } + Err(e) => TransactionReceiptResult::Error(e.to_string()), + }) + .collect::>()) + }), + ) + } } #[derive(Debug, Clone, PartialEq, Eq, Copy)] @@ -323,7 +363,7 @@ mod tests { RetrievedBlockchainTransactions, }; use crate::blockchain::blockchain_interface_utils::calculate_fallback_start_block_number; - use crate::blockchain::test_utils::{all_chains, make_blockchain_interface_web3}; + use crate::blockchain::test_utils::{all_chains, make_blockchain_interface_web3, ReceiptResponseBuilder}; use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; use crate::test_utils::make_paying_wallet; @@ -340,9 +380,10 @@ mod tests { use std::net::Ipv4Addr; use std::str::FromStr; use web3::transports::Http; - use web3::types::{BlockNumber, Bytes, TransactionParameters, H256, U256}; + use web3::types::{BlockNumber, Bytes, TransactionParameters, H2048, H256, U256}; use web3::Web3; + #[test] fn constants_are_correct() { let contract_abi_expected: &str = indoc!( @@ -375,6 +416,10 @@ mod tests { assert_eq!(TRANSACTION_LITERAL, transaction_literal_expected); assert_eq!(TRANSFER_METHOD_ID, [0xa9, 0x05, 0x9c, 0xbb]); assert_eq!(REQUESTS_IN_PARALLEL, 1); + assert_eq!( + TRANSFER_METHOD_ID, + "transfer(address,uint256)".keccak256()[0..4], + ); } #[test] @@ -817,6 +862,116 @@ mod tests { ); } + #[test] + fn process_transaction_receipts_works() { + let port = find_free_port(); + let tx_hash_1 = + H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0e") + .unwrap(); + let tx_hash_2 = + H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0f") + .unwrap(); + let tx_hash_3 = + H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0a") + .unwrap(); + let tx_hash_4 = + H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0b") + .unwrap(); + let tx_hash_5 = + H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0c") + .unwrap(); + let tx_hash_6 = + H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0d") + .unwrap(); + let tx_hash_vec = vec![tx_hash_1, tx_hash_2, tx_hash_3, tx_hash_4, tx_hash_5, tx_hash_6]; + let block_hash = + H256::from_str("6d0abccae617442c26104c2bc63d1bc05e1e002e555aec4ab62a46e826b18f18") + .unwrap(); + let block_number = U64::from_str("b0328d").unwrap(); + let cumulative_gas_used = U256::from_str("60ef").unwrap(); + let gas_used = U256::from_str("60ef").unwrap(); + let status = U64::from(1); + let status_failed = U64::from(0); + let tx_receipt_response_not_present = ReceiptResponseBuilder::default() + .transaction_hash(tx_hash_4) + .build(); + let tx_receipt_response_failed = ReceiptResponseBuilder::default() + .transaction_hash(tx_hash_5) + .status(status_failed) + .build(); + let tx_receipt_response_success = ReceiptResponseBuilder::default() + .transaction_hash(tx_hash_6) + .block_hash(block_hash) + .block_number(block_number) + .cumulative_gas_used(cumulative_gas_used) + .gas_used(gas_used) + .status(status) + .build(); + let _blockchain_client_server = MBCSBuilder::new(port) + .begin_batch() + .err_response( + 429, + "The requests per second (RPS) of your requests are higher than your plan allows." + .to_string(), + 7, + ) + .raw_response(r#"{ "jsonrpc": "2.0", "id": 1, "result": null }"#.to_string()) + .response("trash".to_string(), 0) + .raw_response(tx_receipt_response_not_present) + .raw_response(tx_receipt_response_failed) + .raw_response(tx_receipt_response_success) + .end_batch() + .start(); + let subject = make_blockchain_interface_web3(Some(port)); + + let result = subject + .process_transaction_receipts(tx_hash_vec) + .wait() + .unwrap(); + + assert_eq!(result[0], TransactionReceiptResult::Error("RPC error: Error { code: ServerError(429), message: \"The requests per second (RPS) of your requests are higher than your plan allows.\", data: None }".to_string())); + assert_eq!(result[1], TransactionReceiptResult::NotPresent); + assert_eq!( + result[2], + TransactionReceiptResult::Error( + "invalid type: string \"trash\", expected struct Receipt".to_string() + ) + ); + assert_eq!(result[3], TransactionReceiptResult::NotPresent); + assert_eq!( + result[4], + TransactionReceiptResult::TransactionFailed(TransactionReceipt { + transaction_hash: tx_hash_5, + transaction_index: Default::default(), + block_hash: None, + block_number: None, + cumulative_gas_used: U256::from(0), + gas_used: None, + contract_address: None, + logs: vec![], + status: Some(status_failed), + root: None, + logs_bloom: H2048::default() + }) + ); + assert_eq!( + result[5], + TransactionReceiptResult::Found(TransactionReceipt { + transaction_hash: tx_hash_6, + transaction_index: Default::default(), + block_hash: Some(block_hash), + block_number: Some(block_number), + cumulative_gas_used, + gas_used: Some(gas_used), + contract_address: None, + logs: vec![], + status: Some(status), + root: None, + logs_bloom: H2048::default() + }) + ); + } + #[test] fn web3_gas_limit_const_part_returns_reasonable_values() { type Subject = BlockchainInterfaceWeb3; @@ -835,169 +990,4 @@ mod tests { assert_eq!(Subject::web3_gas_limit_const_part(Chain::PolyAmoy), 70_000); assert_eq!(Subject::web3_gas_limit_const_part(Chain::Dev), 55_000); } - - //an adapted test from old times when we had our own signing method - //I don't have data for the new chains so I omit them in this kind of tests - #[test] - fn signs_various_transactions_for_eth_mainnet() { - let signatures = &[ - &[ - 248, 108, 9, 133, 4, 168, 23, 200, 0, 130, 82, 8, 148, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 136, 13, 224, 182, 179, 167, - 100, 0, 0, 128, 37, 160, 40, 239, 97, 52, 11, 217, 57, 188, 33, 149, 254, 83, 117, - 103, 134, 96, 3, 225, 161, 93, 60, 113, 255, 99, 225, 89, 6, 32, 170, 99, 98, 118, - 160, 103, 203, 233, 216, 153, 127, 118, 26, 236, 183, 3, 48, 75, 56, 0, 204, 245, - 85, 201, 243, 220, 100, 33, 75, 41, 127, 177, 150, 106, 59, 109, 131, - ][..], - &[ - 248, 106, 128, 134, 213, 86, 152, 55, 36, 49, 131, 30, 132, 128, 148, 240, 16, 159, - 200, 223, 40, 48, 39, 182, 40, 92, 200, 137, 245, 170, 98, 78, 172, 31, 85, 132, - 59, 154, 202, 0, 128, 37, 160, 9, 235, 182, 202, 5, 122, 5, 53, 214, 24, 100, 98, - 188, 11, 70, 91, 86, 28, 148, 162, 149, 189, 176, 98, 31, 193, 146, 8, 171, 20, - 154, 156, 160, 68, 15, 253, 119, 92, 233, 26, 131, 58, 180, 16, 119, 114, 4, 213, - 52, 26, 111, 159, 169, 18, 22, 166, 243, 238, 44, 5, 31, 234, 106, 4, 40, - ][..], - &[ - 248, 117, 128, 134, 9, 24, 78, 114, 160, 0, 130, 39, 16, 128, 128, 164, 127, 116, - 101, 115, 116, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 87, 38, 160, 122, 155, 12, 58, 133, 108, 183, 145, 181, - 210, 141, 44, 236, 17, 96, 40, 55, 87, 204, 250, 142, 83, 122, 168, 250, 5, 113, - 172, 203, 5, 12, 181, 160, 9, 100, 95, 141, 167, 178, 53, 101, 115, 131, 83, 172, - 199, 242, 208, 96, 246, 121, 25, 18, 211, 89, 60, 94, 165, 169, 71, 3, 176, 157, - 167, 50, - ][..], - ]; - assert_signature(Chain::EthMainnet, signatures) - } - - // Adapted test from old times when we had our own signing method. - // Don't have data for new chains, so I omit them in this kind of tests - #[test] - fn signs_various_transactions_for_ropsten() { - let signatures = &[ - &[ - 248, 108, 9, 133, 4, 168, 23, 200, 0, 130, 82, 8, 148, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 136, 13, 224, 182, 179, 167, - 100, 0, 0, 128, 41, 160, 8, 220, 80, 201, 100, 41, 178, 35, 151, 227, 210, 85, 27, - 41, 27, 82, 217, 176, 64, 92, 205, 10, 195, 169, 66, 91, 213, 199, 124, 52, 3, 192, - 160, 94, 220, 102, 179, 128, 78, 150, 78, 230, 117, 10, 10, 32, 108, 241, 50, 19, - 148, 198, 6, 147, 110, 175, 70, 157, 72, 31, 216, 193, 229, 151, 115, - ][..], - &[ - 248, 106, 128, 134, 213, 86, 152, 55, 36, 49, 131, 30, 132, 128, 148, 240, 16, 159, - 200, 223, 40, 48, 39, 182, 40, 92, 200, 137, 245, 170, 98, 78, 172, 31, 85, 132, - 59, 154, 202, 0, 128, 41, 160, 186, 65, 161, 205, 173, 93, 185, 43, 220, 161, 63, - 65, 19, 229, 65, 186, 247, 197, 132, 141, 184, 196, 6, 117, 225, 181, 8, 81, 198, - 102, 150, 198, 160, 112, 126, 42, 201, 234, 236, 168, 183, 30, 214, 145, 115, 201, - 45, 191, 46, 3, 113, 53, 80, 203, 164, 210, 112, 42, 182, 136, 223, 125, 232, 21, - 205, - ][..], - &[ - 248, 117, 128, 134, 9, 24, 78, 114, 160, 0, 130, 39, 16, 128, 128, 164, 127, 116, - 101, 115, 116, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 87, 41, 160, 146, 204, 57, 32, 218, 236, 59, 94, 106, 72, - 174, 211, 223, 160, 122, 186, 126, 44, 200, 41, 222, 117, 117, 177, 189, 78, 203, - 8, 172, 155, 219, 66, 160, 83, 82, 37, 6, 243, 61, 188, 102, 176, 132, 102, 74, - 111, 180, 105, 33, 122, 106, 109, 73, 180, 65, 10, 117, 175, 190, 19, 196, 17, 128, - 193, 75, - ][..], - ]; - assert_signature(Chain::EthRopsten, signatures) - } - - #[derive(Deserialize)] - struct Signing { - signed: Vec, - private_key: H256, - } - - fn assert_signature(chain: Chain, slice_of_slices: &[&[u8]]) { - let first_part_tx_1 = r#"[{"nonce": "0x9", "gasPrice": "0x4a817c800", "gasLimit": "0x5208", "to": "0x3535353535353535353535353535353535353535", "value": "0xde0b6b3a7640000", "data": []}, {"private_key": "0x4646464646464646464646464646464646464646464646464646464646464646", "signed": "#; - let first_part_tx_2 = r#"[{"nonce": "0x0", "gasPrice": "0xd55698372431", "gasLimit": "0x1e8480", "to": "0xF0109fC8DF283027b6285cc889F5aA624EaC1F55", "value": "0x3b9aca00", "data": []}, {"private_key": "0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318", "signed": "#; - let first_part_tx_3 = r#"[{"nonce": "0x00", "gasPrice": "0x09184e72a000", "gasLimit": "0x2710", "to": null, "value": "0x00", "data": [127,116,101,115,116,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,87]}, {"private_key": "0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109", "signed": "#; - fn compose(first_part: &str, slice: &[u8]) -> String { - let third_part_jrc = "}]"; - format!("{}{:?}{}", first_part, slice, third_part_jrc) - } - let all_transactions = format!( - "[{}]", - vec![first_part_tx_1, first_part_tx_2, first_part_tx_3] - .iter() - .zip(slice_of_slices.iter()) - .zip(0usize..2) - .fold(String::new(), |so_far, actual| [ - so_far, - compose(actual.0.0, actual.0.1) - ] - .join(if actual.1 == 0 { "" } else { ", " })) - ); - let txs: Vec<(TestRawTransaction, Signing)> = - serde_json::from_str(&all_transactions).unwrap(); - let constant_parts = &[ - &[ - 248u8, 108, 9, 133, 4, 168, 23, 200, 0, 130, 82, 8, 148, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 136, 13, 224, 182, 179, - 167, 100, 0, 0, 128, - ][..], - &[ - 248, 106, 128, 134, 213, 86, 152, 55, 36, 49, 131, 30, 132, 128, 148, 240, 16, 159, - 200, 223, 40, 48, 39, 182, 40, 92, 200, 137, 245, 170, 98, 78, 172, 31, 85, 132, - 59, 154, 202, 0, 128, - ][..], - &[ - 248, 117, 128, 134, 9, 24, 78, 114, 160, 0, 130, 39, 16, 128, 128, 164, 127, 116, - 101, 115, 116, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 87, - ][..], - ]; - - let subject = make_blockchain_interface_web3(None); - let lengths_of_constant_parts: Vec = - constant_parts.iter().map(|part| part.len()).collect(); - for (((tx, signed), length), constant_part) in txs - .iter() - .zip(lengths_of_constant_parts) - .zip(constant_parts) - { - let secret = Wallet::from( - Bip32EncryptionKeyProvider::from_raw_secret(&signed.private_key.0.as_ref()) - .unwrap(), - ) - .prepare_secp256k1_secret() - .unwrap(); - let tx_params = from_raw_transaction_to_transaction_parameters(tx, chain); - let web3 = Web3::new(subject.transport.clone()); - let sign = web3 - .accounts() - .sign_transaction(tx_params, &secret) - .wait() - .unwrap(); - let signed_data_bytes = sign.raw_transaction.0; - assert_eq!(signed_data_bytes, signed.signed); - assert_eq!(signed_data_bytes[..length], **constant_part) - } - } - - fn from_raw_transaction_to_transaction_parameters( - raw_transaction: &TestRawTransaction, - chain: Chain, - ) -> TransactionParameters { - TransactionParameters { - nonce: Some(raw_transaction.nonce), - to: raw_transaction.to, - gas: raw_transaction.gas_limit, - gas_price: Some(raw_transaction.gas_price), - value: raw_transaction.value, - data: Bytes(raw_transaction.data.clone()), - chain_id: Some(chain.rec().num_chain_id), - } - } - - #[test] - fn hash_the_smart_contract_transfer_function_signature() { - assert_eq!( - "transfer(address,uint256)".keccak256()[0..4], - TRANSFER_METHOD_ID, - ); - } } diff --git a/node/src/blockchain/blockchain_interface/lower_level_interface.rs b/node/src/blockchain/blockchain_interface/lower_level_interface.rs index 8208c4b11..9d1adc2c8 100644 --- a/node/src/blockchain/blockchain_interface/lower_level_interface.rs +++ b/node/src/blockchain/blockchain_interface/lower_level_interface.rs @@ -5,7 +5,9 @@ use crate::blockchain::blockchain_interface::data_structures::errors::{Blockchai use crate::sub_lib::wallet::Wallet; use ethereum_types::{H256, U64}; use futures::Future; +use serde_json::Value; use web3::contract::Contract; +use web3::Error; use web3::transports::Http; use web3::types::{Address, Filter, Log, U256}; use masq_lib::blockchains::chains::Chain; @@ -23,33 +25,33 @@ pub trait LowBlockchainInt { fn get_transaction_fee_balance( &self, address: Address, - ) -> Box>; + ) -> Box>; fn get_service_fee_balance( &self, address: Address, - ) -> Box>; + ) -> Box>; - fn get_gas_price(&self) -> Box>; + fn get_gas_price(&self) -> Box>; - fn get_block_number(&self) -> Box>; + fn get_block_number(&self) -> Box>; fn get_transaction_id( &self, address: Address, - ) -> Box>; + ) -> Box>; fn get_transaction_receipt_in_batch( &self, hash_vec: Vec, - ) -> Box, Error = BlockchainError>>; + ) -> Box>, Error=BlockchainError>>; fn get_contract(&self) -> Contract; fn get_transaction_logs( &self, filter: Filter, - ) -> Box, Error = BlockchainError>>; + ) -> Box, Error=BlockchainError>>; fn submit_payables_in_batch( &self, @@ -58,5 +60,5 @@ pub trait LowBlockchainInt { consuming_wallet: Wallet, fingerprints_recipient: Recipient, affordable_accounts: Vec, - ) -> Box, Error = PayableTransactionError>>; + ) -> Box, Error=PayableTransactionError>>; } diff --git a/node/src/blockchain/blockchain_interface/mod.rs b/node/src/blockchain/blockchain_interface/mod.rs index eafba9e9f..c2555f3c4 100644 --- a/node/src/blockchain/blockchain_interface/mod.rs +++ b/node/src/blockchain/blockchain_interface/mod.rs @@ -4,6 +4,7 @@ pub mod blockchain_interface_web3; pub mod data_structures; pub mod lower_level_interface; +use ethereum_types::H256; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; use crate::blockchain::blockchain_interface::data_structures::errors::{ BlockchainAgentBuildError, BlockchainError, @@ -14,6 +15,7 @@ use crate::sub_lib::wallet::Wallet; use futures::Future; use masq_lib::blockchains::chains::Chain; use web3::types::{Address, BlockNumber}; +use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; pub trait BlockchainInterface { fn contract_address(&self) -> Address; @@ -37,5 +39,10 @@ pub trait BlockchainInterface { consuming_wallet: Wallet, ) -> Box, Error=BlockchainAgentBuildError>>; + fn process_transaction_receipts( + &self, + transaction_hashes: Vec, + ) -> Box, Error=BlockchainError>>; + as_any_ref_in_trait!(); } diff --git a/node/src/blockchain/test_utils.rs b/node/src/blockchain/test_utils.rs index 2110f80b3..1f4229d64 100644 --- a/node/src/blockchain/test_utils.rs +++ b/node/src/blockchain/test_utils.rs @@ -33,6 +33,7 @@ use web3::transports::{EventLoopHandle, Http}; use web3::types::{ Address, BlockNumber, Index, Log, SignedTransaction, TransactionReceipt, H2048, U256, }; +use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; lazy_static! { static ref BIG_MEANINGLESS_PHRASE: Vec<&'static str> = vec![ @@ -63,7 +64,7 @@ pub fn make_blockchain_interface_web3(port_opt: Option) -> BlockchainInterf &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); BlockchainInterfaceWeb3::new(transport, event_loop_handle, chain) } @@ -214,7 +215,7 @@ impl BlockchainInterface for BlockchainInterfaceMock { start_block: BlockNumber, fallback_start_block_number: u64, recipient: Address, - ) -> Box> { + ) -> Box> { self.retrieve_transactions_parameters.lock().unwrap().push(( start_block, fallback_start_block_number, @@ -228,13 +229,17 @@ impl BlockchainInterface for BlockchainInterfaceMock { fn build_blockchain_agent( &self, _consuming_wallet: Wallet, - ) -> Box, Error = BlockchainAgentBuildError>> { + ) -> Box, Error=BlockchainAgentBuildError>> { unimplemented!("not needed so far") } fn lower_interface(&self) -> Box { unimplemented!("not needed so far") } + + fn process_transaction_receipts(&self, _transaction_hashes: Vec) -> Box, Error=BlockchainError>> { + unimplemented!("not needed so far") + } } impl BlockchainInterfaceMock { From b0aed3ac6e3017b1526eed6efe7dff2b101e331f Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 11 Nov 2024 21:39:30 +1300 Subject: [PATCH 19/56] GH-744: Moved submit_payables_in_batch to blockchain_interface --- node/src/blockchain/blockchain_bridge.rs | 1 - .../lower_level_interface_web3.rs | 88 ++----------------- .../blockchain_interface_web3/mod.rs | 53 ++++++++--- .../lower_level_interface.rs | 15 ++-- .../blockchain/blockchain_interface/mod.rs | 19 +++- node/src/blockchain/test_utils.rs | 14 ++- 6 files changed, 78 insertions(+), 112 deletions(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 4ccacff93..71b75f99b 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -462,7 +462,6 @@ impl BlockchainBridge { let logger = self.logger.clone(); let chain = self.blockchain_interface.get_chain(); self.blockchain_interface - .lower_interface() .submit_payables_in_batch( logger, chain, diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index 98608bae7..205202ff5 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -1,22 +1,12 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -use crate::accountant::db_access_objects::payable_dao::PayableAccount; -use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; use crate::blockchain::blockchain_interface::blockchain_interface_web3::CONTRACT_ABI; use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError::QueryFailed; -use crate::blockchain::blockchain_interface::data_structures::errors::{ - BlockchainError, PayableTransactionError, -}; -use crate::blockchain::blockchain_interface::data_structures::ProcessedPayableFallible; +use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError; use crate::blockchain::blockchain_interface::lower_level_interface::LowBlockchainInt; -use crate::blockchain::blockchain_interface_utils::send_payables_within_batch; -use crate::sub_lib::wallet::Wallet; -use actix::Recipient; use ethereum_types::{H256, U256, U64}; use futures::Future; use serde_json::Value; -use masq_lib::blockchains::chains::Chain; -use masq_lib::logger::Logger; use web3::contract::{Contract, Options}; use web3::transports::{Batch, Http}; use web3::types::{Address, BlockNumber, Filter, Log, TransactionReceipt}; @@ -104,39 +94,6 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { .transport() .submit_batch() .map_err(|e| QueryFailed(e.to_string())) - // .and_then(move |batch_response| { - // Ok(batch_response - // .into_iter() - // .map(|response| match response { - // Ok(result) => { - // match serde_json::from_value::(result) { - // Ok(receipt) => { - // match receipt.status { - // None => { - // TransactionReceiptResult::NotPresent - // } - // Some(status) => { - // if status == U64::from(1) { - // TransactionReceiptResult::Found(receipt) - // } else { - // TransactionReceiptResult::TransactionFailed(receipt) - // } - // } - // } - // } - // Err(e) => { - // if e.to_string().contains("invalid type: null") { - // TransactionReceiptResult::NotPresent - // } else { - // TransactionReceiptResult::Error(e.to_string()) - // } - // } - // } - // } - // Err(e) => TransactionReceiptResult::Error(e.to_string()), - // }) - // .collect::>()) - // }), ) } @@ -157,41 +114,8 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } - fn submit_payables_in_batch( - &self, - logger: Logger, - chain: Chain, - consuming_wallet: Wallet, - fingerprints_recipient: Recipient, - affordable_accounts: Vec, - ) -> Box, Error=PayableTransactionError>> - { - let web3_batch = self.web3_batch.clone(); - let get_transaction_id = self.get_transaction_id(consuming_wallet.address()); - // We are not relying on Database and fetching the values straight from the blockchain. - // Modify according to the Payment adjusters new design - let get_gas_price = self.get_gas_price(); - - Box::new( - get_transaction_id - .map_err(PayableTransactionError::TransactionID) - .and_then(move |pending_nonce| { - get_gas_price - .map_err(PayableTransactionError::GasPriceQueryFailed) - .and_then(move |gas_price_wei| { - send_payables_within_batch( - logger, - chain, - web3_batch, - consuming_wallet, - gas_price_wei, - pending_nonce, - fingerprints_recipient, - affordable_accounts, - ) - }) - }), - ) + fn get_web3_batch(&self) -> Web3> { + self.web3_batch.clone() } } @@ -218,13 +142,11 @@ mod tests { use std::str::FromStr; use ethereum_types::{H256, U64}; use futures::Future; - use trust_dns_proto::rr::DNSClass::NONE; - use web3::types::{BlockNumber, Bytes, FilterBuilder, H2048, Log, TransactionReceipt, U256}; + use web3::types::{BlockNumber, Bytes, FilterBuilder, Log, U256}; use masq_lib::test_utils::mock_blockchain_client_server::MBCSBuilder; use crate::blockchain::blockchain_interface::blockchain_interface_web3::TRANSACTION_LITERAL; - use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError::QueryFailed; - use crate::blockchain::test_utils::{make_blockchain_interface_web3, ReceiptResponseBuilder}; + use crate::blockchain::test_utils::{make_blockchain_interface_web3}; use crate::test_utils::make_wallet; #[test] diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index ea33d6948..41e3f3ae0 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -2,8 +2,8 @@ pub mod lower_level_interface_web3; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; -use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError; -use crate::blockchain::blockchain_interface::data_structures::BlockchainTransaction; +use crate::blockchain::blockchain_interface::data_structures::errors::{BlockchainError, PayableTransactionError}; +use crate::blockchain::blockchain_interface::data_structures::{BlockchainTransaction, ProcessedPayableFallible}; use crate::blockchain::blockchain_interface::lower_level_interface::LowBlockchainInt; use crate::blockchain::blockchain_interface::RetrievedBlockchainTransactions; use crate::blockchain::blockchain_interface::{BlockchainAgentBuildError, BlockchainInterface}; @@ -14,11 +14,15 @@ use masq_lib::blockchains::chains::Chain; use masq_lib::logger::Logger; use std::convert::{From, TryInto}; use std::fmt::Debug; +use std::ops::Deref; +use actix::Recipient; use ethereum_types::U64; use web3::transports::{EventLoopHandle, Http}; use web3::types::{Address, BlockNumber, Log, H256, U256, FilterBuilder, TransactionReceipt}; +use crate::accountant::db_access_objects::payable_dao::PayableAccount; +use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{LowBlockchainIntWeb3, TransactionReceiptResult}; -use crate::blockchain::blockchain_interface_utils::{create_blockchain_agent_web3, BlockchainAgentFutureResult}; +use crate::blockchain::blockchain_interface_utils::{create_blockchain_agent_web3, send_payables_within_batch, BlockchainAgentFutureResult}; const CONTRACT_ABI: &str = indoc!( r#"[{ @@ -78,6 +82,13 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { self.chain } + fn lower_interface(&self) -> Box { + Box::new(LowBlockchainIntWeb3::new( + self.transport.clone(), + self.contract_address(), + )) + } + fn retrieve_transactions( &self, start_block: BlockNumber, @@ -197,13 +208,6 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { ) } - fn lower_interface(&self) -> Box { - Box::new(LowBlockchainIntWeb3::new( - self.transport.clone(), - self.contract_address(), - )) - } - fn process_transaction_receipts(&self, transaction_hashes: Vec) -> Box, Error=BlockchainError>> { Box::new( self.lower_interface().get_transaction_receipt_in_batch(transaction_hashes) @@ -243,6 +247,35 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { }), ) } + + fn submit_payables_in_batch(&self, logger: Logger, chain: Chain, consuming_wallet: Wallet, fingerprints_recipient: Recipient, affordable_accounts: Vec) -> Box, Error=PayableTransactionError>> { + let web3_batch = self.lower_interface().get_web3_batch(); + let get_transaction_id = self.lower_interface().get_transaction_id(consuming_wallet.address()); + // We are not relying on Database and fetching the values straight from the blockchain. + // Modify according to the Payment adjusters new design + let get_gas_price = self.lower_interface().get_gas_price(); + + Box::new( + get_transaction_id + .map_err(PayableTransactionError::TransactionID) + .and_then(move |pending_nonce| { + get_gas_price + .map_err(PayableTransactionError::GasPriceQueryFailed) + .and_then(move |gas_price_wei| { + send_payables_within_batch( + logger, + chain, + web3_batch, + consuming_wallet, + gas_price_wei, + pending_nonce, + fingerprints_recipient, + affordable_accounts, + ) + }) + }), + ) + } } #[derive(Debug, Clone, PartialEq, Eq, Copy)] diff --git a/node/src/blockchain/blockchain_interface/lower_level_interface.rs b/node/src/blockchain/blockchain_interface/lower_level_interface.rs index 9d1adc2c8..a9fdf7e1e 100644 --- a/node/src/blockchain/blockchain_interface/lower_level_interface.rs +++ b/node/src/blockchain/blockchain_interface/lower_level_interface.rs @@ -7,8 +7,8 @@ use ethereum_types::{H256, U64}; use futures::Future; use serde_json::Value; use web3::contract::Contract; -use web3::Error; -use web3::transports::Http; +use web3::{Error, Web3}; +use web3::transports::{Batch, Http}; use web3::types::{Address, Filter, Log, U256}; use masq_lib::blockchains::chains::Chain; use masq_lib::logger::Logger; @@ -53,12 +53,7 @@ pub trait LowBlockchainInt { filter: Filter, ) -> Box, Error=BlockchainError>>; - fn submit_payables_in_batch( - &self, - logger: Logger, - chain: Chain, - consuming_wallet: Wallet, - fingerprints_recipient: Recipient, - affordable_accounts: Vec, - ) -> Box, Error=PayableTransactionError>>; + fn get_web3_batch( + &self + ) -> Web3>; } diff --git a/node/src/blockchain/blockchain_interface/mod.rs b/node/src/blockchain/blockchain_interface/mod.rs index c2555f3c4..58c740bc5 100644 --- a/node/src/blockchain/blockchain_interface/mod.rs +++ b/node/src/blockchain/blockchain_interface/mod.rs @@ -4,17 +4,19 @@ pub mod blockchain_interface_web3; pub mod data_structures; pub mod lower_level_interface; +use actix::Recipient; use ethereum_types::H256; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; -use crate::blockchain::blockchain_interface::data_structures::errors::{ - BlockchainAgentBuildError, BlockchainError, -}; -use crate::blockchain::blockchain_interface::data_structures::RetrievedBlockchainTransactions; +use crate::blockchain::blockchain_interface::data_structures::errors::{BlockchainAgentBuildError, BlockchainError, PayableTransactionError}; +use crate::blockchain::blockchain_interface::data_structures::{ProcessedPayableFallible, RetrievedBlockchainTransactions}; use crate::blockchain::blockchain_interface::lower_level_interface::LowBlockchainInt; use crate::sub_lib::wallet::Wallet; use futures::Future; use masq_lib::blockchains::chains::Chain; use web3::types::{Address, BlockNumber}; +use masq_lib::logger::Logger; +use crate::accountant::db_access_objects::payable_dao::PayableAccount; +use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; pub trait BlockchainInterface { @@ -44,5 +46,14 @@ pub trait BlockchainInterface { transaction_hashes: Vec, ) -> Box, Error=BlockchainError>>; + fn submit_payables_in_batch( + &self, + logger: Logger, + chain: Chain, + consuming_wallet: Wallet, + fingerprints_recipient: Recipient, + affordable_accounts: Vec, + ) -> Box, Error=PayableTransactionError>>; + as_any_ref_in_trait!(); } diff --git a/node/src/blockchain/test_utils.rs b/node/src/blockchain/test_utils.rs index 1f4229d64..b2dfcfa8b 100644 --- a/node/src/blockchain/test_utils.rs +++ b/node/src/blockchain/test_utils.rs @@ -6,10 +6,8 @@ use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockch use crate::blockchain::blockchain_interface::blockchain_interface_web3::{ BlockchainInterfaceWeb3, REQUESTS_IN_PARALLEL, }; -use crate::blockchain::blockchain_interface::data_structures::errors::{ - BlockchainAgentBuildError, BlockchainError, -}; -use crate::blockchain::blockchain_interface::data_structures::RetrievedBlockchainTransactions; +use crate::blockchain::blockchain_interface::data_structures::errors::{BlockchainAgentBuildError, BlockchainError, PayableTransactionError}; +use crate::blockchain::blockchain_interface::data_structures::{ProcessedPayableFallible, RetrievedBlockchainTransactions}; use crate::blockchain::blockchain_interface::lower_level_interface::LowBlockchainInt; use crate::blockchain::blockchain_interface::BlockchainInterface; use crate::set_arbitrary_id_stamp_in_mock_impl; @@ -29,10 +27,14 @@ use std::cell::RefCell; use std::fmt::Debug; use std::net::Ipv4Addr; use std::sync::{Arc, Mutex}; +use actix::Recipient; use web3::transports::{EventLoopHandle, Http}; use web3::types::{ Address, BlockNumber, Index, Log, SignedTransaction, TransactionReceipt, H2048, U256, }; +use masq_lib::logger::Logger; +use crate::accountant::db_access_objects::payable_dao::PayableAccount; +use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; lazy_static! { @@ -240,6 +242,10 @@ impl BlockchainInterface for BlockchainInterfaceMock { fn process_transaction_receipts(&self, _transaction_hashes: Vec) -> Box, Error=BlockchainError>> { unimplemented!("not needed so far") } + + fn submit_payables_in_batch(&self, logger: Logger, chain: Chain, consuming_wallet: Wallet, fingerprints_recipient: Recipient, affordable_accounts: Vec) -> Box, Error=PayableTransactionError>> { + unimplemented!("not needed so far") + } } impl BlockchainInterfaceMock { From fac493618f486f02ef60267cc55f72832cfb2837 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Tue, 12 Nov 2024 21:25:20 +1300 Subject: [PATCH 20/56] GH-744: removed test: blockchain_bridge_can_return_report_transaction_receipts_with_an_empty_vector --- node/src/blockchain/blockchain_bridge.rs | 42 ------------------------ 1 file changed, 42 deletions(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 71b75f99b..e6d108884 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -1421,48 +1421,6 @@ mod tests { TestLogHandler::new().exists_log_containing("WARN: BlockchainBridge: Aborting scanning; 1 transactions succeed and 3 transactions failed"); } - #[test] - fn blockchain_bridge_can_return_report_transaction_receipts_with_an_empty_vector() { - let (accountant, _, accountant_recording) = make_recorder(); - let recipient = accountant.start().recipient(); - let transaction_receipt_response = ReceiptResponseBuilder::default().build(); - let port = find_free_port(); - let _blockchain_client_server = MBCSBuilder::new(port) - .begin_batch() - .raw_response(transaction_receipt_response) - .end_batch() - .start(); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); - let mut subject = BlockchainBridge::new( - Box::new(blockchain_interface), - Box::new(PersistentConfigurationMock::default()), - false, - ); - subject - .pending_payable_confirmation - .report_transaction_receipts_sub_opt = Some(recipient); - let msg = RequestTransactionReceipts { - pending_payable: vec![], - response_skeleton_opt: None, - }; - let system = System::new( - "blockchain_bridge_can_return_report_transaction_receipts_with_an_empty_vector", - ); - - let _ = subject.handle_request_transaction_receipts(msg).wait(); - - System::current().stop(); - system.run(); - let recording = accountant_recording.lock().unwrap(); - assert_eq!( - recording.get_record::(0), - &ReportTransactionReceipts { - fingerprints_with_receipts: vec![], - response_skeleton_opt: None - } - ) - } - #[test] fn handle_request_transaction_receipts_short_circuits_if_submit_batch_fails() { init_test_logging(); From c5ddb575e47a897dfbdc7973edabb8364739bac7 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Thu, 14 Nov 2024 00:08:57 +1300 Subject: [PATCH 21/56] GH-744: Fixed a few more URGENCY comments --- node/src/blockchain/blockchain_bridge.rs | 6 +- node/src/neighborhood/mod.rs | 154 +++++++++++------------ 2 files changed, 74 insertions(+), 86 deletions(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index e6d108884..5c354c3f5 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -434,10 +434,6 @@ impl BlockchainBridge { let scan_error_subs_opt = self.scan_error_subs_opt.clone(); let future = handler(self, msg).map_err(move |e| { warning!(logger, "{}", e); - // TODO: This ScanError needs to be removed, And added into OutboundPaymentsInstructions & QualifiedPayablesMessage - // There are certain cases when its a partial error and we are triggering errors that will send ScanError messages. - // In case we dont send this message at all and instead we use the above two mentioned messages to send total failure and partial failure. - // BlockchainBridge wont segregate the messages and Accountant can later on deal with success, partial failures and total failures accordingly. scan_error_subs_opt .as_ref() .expect("Accountant not bound") @@ -1770,6 +1766,8 @@ mod tests { let _ = subject.handle_retrieve_transactions(retrieve_transactions); } + + // TODO: GH-555: Remove system_stop_conditions while also confirming the ScanError msg wasn't sent. #[test] fn handle_scan_future_handles_success() { let (accountant, _, accountant_recording_arc) = make_recorder(); diff --git a/node/src/neighborhood/mod.rs b/node/src/neighborhood/mod.rs index c229bb10b..1444c8534 100644 --- a/node/src/neighborhood/mod.rs +++ b/node/src/neighborhood/mod.rs @@ -846,13 +846,13 @@ impl Neighborhood { { Ok(_) => info!(self.logger, "Persisted neighbor changes for next run"), Err(PersistentConfigError::DatabaseError(msg)) - if &msg == "database is locked" => - { - warning! ( + if &msg == "database is locked" => + { + warning!( self.logger, "Could not persist immediate-neighbor changes: database locked - skipping" ) - } + } Err(e) => error!( self.logger, "Could not persist immediate-neighbor changes: {:?}", e @@ -975,7 +975,7 @@ impl Neighborhood { None, None, ) - .expect("route creation error") + .expect("route creation error") } fn zero_hop_route_response(&mut self) -> RouteQueryResponse { @@ -994,7 +994,7 @@ impl Neighborhood { return_route_id, None, ) - .expect("Couldn't create route"); + .expect("Couldn't create route"); RouteQueryResponse { route, expected_services: ExpectedServices::RoundTrip( @@ -1076,7 +1076,7 @@ impl Neighborhood { return_route_id, Some(self.chain.rec().contract), ) - .expect("Internal error: bad route"), + .expect("Internal error: bad route"), expected_services: ExpectedServices::RoundTrip( expected_request_services, expected_response_services, @@ -1145,15 +1145,15 @@ impl Neighborhood { } else { match (originator_key, exit_key) { (Some(originator_key), Some(exit_key)) - if route_segment_key == originator_key - || route_segment_key == exit_key => - { - Ok(ExpectedService::Exit( - route_segment_key.clone(), - node.earning_wallet(), - *node.rate_pack(), - )) - } + if route_segment_key == originator_key + || route_segment_key == exit_key => + { + Ok(ExpectedService::Exit( + route_segment_key.clone(), + node.earning_wallet(), + *node.rate_pack(), + )) + } (Some(_), Some(_)) => Ok(ExpectedService::Routing( route_segment_key.clone(), node.earning_wallet(), @@ -1318,10 +1318,10 @@ impl Neighborhood { if self.route_length_qualifies(hops_remaining) && self.last_key_qualifies(previous_node, target_opt) && self.validate_last_node_not_too_close_to_first_node( - prefix.len(), - *first_node_key, - previous_node.public_key(), - ) + prefix.len(), + *first_node_key, + previous_node.public_key(), + ) { if undesirability < *minimum_undesirability { *minimum_undesirability = undesirability; @@ -1775,7 +1775,7 @@ mod tests { cryptde, "masq://eth-ropsten:AQIDBA@1.2.3.4:1234", )) - .unwrap()]), + .unwrap()]), min_hops: MIN_HOPS_FOR_TEST, }, earning_wallet.clone(), @@ -1800,7 +1800,7 @@ mod tests { cryptde, "masq://eth-mainnet:AQIDBA@1.2.3.4:1234", )) - .unwrap()]), + .unwrap()]), min_hops: MIN_HOPS_FOR_TEST, }, earning_wallet.clone(), @@ -2008,8 +2008,7 @@ mod tests { } #[test] - fn neighborhood_logs_with_trace_if_it_receives_a_cpm_with_a_pass_target_that_is_a_part_of_a_different_connection_progress( - ) { + fn neighborhood_logs_with_trace_if_it_receives_a_cpm_with_a_pass_target_that_is_a_part_of_a_different_connection_progress() { init_test_logging(); let peer_1 = make_ip(1); let peer_2 = make_ip(2); @@ -2159,8 +2158,7 @@ mod tests { } #[test] - pub fn neighborhood_logs_with_trace_if_it_receives_ask_about_debut_message_from_unknown_descriptor( - ) { + pub fn neighborhood_logs_with_trace_if_it_receives_ask_about_debut_message_from_unknown_descriptor() { init_test_logging(); let (_known_ip, known_desc) = make_node(1); let (unknown_ip, unknown_desc) = make_node(2); @@ -2370,7 +2368,7 @@ mod tests { body: UiConnectionChangeBroadcast { stage: UiConnectionStage::ConnectedToNeighbor } - .tmb(0) + .tmb(0) }) ); } @@ -2429,7 +2427,7 @@ mod tests { body: UiConnectionChangeBroadcast { stage: UiConnectionStage::ConnectedToNeighbor } - .tmb(0) + .tmb(0) }) ); } @@ -2479,8 +2477,7 @@ mod tests { } #[test] - pub fn progress_in_the_stage_of_overall_connection_status_made_by_one_cpm_is_not_overriden_by_the_other( - ) { + pub fn progress_in_the_stage_of_overall_connection_status_made_by_one_cpm_is_not_overriden_by_the_other() { let peer_1 = make_ip(1); let peer_2 = make_ip(2); let initial_node_descriptors = @@ -2599,9 +2596,9 @@ mod tests { system.run(); // If this never halts, it's because the Neighborhood isn't properly killing its actor let tlh = TestLogHandler::new(); - tlh.exists_log_containing ("WARN: Neighborhood: Node at 3.4.5.6 refused Debut: No neighbors for Introduction or Pass"); - tlh.exists_log_containing ("WARN: Neighborhood: Node at 4.5.6.7 refused Debut: Node owner manually rejected your Debut"); - tlh.exists_log_containing ("ERROR: Neighborhood: None of the Nodes listed in the --neighbors parameter could accept your Debut; shutting down"); + tlh.exists_log_containing("WARN: Neighborhood: Node at 3.4.5.6 refused Debut: No neighbors for Introduction or Pass"); + tlh.exists_log_containing("WARN: Neighborhood: Node at 4.5.6.7 refused Debut: Node owner manually rejected your Debut"); + tlh.exists_log_containing("ERROR: Neighborhood: None of the Nodes listed in the --neighbors parameter could accept your Debut; shutting down"); } #[test] @@ -2621,8 +2618,7 @@ mod tests { } #[test] - fn route_query_responds_with_none_when_asked_for_two_hop_round_trip_route_without_consuming_wallet( - ) { + fn route_query_responds_with_none_when_asked_for_two_hop_round_trip_route_without_consuming_wallet() { let system = System::new("route_query_responds_with_none_when_asked_for_two_hop_round_trip_route_without_consuming_wallet"); let subject = make_standard_subject(); let addr: Addr = subject.start(); @@ -2721,7 +2717,7 @@ mod tests { 0, None, ) - .unwrap(), + .unwrap(), expected_services: ExpectedServices::RoundTrip( vec![ ExpectedService::Nothing, @@ -2746,8 +2742,7 @@ mod tests { } #[test] - fn route_query_responds_with_none_when_asked_for_two_hop_one_way_route_without_consuming_wallet( - ) { + fn route_query_responds_with_none_when_asked_for_two_hop_one_way_route_without_consuming_wallet() { let system = System::new("route_query_responds_with_none_when_asked_for_two_hop_one_way_route_without_consuming_wallet"); let mut subject = make_standard_subject(); subject.min_hops = Hops::TwoHops; @@ -2794,7 +2789,7 @@ mod tests { 0, None, ) - .unwrap(), + .unwrap(), expected_services: ExpectedServices::RoundTrip( vec![ExpectedService::Nothing, ExpectedService::Nothing], vec![ExpectedService::Nothing, ExpectedService::Nothing], @@ -2885,7 +2880,7 @@ mod tests { 0, Some(contract_address), ) - .unwrap(), + .unwrap(), expected_services: ExpectedServices::RoundTrip( vec![ ExpectedService::Nothing, @@ -3119,7 +3114,7 @@ mod tests { body: UiConnectionChangeBroadcast { stage: UiConnectionStage::ConnectedToNeighbor } - .tmb(0), + .tmb(0), }) ); TestLogHandler::new().assert_logs_contain_in_order(vec![ @@ -3421,7 +3416,7 @@ mod tests { assert_eq!( new_undesirability, 1_000_000 // existing undesirability - + rate_pack.routing_charge (1_000) as i64 // charge to route packet + + rate_pack.routing_charge(1_000) as i64 // charge to route packet ); } @@ -3444,7 +3439,7 @@ mod tests { assert_eq!( new_undesirability, 1_000_000 // existing undesirability - + rate_pack.exit_charge (1_000) as i64 // charge to exit request + + rate_pack.exit_charge(1_000) as i64 // charge to exit request ); } @@ -3472,8 +3467,8 @@ mod tests { assert_eq!( new_undesirability, 1_000_000 // existing undesirability - + rate_pack.exit_charge (1_000) as i64 // charge to exit request - + UNREACHABLE_HOST_PENALTY // because host is blacklisted + + rate_pack.exit_charge(1_000) as i64 // charge to exit request + + UNREACHABLE_HOST_PENALTY // because host is blacklisted ); TestLogHandler::new().exists_log_containing( "TRACE: Neighborhood: Node with PubKey 0x02030405 \ @@ -3521,8 +3516,8 @@ mod tests { let rate_pack = node_record.rate_pack(); assert_eq!( initial_undesirability, - rate_pack.exit_charge (1_000) as i64 // charge to exit response - + rate_pack.routing_charge (1_000) as i64 // charge to route response + rate_pack.exit_charge(1_000) as i64 // charge to exit response + + rate_pack.routing_charge(1_000) as i64 // charge to route response ); } @@ -3545,7 +3540,7 @@ mod tests { assert_eq!( new_undesirability, 1_000_000 // existing undesirability - + rate_pack.routing_charge (1_000) as i64 // charge to route response + + rate_pack.routing_charge(1_000) as i64 // charge to route response ); } @@ -3614,7 +3609,7 @@ mod tests { sub.try_send(RemoveNeighborMessage { public_key: removed_neighbor_inside.public_key().clone(), }) - .unwrap(); + .unwrap(); system.run(); }); @@ -3817,7 +3812,7 @@ mod tests { &CryptDENull::from(&public_key, TEST_DEFAULT_CHAIN), &package.payload, ) - .unwrap(); + .unwrap(); assert_eq!( payload, MessageType::GossipFailure(VersionedData::new( @@ -3961,8 +3956,7 @@ mod tests { } #[test] - fn neighborhood_ignores_gossip_if_it_receives_a_pass_target_which_is_a_part_of_a_different_connection_progress( - ) { + fn neighborhood_ignores_gossip_if_it_receives_a_pass_target_which_is_a_part_of_a_different_connection_progress() { init_test_logging(); let handle_params_arc = Arc::new(Mutex::new(vec![])); let gossip_acceptor = GossipAcceptorMock::new() @@ -4045,7 +4039,7 @@ mod tests { body: UiConnectionChangeBroadcast { stage: UiConnectionStage::RouteFound } - .tmb(0), + .tmb(0), } ); TestLogHandler::new().exists_log_containing(&format!( @@ -4242,8 +4236,7 @@ mod tests { } #[test] - fn neighborhood_does_not_update_past_neighbors_without_password_even_when_neighbor_list_changes( - ) { + fn neighborhood_does_not_update_past_neighbors_without_password_even_when_neighbor_list_changes() { let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A let old_neighbor = make_node_record(1111, true); let new_neighbor = make_node_record(2222, true); @@ -4431,7 +4424,7 @@ mod tests { full_neighbor.public_key(), &MessageType::Gossip(gossip.clone().into()), ) - .unwrap() + .unwrap() ), ( half_neighbor.public_key().clone(), @@ -4440,7 +4433,7 @@ mod tests { half_neighbor.public_key(), &MessageType::Gossip(gossip.into()), ) - .unwrap() + .unwrap() ), ]), digest_set @@ -4451,14 +4444,14 @@ mod tests { "INFO: Neighborhood: Sending update Gossip about 0 Nodes to Node {}", full_neighbor.public_key() ) - .as_str(), + .as_str(), ); tlh.exists_log_containing( format!( "INFO: Neighborhood: Sending update Gossip about 0 Nodes to Node {}", half_neighbor.public_key() ) - .as_str(), + .as_str(), ); let key_as_str = format!("{}", main_cryptde().public_key()); tlh.exists_log_containing(&format!("Sent Gossip: digraph db {{ \"src\" [label=\"Gossip From:\\n{}\\n5.5.5.5\"]; \"dest\" [label=\"Gossip To:\\nAQIDBA\\n1.2.3.4\"]; \"src\" -> \"dest\" [arrowhead=empty]; }}", &key_as_str[..8])); @@ -4468,8 +4461,8 @@ mod tests { #[test] fn neighborhood_sends_no_gossip_when_target_does_not_exist() { let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A - // This is ungossippable not because of any attribute of its own, but because the - // GossipProducerMock is set to return None when ordered to target it. + // This is ungossippable not because of any attribute of its own, but because the + // GossipProducerMock is set to return None when ordered to target it. let ungossippable = make_node_record(1050, true); let mut subject = neighborhood_from_nodes(&subject_node, Some(&ungossippable)); subject @@ -4763,7 +4756,7 @@ mod tests { main_cryptde(), // Used to provide default cryptde "masq://eth-ropsten:AQIDBA@1.2.3.4:1234", )) - .unwrap(); + .unwrap(); let (hopper, _, hopper_recording) = make_recorder(); let mut subject = Neighborhood::new( cryptde, @@ -4853,7 +4846,7 @@ mod tests { assert_eq!(neighborhood.min_hops, min_hops_in_persistent_configuration); }), }) - .unwrap(); + .unwrap(); System::current().stop(); system.run(); } @@ -4959,7 +4952,7 @@ mod tests { addr.try_send(RemoveNeighborMessage { public_key: a.public_key().clone(), }) - .unwrap(); + .unwrap(); let three_hop_route_request = RouteQueryMessage { target_key_opt: Some(c.public_key().clone()), @@ -5021,7 +5014,7 @@ mod tests { }, recipient, }) - .unwrap(); + .unwrap(); system.run(); }); @@ -5067,7 +5060,7 @@ mod tests { }, earning_wallet.clone(), consuming_wallet.clone(), - "neighborhood_sends_node_query_response_with_none_when_key_query_matches_no_configured_data" + "neighborhood_sends_node_query_response_with_none_when_key_query_matches_no_configured_data", ), ); let addr: Addr = subject.start(); @@ -5084,7 +5077,7 @@ mod tests { }, recipient, }) - .unwrap(); + .unwrap(); system.run(); }); @@ -5129,7 +5122,7 @@ mod tests { }, earning_wallet.clone(), consuming_wallet.clone(), - "neighborhood_sends_node_query_response_with_result_when_key_query_matches_configured_data" + "neighborhood_sends_node_query_response_with_result_when_key_query_matches_configured_data", ), ); subject @@ -5145,7 +5138,7 @@ mod tests { context, recipient, }) - .unwrap(); + .unwrap(); system.run(); }); @@ -5164,8 +5157,7 @@ mod tests { } #[test] - fn neighborhood_sends_node_query_response_with_none_when_ip_address_query_matches_no_configured_data( - ) { + fn neighborhood_sends_node_query_response_with_none_when_ip_address_query_matches_no_configured_data() { let cryptde: &dyn CryptDE = main_cryptde(); let earning_wallet = make_wallet("earning"); let consuming_wallet = Some(make_paying_wallet(b"consuming")); @@ -5196,7 +5188,7 @@ mod tests { }, earning_wallet.clone(), consuming_wallet.clone(), - "neighborhood_sends_node_query_response_with_none_when_ip_address_query_matches_no_configured_data" + "neighborhood_sends_node_query_response_with_none_when_ip_address_query_matches_no_configured_data", ), ); let addr: Addr = subject.start(); @@ -5213,7 +5205,7 @@ mod tests { }, recipient, }) - .unwrap(); + .unwrap(); system.run(); }); @@ -5226,8 +5218,7 @@ mod tests { } #[test] - fn neighborhood_sends_node_query_response_with_result_when_ip_address_query_matches_configured_data( - ) { + fn neighborhood_sends_node_query_response_with_result_when_ip_address_query_matches_configured_data() { let cryptde: &dyn CryptDE = main_cryptde(); let (recorder, awaiter, recording_arc) = make_recorder(); let node_record = make_node_record(1234, true); @@ -5260,7 +5251,7 @@ mod tests { }, node_record.earning_wallet(), None, - "neighborhood_sends_node_query_response_with_result_when_ip_address_query_matches_configured_data" + "neighborhood_sends_node_query_response_with_result_when_ip_address_query_matches_configured_data", ); let mut subject = Neighborhood::new(cryptde, &config); subject @@ -5276,7 +5267,7 @@ mod tests { context, recipient, }) - .unwrap(); + .unwrap(); system.run(); }); @@ -5819,7 +5810,7 @@ mod tests { body: UiConnectionStatusResponse { stage: stage.into() } - .tmb(context_id), + .tmb(context_id), }) ) } @@ -5844,7 +5835,7 @@ mod tests { body: UiConnectionStatusResponse { stage: stage.into() } - .tmb(context_id), + .tmb(context_id), }) ) } @@ -5869,7 +5860,7 @@ mod tests { body: UiConnectionStatusResponse { stage: stage.into() } - .tmb(context_id), + .tmb(context_id), }) ) } @@ -5886,8 +5877,7 @@ mod tests { } #[test] - fn curate_past_neighbors_does_not_write_to_database_if_neighbors_are_same_but_order_has_changed( - ) { + fn curate_past_neighbors_does_not_write_to_database_if_neighbors_are_same_but_order_has_changed() { let mut subject = make_standard_subject(); // This mock is completely unprepared: any call to it should cause a panic let persistent_config = PersistentConfigurationMock::new(); From 237a53321de8a409d613fea8846fbb9581c126e0 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Thu, 14 Nov 2024 00:17:12 +1300 Subject: [PATCH 22/56] GH-744: cleanup & formatting --- node/src/accountant/mod.rs | 68 +++++----- node/src/accountant/scanners/mod.rs | 38 +++--- .../src/accountant/scanners/scanners_utils.rs | 8 +- node/src/blockchain/blockchain_bridge.rs | 55 ++++---- .../lower_level_interface_web3.rs | 41 +++--- .../blockchain_interface_web3/mod.rs | 79 ++++++----- .../lower_level_interface.rs | 30 ++--- .../blockchain/blockchain_interface/mod.rs | 8 +- node/src/blockchain/test_utils.rs | 21 ++- node/src/neighborhood/mod.rs | 126 ++++++++++-------- 10 files changed, 250 insertions(+), 224 deletions(-) diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index f7b0a5b6b..ac1689209 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -743,7 +743,7 @@ impl Accountant { stats_opt, query_results_opt, } - .tmb(context_id) + .tmb(context_id) } fn request_payable_accounts_by_specific_mode( @@ -1032,11 +1032,11 @@ pub fn checked_conversion>(num: T) -> S { politely_checked_conversion(num).unwrap_or_else(|msg| panic!("{}", msg)) } -pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { +pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { (T::from(gwei)).mul(T::from(WEIS_IN_GWEI as u32)) } -pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { +pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { checked_conversion::(wei.div(S::from(WEIS_IN_GWEI as u32))) } @@ -1364,7 +1364,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Receivables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1456,7 +1456,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Payables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1523,7 +1523,8 @@ mod tests { } #[test] - fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge() { + fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge( + ) { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1615,7 +1616,8 @@ mod tests { } #[test] - fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge() { + fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge( + ) { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1763,7 +1765,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1818,7 +1820,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; let second_message = first_message.clone(); let peer_actors = peer_actors_builder() @@ -2009,7 +2011,8 @@ mod tests { } #[test] - fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block() { + fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block( + ) { let more_money_received_params_arc = Arc::new(Mutex::new(vec![])); let commit_params_arc = Arc::new(Mutex::new(vec![])); let set_by_guest_transaction_params_arc = Arc::new(Mutex::new(vec![])); @@ -2708,7 +2711,7 @@ mod tests { addr.try_send(ScanForPayables { response_skeleton_opt: None, }) - .unwrap(); + .unwrap(); // We ignored the second ScanForPayables message because the first message meant a scan // was already in progress; now let's make it look like that scan has ended so that we @@ -2721,7 +2724,7 @@ mod tests { .mark_as_ended(&Logger::new("irrelevant")) }), }) - .unwrap(); + .unwrap(); addr.try_send(message_after.clone()).unwrap(); system.run(); let recording = blockchain_bridge_recording.lock().unwrap(); @@ -4030,7 +4033,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4114,7 +4117,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4177,7 +4180,7 @@ mod tests { }), query_results_opt: None } - .tmb(context_id) + .tmb(context_id) ) } @@ -4254,12 +4257,12 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 58, pending_payable_hash_opt: None - }, ]), + },]), receivable_opt: Some(vec![UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), age_s: extracted_receivable_ages[0], balance_gwei: 3_788_455 - }, ]) + },]) }), } ); @@ -4420,7 +4423,7 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 5, pending_payable_hash_opt: None - }, ]), + },]), receivable_opt: Some(vec![ UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), @@ -4609,7 +4612,8 @@ mod tests { expected = "Broken code: PayableAccount with less than 1 gwei passed through db query \ constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 8686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei() { + fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei( + ) { let payable_accounts_retrieved = vec![PayableAccount { wallet: make_wallet("abcd123"), balance_wei: 8_686_005, @@ -4645,7 +4649,8 @@ mod tests { expected = "Broken code: ReceivableAccount with balance between 1 and 0 gwei passed through \ db query constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 7686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei() { + fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei( + ) { let receivable_accounts_retrieved = vec![ReceivableAccount { wallet: make_wallet("abcd123"), balance_wei: 7_686_005, @@ -4884,10 +4889,11 @@ pub mod exportable_test_parts { } } - fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao() -> ShouldWeRunTheTest { + fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao( + ) -> ShouldWeRunTheTest { fn skip_down_to_first_line_saying_new_delinquencies( - previous: impl Iterator, - ) -> impl Iterator { + previous: impl Iterator, + ) -> impl Iterator { previous .skip_while(|line| { let adjusted_line: String = line @@ -4898,7 +4904,7 @@ pub mod exportable_test_parts { }) .skip(1) } - fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { + fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { fn yield_if_contains_semicolon(line: &str) -> Option { line.contains(';').then(|| line.to_string()) } @@ -4937,13 +4943,13 @@ pub mod exportable_test_parts { skip_down_to_first_line_saying_new_delinquencies( lines_with_cut_fn_trait_definition, ) - .take_while(|line| { - let adjusted_line: String = line - .chars() - .skip_while(|char| char.is_whitespace()) - .collect(); - !adjusted_line.starts_with("fn") - }); + .take_while(|line| { + let adjusted_line: String = line + .chars() + .skip_while(|char| char.is_whitespace()) + .collect(); + !adjusted_line.starts_with("fn") + }); assert_is_not_trait_definition(assumed_implemented_function_body) } fn user_defined_functions_detected(line_undivided_fn_body: &str) -> bool { diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index cf0f2f15f..2aa146cdc 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -18,7 +18,7 @@ use crate::accountant::scanners::scanners_utils::payable_scanner_utils::{ PayableThresholdsGaugeReal, PayableTransactingErrorEnum, PendingPayableMetadata, }; use crate::accountant::scanners::scanners_utils::pending_payable_scanner_utils::{ - elapsed_in_ms, handle_none_status, handle_status_with_failure, handle_status_with_success, + elapsed_in_ms, handle_status_with_failure, handle_status_with_success, PendingPayableScanReport, }; use crate::accountant::scanners::scanners_utils::receivable_scanner_utils::balance_and_age; @@ -51,7 +51,7 @@ use std::rc::Rc; use std::time::{Duration, SystemTime}; use time::format_description::parse; use time::OffsetDateTime; -use web3::types::{TransactionReceipt, H256}; +use web3::types::H256; use masq_lib::type_obfuscation::Obfuscated; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::{PreparedAdjustment, MultistagePayableScanner, SolvencySensitivePaymentInstructor}; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::msgs::{BlockchainAgentWithContextMessage, QualifiedPayablesMessage}; @@ -321,7 +321,7 @@ impl PayableScanner { logger: &Logger, ) -> Vec { fn pass_payables_and_drop_points( - qp_tp: impl Iterator, + qp_tp: impl Iterator, ) -> Vec { let (payables, _) = qp_tp.unzip::<_, _, Vec, Vec<_>>(); payables @@ -677,16 +677,12 @@ impl PendingPayableScanner { msg.fingerprints_with_receipts.into_iter().fold( scan_report, |scan_report_so_far, (receipt_result, fingerprint)| match receipt_result { - TransactionReceiptResult::Found(_receipt) => handle_status_with_success( - scan_report_so_far, - fingerprint, - logger, - ), - TransactionReceiptResult::TransactionFailed(_receipt) => handle_status_with_failure( - scan_report_so_far, - fingerprint, - logger, - ), + TransactionReceiptResult::Found(_receipt) => { + handle_status_with_success(scan_report_so_far, fingerprint, logger) + } + TransactionReceiptResult::TransactionFailed(_receipt) => { + handle_status_with_failure(scan_report_so_far, fingerprint, logger) + } TransactionReceiptResult::NotPresent => handle_none_receipt( scan_report_so_far, fingerprint, @@ -1635,9 +1631,9 @@ mod tests { (vals.intruder_for_hash_2, 5), (vals.common_hash_3, 6), ] - .iter() - .map(|(hash, _rowid)| *hash) - .collect::>(); + .iter() + .map(|(hash, _rowid)| *hash) + .collect::>(); let result = PayableScanner::is_symmetrical( pending_payables_ref_from_blockchain_bridge, @@ -2359,11 +2355,7 @@ mod tests { hash: H256, ) -> PendingPayableScanReport { init_test_logging(); - let tx_receipt = TransactionReceipt::default(); //status defaulted to None let when_sent = SystemTime::now().sub(Duration::from_secs(pending_payable_age_sec)); - let subject = PendingPayableScannerBuilder::new() - .when_pending_too_long_sec(when_pending_too_long_sec) - .build(); let fingerprint = PendingPayableFingerprint { rowid, timestamp: when_sent, @@ -2410,7 +2402,8 @@ mod tests { } #[test] - fn interpret_transaction_receipt_when_transaction_status_is_none_and_outside_waiting_interval() { + fn interpret_transaction_receipt_when_transaction_status_is_none_and_outside_waiting_interval() + { let test_name = "interpret_transaction_receipt_when_transaction_status_is_none_and_outside_waiting_interval"; let hash = make_tx_hash(0x237); let rowid = 466; @@ -2506,7 +2499,6 @@ mod tests { fn interpret_transaction_receipt_when_transaction_status_is_a_failure() { init_test_logging(); let test_name = "interpret_transaction_receipt_when_transaction_status_is_a_failure"; - let subject = PendingPayableScannerBuilder::new().build(); let mut tx_receipt = TransactionReceipt::default(); tx_receipt.status = Some(U64::from(0)); //failure let hash = make_tx_hash(0xd7); @@ -2527,7 +2519,7 @@ mod tests { result, PendingPayableScanReport { still_pending: vec![], - failures: vec![PendingPayableId::new(777777, hash, )], + failures: vec![PendingPayableId::new(777777, hash,)], confirmed: vec![] } ); diff --git a/node/src/accountant/scanners/scanners_utils.rs b/node/src/accountant/scanners/scanners_utils.rs index e730bba08..1876ca58d 100644 --- a/node/src/accountant/scanners/scanners_utils.rs +++ b/node/src/accountant/scanners/scanners_utils.rs @@ -156,10 +156,10 @@ pub mod payable_scanner_utils { add_pending_payable(acc, pending_payable) } ProcessedPayableFallible::Failed(RpcPayableFailure { - rpc_error, - recipient_wallet, - hash, - }) => { + rpc_error, + recipient_wallet, + hash, + }) => { warning!(logger, "Remote transaction failure: '{}' for payment to {} and transaction hash {:?}. \ Please check your blockchain service URL configuration.", rpc_error, recipient_wallet, hash ); diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 5c354c3f5..d9df66bfb 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -246,7 +246,7 @@ impl BlockchainBridge { fn handle_qualified_payable_msg( &mut self, incoming_message: QualifiedPayablesMessage, - ) -> Box> { + ) -> Box> { // TODO rewrite this into a batch call as soon as GH-629 gets into master let accountant_recipient = self.payable_payments_setup_subs_opt.clone(); return Box::new( @@ -271,7 +271,7 @@ impl BlockchainBridge { fn handle_outbound_payments_instructions( &mut self, msg: OutboundPaymentsInstructions, - ) -> Box> { + ) -> Box> { let skeleton_opt = msg.response_skeleton_opt; let sent_payable_subs = self .sent_payable_subs_opt @@ -306,7 +306,7 @@ impl BlockchainBridge { fn handle_retrieve_transactions( &mut self, msg: RetrieveTransactions, - ) -> Box> { + ) -> Box> { let start_block_nbr = match self.persistent_config.start_block() { Ok(sb) => sb, Err(e) => panic!("Cannot retrieve start block from database; payments to you may not be processed: {:?}", e) @@ -377,7 +377,7 @@ impl BlockchainBridge { fn handle_request_transaction_receipts( &mut self, msg: RequestTransactionReceipts, - ) -> Box> { + ) -> Box> { let accountant_recipient = self .pending_payable_confirmation .report_transaction_receipts_sub_opt @@ -426,7 +426,7 @@ impl BlockchainBridge { fn handle_scan_future(&mut self, handler: F, scan_type: ScanType, msg: M) where - F: FnOnce(&mut BlockchainBridge, M) -> Box>, + F: FnOnce(&mut BlockchainBridge, M) -> Box>, M: SkeletonOptHolder, { let skeleton_opt = msg.skeleton_opt(); @@ -452,19 +452,18 @@ impl BlockchainBridge { &self, agent: Box, affordable_accounts: Vec, - ) -> Box, Error=PayableTransactionError>> + ) -> Box, Error = PayableTransactionError>> { let new_fingerprints_recipient = self.new_fingerprints_recipient(); let logger = self.logger.clone(); let chain = self.blockchain_interface.get_chain(); - self.blockchain_interface - .submit_payables_in_batch( - logger, - chain, - agent.consuming_wallet().clone(), - new_fingerprints_recipient, - affordable_accounts, - ) + self.blockchain_interface.submit_payables_in_batch( + logger, + chain, + agent.consuming_wallet().clone(), + new_fingerprints_recipient, + affordable_accounts, + ) } fn new_fingerprints_recipient(&self) -> Recipient { @@ -597,7 +596,7 @@ mod tests { addr.try_send(BindMessage { peer_actors: peer_actors_builder().build(), }) - .unwrap(); + .unwrap(); System::current().stop(); system.run(); @@ -640,7 +639,8 @@ mod tests { } #[test] - fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant() { + fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant( + ) { let system = System::new( "qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant", ); @@ -807,7 +807,8 @@ mod tests { } #[test] - fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant() { + fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant( + ) { let system = System::new( "handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant", ); @@ -875,7 +876,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap() + .unwrap() })]), response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, @@ -891,7 +892,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -965,7 +966,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -1030,7 +1031,7 @@ mod tests { hash: H256::from_str( "cc73f3d5fe9fc3dac28b510ddeb157b0f8030b201e809014967396cdf365488a" ) - .unwrap() + .unwrap() }) ); assert_eq!( @@ -1040,7 +1041,7 @@ mod tests { hash: H256::from_str( "891d9ffa838aedc0bb2f6f7e9737128ce98bb33d07b4c8aa5645871e20d6cd13" ) - .unwrap() + .unwrap() }) ); let recording = accountant_recording.lock().unwrap(); @@ -1291,7 +1292,8 @@ mod tests { } #[test] - fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort() { + fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort( + ) { init_test_logging(); let port = find_free_port(); let block_number = U64::from(4545454); @@ -1698,7 +1700,9 @@ mod tests { blockchain_interface.logger = logger; let persistent_config = PersistentConfigurationMock::new() .start_block_result(Ok(6)) - .max_block_count_result(Err(PersistentConfigError::DatabaseError("my tummy hurts".to_string()))); + .max_block_count_result(Err(PersistentConfigError::DatabaseError( + "my tummy hurts".to_string(), + ))); let subject = BlockchainBridge::new( Box::new(blockchain_interface), Box::new(persistent_config), @@ -1766,7 +1770,6 @@ mod tests { let _ = subject.handle_retrieve_transactions(retrieve_transactions); } - // TODO: GH-555: Remove system_stop_conditions while also confirming the ScanError msg wasn't sent. #[test] fn handle_scan_future_handles_success() { @@ -2001,7 +2004,7 @@ pub mod exportable_test_parts { use crate::test_utils::unshared_test_utils::SubsFactoryTestAddrLeaker; impl SubsFactory - for SubsFactoryTestAddrLeaker + for SubsFactoryTestAddrLeaker { fn make(&self, addr: &Addr) -> BlockchainBridgeSubs { self.send_leaker_msg_and_return_meaningless_subs( diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index 205202ff5..134a15b10 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -1,8 +1,8 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. use crate::blockchain::blockchain_interface::blockchain_interface_web3::CONTRACT_ABI; -use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError::QueryFailed; use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError; +use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError::QueryFailed; use crate::blockchain::blockchain_interface::lower_level_interface::LowBlockchainInt; use ethereum_types::{H256, U256, U64}; use futures::Future; @@ -32,7 +32,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_fee_balance( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.web3 .eth() @@ -44,7 +44,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_service_fee_balance( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.contract .query("balanceOf", address, None, Options::default(), None) @@ -52,7 +52,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } - fn get_gas_price(&self) -> Box> { + fn get_gas_price(&self) -> Box> { Box::new( self.web3 .eth() @@ -61,7 +61,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } - fn get_block_number(&self) -> Box> { + fn get_block_number(&self) -> Box> { Box::new( self.web3 .eth() @@ -73,7 +73,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_id( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.web3 .eth() @@ -85,7 +85,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_receipt_in_batch( &self, hash_vec: Vec, - ) -> Box>, Error=BlockchainError>> { + ) -> Box>, Error = BlockchainError>> { let _ = hash_vec.into_iter().map(|hash| { self.web3_batch.eth().transaction_receipt(hash); }); @@ -93,7 +93,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { self.web3_batch .transport() .submit_batch() - .map_err(|e| QueryFailed(e.to_string())) + .map_err(|e| QueryFailed(e.to_string())), ) } @@ -105,7 +105,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_logs( &self, filter: Filter, - ) -> Box, Error=BlockchainError>> { + ) -> Box, Error = BlockchainError>> { Box::new( self.web3 .eth() @@ -136,18 +136,18 @@ impl LowBlockchainIntWeb3 { #[cfg(test)] mod tests { + use crate::blockchain::blockchain_interface::blockchain_interface_web3::TRANSACTION_LITERAL; + use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError::QueryFailed; use crate::blockchain::blockchain_interface::{BlockchainError, BlockchainInterface}; + use crate::blockchain::test_utils::make_blockchain_interface_web3; use crate::sub_lib::wallet::Wallet; - use masq_lib::utils::find_free_port; - use std::str::FromStr; + use crate::test_utils::make_wallet; use ethereum_types::{H256, U64}; use futures::Future; - use web3::types::{BlockNumber, Bytes, FilterBuilder, Log, U256}; use masq_lib::test_utils::mock_blockchain_client_server::MBCSBuilder; - use crate::blockchain::blockchain_interface::blockchain_interface_web3::TRANSACTION_LITERAL; - use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError::QueryFailed; - use crate::blockchain::test_utils::{make_blockchain_interface_web3}; - use crate::test_utils::make_wallet; + use masq_lib::utils::find_free_port; + use std::str::FromStr; + use web3::types::{BlockNumber, Bytes, FilterBuilder, Log, U256}; #[test] fn get_transaction_fee_balance_works() { @@ -167,7 +167,8 @@ mod tests { } #[test] - fn get_transaction_fee_balance_returns_an_error_for_unintelligible_response_to_requesting_eth_balance() { + fn get_transaction_fee_balance_returns_an_error_for_unintelligible_response_to_requesting_eth_balance( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0xFFFQ".to_string(), 0) @@ -449,7 +450,7 @@ mod tests { topics: vec![H256::from_str( "241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80" ) - .unwrap()], + .unwrap()], data: Bytes(vec![ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 51, 16, 114, 0, 88, 197, 31, 13, 228, 86, 226, 115, 198, 38, 205, 211 @@ -458,14 +459,14 @@ mod tests { H256::from_str( "7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70" ) - .unwrap() + .unwrap() ), block_number: Some(U64::from(6040059)), transaction_hash: Some( H256::from_str( "3dc91b98249fa9f2c5c37486a2427a3a7825be240c1c84961dfb3063d9c04d50" ) - .unwrap() + .unwrap() ), transaction_index: Some(U64::from(29)), log_index: Some(U256::from(29)), diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 41e3f3ae0..f245cade2 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -14,7 +14,6 @@ use masq_lib::blockchains::chains::Chain; use masq_lib::logger::Logger; use std::convert::{From, TryInto}; use std::fmt::Debug; -use std::ops::Deref; use actix::Recipient; use ethereum_types::U64; use web3::transports::{EventLoopHandle, Http}; @@ -94,7 +93,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { start_block: BlockNumber, fallback_start_block_number: u64, recipient: Address, - ) -> Box> { + ) -> Box> { let lower_level_interface = self.lower_interface(); let logger = self.logger.clone(); let contract_address = lower_level_interface.get_contract().address(); @@ -154,7 +153,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { &self, // TODO: Change wallet to address in the future consuming_wallet: Wallet, - ) -> Box, Error=BlockchainAgentBuildError>> { + ) -> Box, Error = BlockchainAgentBuildError>> { let wallet_address = consuming_wallet.address(); let gas_limit_const_part = self.gas_limit_const_part; // TODO: Would it be better to wrap these 4 calls into a single batch call? @@ -208,9 +207,13 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { ) } - fn process_transaction_receipts(&self, transaction_hashes: Vec) -> Box, Error=BlockchainError>> { + fn process_transaction_receipts( + &self, + transaction_hashes: Vec, + ) -> Box, Error = BlockchainError>> { Box::new( - self.lower_interface().get_transaction_receipt_in_batch(transaction_hashes) + self.lower_interface() + .get_transaction_receipt_in_batch(transaction_hashes) .map_err(|e| e) .and_then(move |batch_response| { Ok(batch_response @@ -218,20 +221,16 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { .map(|response| match response { Ok(result) => { match serde_json::from_value::(result) { - Ok(receipt) => { - match receipt.status { - None => { - TransactionReceiptResult::NotPresent - } - Some(status) => { - if status == U64::from(1) { - TransactionReceiptResult::Found(receipt) - } else { - TransactionReceiptResult::TransactionFailed(receipt) - } + Ok(receipt) => match receipt.status { + None => TransactionReceiptResult::NotPresent, + Some(status) => { + if status == U64::from(1) { + TransactionReceiptResult::Found(receipt) + } else { + TransactionReceiptResult::TransactionFailed(receipt) } } - } + }, Err(e) => { if e.to_string().contains("invalid type: null") { TransactionReceiptResult::NotPresent @@ -248,9 +247,19 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { ) } - fn submit_payables_in_batch(&self, logger: Logger, chain: Chain, consuming_wallet: Wallet, fingerprints_recipient: Recipient, affordable_accounts: Vec) -> Box, Error=PayableTransactionError>> { + fn submit_payables_in_batch( + &self, + logger: Logger, + chain: Chain, + consuming_wallet: Wallet, + fingerprints_recipient: Recipient, + affordable_accounts: Vec, + ) -> Box, Error = PayableTransactionError>> + { let web3_batch = self.lower_interface().get_web3_batch(); - let get_transaction_id = self.lower_interface().get_transaction_id(consuming_wallet.address()); + let get_transaction_id = self + .lower_interface() + .get_transaction_id(consuming_wallet.address()); // We are not relying on Database and fetching the values straight from the blockchain. // Modify according to the Payment adjusters new design let get_gas_price = self.lower_interface().get_gas_price(); @@ -384,7 +393,6 @@ impl BlockchainInterfaceWeb3 { mod tests { use super::*; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::agent_web3::WEB3_MAXIMAL_GAS_LIMIT_MARGIN; - use crate::blockchain::bip32::Bip32EncryptionKeyProvider; use crate::blockchain::blockchain_interface::blockchain_interface_web3::{ BlockchainInterfaceWeb3, CONTRACT_ABI, REQUESTS_IN_PARALLEL, TRANSACTION_LITERAL, TRANSFER_METHOD_ID, @@ -396,11 +404,13 @@ mod tests { RetrievedBlockchainTransactions, }; use crate::blockchain::blockchain_interface_utils::calculate_fallback_start_block_number; - use crate::blockchain::test_utils::{all_chains, make_blockchain_interface_web3, ReceiptResponseBuilder}; + use crate::blockchain::test_utils::{ + all_chains, make_blockchain_interface_web3, ReceiptResponseBuilder, + }; use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; use crate::test_utils::make_paying_wallet; - use crate::test_utils::{make_wallet, TestRawTransaction}; + use crate::test_utils::make_wallet; use ethsign_crypto::Keccak256; use futures::Future; use indoc::indoc; @@ -409,13 +419,10 @@ mod tests { use masq_lib::test_utils::mock_blockchain_client_server::MBCSBuilder; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use masq_lib::utils::find_free_port; - use serde_derive::Deserialize; use std::net::Ipv4Addr; use std::str::FromStr; use web3::transports::Http; - use web3::types::{BlockNumber, Bytes, TransactionParameters, H2048, H256, U256}; - use web3::Web3; - + use web3::types::{BlockNumber, H2048, H256, U256}; #[test] fn constants_are_correct() { @@ -619,7 +626,8 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned() { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -644,7 +652,8 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned() { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -666,7 +675,8 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number() { + fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x400", 1) @@ -677,7 +687,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let end_block_nbr = 1024u64; let subject = @@ -707,7 +717,8 @@ mod tests { } #[test] - fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one() { + fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("trash", 1) @@ -782,7 +793,7 @@ mod tests { ); let expected_fee_estimation = (3 * (BlockchainInterfaceWeb3::web3_gas_limit_const_part(chain) - + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) + + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) * expected_gas_price_wei) as u128; assert_eq!( result.estimated_transaction_fee_total(3), @@ -916,7 +927,9 @@ mod tests { let tx_hash_6 = H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0d") .unwrap(); - let tx_hash_vec = vec![tx_hash_1, tx_hash_2, tx_hash_3, tx_hash_4, tx_hash_5, tx_hash_6]; + let tx_hash_vec = vec![ + tx_hash_1, tx_hash_2, tx_hash_3, tx_hash_4, tx_hash_5, tx_hash_6, + ]; let block_hash = H256::from_str("6d0abccae617442c26104c2bc63d1bc05e1e002e555aec4ab62a46e826b18f18") .unwrap(); diff --git a/node/src/blockchain/blockchain_interface/lower_level_interface.rs b/node/src/blockchain/blockchain_interface/lower_level_interface.rs index a9fdf7e1e..a19b879ea 100644 --- a/node/src/blockchain/blockchain_interface/lower_level_interface.rs +++ b/node/src/blockchain/blockchain_interface/lower_level_interface.rs @@ -1,21 +1,13 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -use actix::Recipient; -use crate::blockchain::blockchain_interface::data_structures::errors::{BlockchainError, PayableTransactionError}; -use crate::sub_lib::wallet::Wallet; +use crate::blockchain::blockchain_interface::data_structures::errors::BlockchainError; use ethereum_types::{H256, U64}; use futures::Future; use serde_json::Value; use web3::contract::Contract; -use web3::{Error, Web3}; use web3::transports::{Batch, Http}; use web3::types::{Address, Filter, Log, U256}; -use masq_lib::blockchains::chains::Chain; -use masq_lib::logger::Logger; -use crate::accountant::db_access_objects::payable_dao::PayableAccount; -use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; -use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; -use crate::blockchain::blockchain_interface::data_structures::ProcessedPayableFallible; +use web3::{Error, Web3}; pub trait LowBlockchainInt { // TODO: GH-495 The data structures in this trait are not generic, will need associated_type_defaults to implement it. @@ -25,35 +17,33 @@ pub trait LowBlockchainInt { fn get_transaction_fee_balance( &self, address: Address, - ) -> Box>; + ) -> Box>; fn get_service_fee_balance( &self, address: Address, - ) -> Box>; + ) -> Box>; - fn get_gas_price(&self) -> Box>; + fn get_gas_price(&self) -> Box>; - fn get_block_number(&self) -> Box>; + fn get_block_number(&self) -> Box>; fn get_transaction_id( &self, address: Address, - ) -> Box>; + ) -> Box>; fn get_transaction_receipt_in_batch( &self, hash_vec: Vec, - ) -> Box>, Error=BlockchainError>>; + ) -> Box>, Error = BlockchainError>>; fn get_contract(&self) -> Contract; fn get_transaction_logs( &self, filter: Filter, - ) -> Box, Error=BlockchainError>>; + ) -> Box, Error = BlockchainError>>; - fn get_web3_batch( - &self - ) -> Web3>; + fn get_web3_batch(&self) -> Web3>; } diff --git a/node/src/blockchain/blockchain_interface/mod.rs b/node/src/blockchain/blockchain_interface/mod.rs index 58c740bc5..6873443bd 100644 --- a/node/src/blockchain/blockchain_interface/mod.rs +++ b/node/src/blockchain/blockchain_interface/mod.rs @@ -34,17 +34,17 @@ pub trait BlockchainInterface { start_block: BlockNumber, fallback_start_block_number: u64, recipient: Address, - ) -> Box>; + ) -> Box>; fn build_blockchain_agent( &self, consuming_wallet: Wallet, - ) -> Box, Error=BlockchainAgentBuildError>>; + ) -> Box, Error = BlockchainAgentBuildError>>; fn process_transaction_receipts( &self, transaction_hashes: Vec, - ) -> Box, Error=BlockchainError>>; + ) -> Box, Error = BlockchainError>>; fn submit_payables_in_batch( &self, @@ -53,7 +53,7 @@ pub trait BlockchainInterface { consuming_wallet: Wallet, fingerprints_recipient: Recipient, affordable_accounts: Vec, - ) -> Box, Error=PayableTransactionError>>; + ) -> Box, Error = PayableTransactionError>>; as_any_ref_in_trait!(); } diff --git a/node/src/blockchain/test_utils.rs b/node/src/blockchain/test_utils.rs index b2dfcfa8b..eed9c2b39 100644 --- a/node/src/blockchain/test_utils.rs +++ b/node/src/blockchain/test_utils.rs @@ -66,7 +66,7 @@ pub fn make_blockchain_interface_web3(port_opt: Option) -> BlockchainInterf &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); BlockchainInterfaceWeb3::new(transport, event_loop_handle, chain) } @@ -217,7 +217,7 @@ impl BlockchainInterface for BlockchainInterfaceMock { start_block: BlockNumber, fallback_start_block_number: u64, recipient: Address, - ) -> Box> { + ) -> Box> { self.retrieve_transactions_parameters.lock().unwrap().push(( start_block, fallback_start_block_number, @@ -231,7 +231,7 @@ impl BlockchainInterface for BlockchainInterfaceMock { fn build_blockchain_agent( &self, _consuming_wallet: Wallet, - ) -> Box, Error=BlockchainAgentBuildError>> { + ) -> Box, Error = BlockchainAgentBuildError>> { unimplemented!("not needed so far") } @@ -239,11 +239,22 @@ impl BlockchainInterface for BlockchainInterfaceMock { unimplemented!("not needed so far") } - fn process_transaction_receipts(&self, _transaction_hashes: Vec) -> Box, Error=BlockchainError>> { + fn process_transaction_receipts( + &self, + _transaction_hashes: Vec, + ) -> Box, Error = BlockchainError>> { unimplemented!("not needed so far") } - fn submit_payables_in_batch(&self, logger: Logger, chain: Chain, consuming_wallet: Wallet, fingerprints_recipient: Recipient, affordable_accounts: Vec) -> Box, Error=PayableTransactionError>> { + fn submit_payables_in_batch( + &self, + _logger: Logger, + _chain: Chain, + _consuming_wallet: Wallet, + _fingerprints_recipient: Recipient, + _affordable_accounts: Vec, + ) -> Box, Error = PayableTransactionError>> + { unimplemented!("not needed so far") } } diff --git a/node/src/neighborhood/mod.rs b/node/src/neighborhood/mod.rs index 1444c8534..cb98e53f3 100644 --- a/node/src/neighborhood/mod.rs +++ b/node/src/neighborhood/mod.rs @@ -846,13 +846,13 @@ impl Neighborhood { { Ok(_) => info!(self.logger, "Persisted neighbor changes for next run"), Err(PersistentConfigError::DatabaseError(msg)) - if &msg == "database is locked" => - { - warning!( + if &msg == "database is locked" => + { + warning!( self.logger, "Could not persist immediate-neighbor changes: database locked - skipping" ) - } + } Err(e) => error!( self.logger, "Could not persist immediate-neighbor changes: {:?}", e @@ -975,7 +975,7 @@ impl Neighborhood { None, None, ) - .expect("route creation error") + .expect("route creation error") } fn zero_hop_route_response(&mut self) -> RouteQueryResponse { @@ -994,7 +994,7 @@ impl Neighborhood { return_route_id, None, ) - .expect("Couldn't create route"); + .expect("Couldn't create route"); RouteQueryResponse { route, expected_services: ExpectedServices::RoundTrip( @@ -1076,7 +1076,7 @@ impl Neighborhood { return_route_id, Some(self.chain.rec().contract), ) - .expect("Internal error: bad route"), + .expect("Internal error: bad route"), expected_services: ExpectedServices::RoundTrip( expected_request_services, expected_response_services, @@ -1145,15 +1145,15 @@ impl Neighborhood { } else { match (originator_key, exit_key) { (Some(originator_key), Some(exit_key)) - if route_segment_key == originator_key - || route_segment_key == exit_key => - { - Ok(ExpectedService::Exit( - route_segment_key.clone(), - node.earning_wallet(), - *node.rate_pack(), - )) - } + if route_segment_key == originator_key + || route_segment_key == exit_key => + { + Ok(ExpectedService::Exit( + route_segment_key.clone(), + node.earning_wallet(), + *node.rate_pack(), + )) + } (Some(_), Some(_)) => Ok(ExpectedService::Routing( route_segment_key.clone(), node.earning_wallet(), @@ -1318,10 +1318,10 @@ impl Neighborhood { if self.route_length_qualifies(hops_remaining) && self.last_key_qualifies(previous_node, target_opt) && self.validate_last_node_not_too_close_to_first_node( - prefix.len(), - *first_node_key, - previous_node.public_key(), - ) + prefix.len(), + *first_node_key, + previous_node.public_key(), + ) { if undesirability < *minimum_undesirability { *minimum_undesirability = undesirability; @@ -1775,7 +1775,7 @@ mod tests { cryptde, "masq://eth-ropsten:AQIDBA@1.2.3.4:1234", )) - .unwrap()]), + .unwrap()]), min_hops: MIN_HOPS_FOR_TEST, }, earning_wallet.clone(), @@ -1800,7 +1800,7 @@ mod tests { cryptde, "masq://eth-mainnet:AQIDBA@1.2.3.4:1234", )) - .unwrap()]), + .unwrap()]), min_hops: MIN_HOPS_FOR_TEST, }, earning_wallet.clone(), @@ -2008,7 +2008,8 @@ mod tests { } #[test] - fn neighborhood_logs_with_trace_if_it_receives_a_cpm_with_a_pass_target_that_is_a_part_of_a_different_connection_progress() { + fn neighborhood_logs_with_trace_if_it_receives_a_cpm_with_a_pass_target_that_is_a_part_of_a_different_connection_progress( + ) { init_test_logging(); let peer_1 = make_ip(1); let peer_2 = make_ip(2); @@ -2158,7 +2159,8 @@ mod tests { } #[test] - pub fn neighborhood_logs_with_trace_if_it_receives_ask_about_debut_message_from_unknown_descriptor() { + pub fn neighborhood_logs_with_trace_if_it_receives_ask_about_debut_message_from_unknown_descriptor( + ) { init_test_logging(); let (_known_ip, known_desc) = make_node(1); let (unknown_ip, unknown_desc) = make_node(2); @@ -2368,7 +2370,7 @@ mod tests { body: UiConnectionChangeBroadcast { stage: UiConnectionStage::ConnectedToNeighbor } - .tmb(0) + .tmb(0) }) ); } @@ -2427,7 +2429,7 @@ mod tests { body: UiConnectionChangeBroadcast { stage: UiConnectionStage::ConnectedToNeighbor } - .tmb(0) + .tmb(0) }) ); } @@ -2477,7 +2479,8 @@ mod tests { } #[test] - pub fn progress_in_the_stage_of_overall_connection_status_made_by_one_cpm_is_not_overriden_by_the_other() { + pub fn progress_in_the_stage_of_overall_connection_status_made_by_one_cpm_is_not_overriden_by_the_other( + ) { let peer_1 = make_ip(1); let peer_2 = make_ip(2); let initial_node_descriptors = @@ -2618,7 +2621,8 @@ mod tests { } #[test] - fn route_query_responds_with_none_when_asked_for_two_hop_round_trip_route_without_consuming_wallet() { + fn route_query_responds_with_none_when_asked_for_two_hop_round_trip_route_without_consuming_wallet( + ) { let system = System::new("route_query_responds_with_none_when_asked_for_two_hop_round_trip_route_without_consuming_wallet"); let subject = make_standard_subject(); let addr: Addr = subject.start(); @@ -2717,7 +2721,7 @@ mod tests { 0, None, ) - .unwrap(), + .unwrap(), expected_services: ExpectedServices::RoundTrip( vec![ ExpectedService::Nothing, @@ -2742,7 +2746,8 @@ mod tests { } #[test] - fn route_query_responds_with_none_when_asked_for_two_hop_one_way_route_without_consuming_wallet() { + fn route_query_responds_with_none_when_asked_for_two_hop_one_way_route_without_consuming_wallet( + ) { let system = System::new("route_query_responds_with_none_when_asked_for_two_hop_one_way_route_without_consuming_wallet"); let mut subject = make_standard_subject(); subject.min_hops = Hops::TwoHops; @@ -2789,7 +2794,7 @@ mod tests { 0, None, ) - .unwrap(), + .unwrap(), expected_services: ExpectedServices::RoundTrip( vec![ExpectedService::Nothing, ExpectedService::Nothing], vec![ExpectedService::Nothing, ExpectedService::Nothing], @@ -2880,7 +2885,7 @@ mod tests { 0, Some(contract_address), ) - .unwrap(), + .unwrap(), expected_services: ExpectedServices::RoundTrip( vec![ ExpectedService::Nothing, @@ -3114,7 +3119,7 @@ mod tests { body: UiConnectionChangeBroadcast { stage: UiConnectionStage::ConnectedToNeighbor } - .tmb(0), + .tmb(0), }) ); TestLogHandler::new().assert_logs_contain_in_order(vec![ @@ -3609,7 +3614,7 @@ mod tests { sub.try_send(RemoveNeighborMessage { public_key: removed_neighbor_inside.public_key().clone(), }) - .unwrap(); + .unwrap(); system.run(); }); @@ -3812,7 +3817,7 @@ mod tests { &CryptDENull::from(&public_key, TEST_DEFAULT_CHAIN), &package.payload, ) - .unwrap(); + .unwrap(); assert_eq!( payload, MessageType::GossipFailure(VersionedData::new( @@ -3956,7 +3961,8 @@ mod tests { } #[test] - fn neighborhood_ignores_gossip_if_it_receives_a_pass_target_which_is_a_part_of_a_different_connection_progress() { + fn neighborhood_ignores_gossip_if_it_receives_a_pass_target_which_is_a_part_of_a_different_connection_progress( + ) { init_test_logging(); let handle_params_arc = Arc::new(Mutex::new(vec![])); let gossip_acceptor = GossipAcceptorMock::new() @@ -4039,7 +4045,7 @@ mod tests { body: UiConnectionChangeBroadcast { stage: UiConnectionStage::RouteFound } - .tmb(0), + .tmb(0), } ); TestLogHandler::new().exists_log_containing(&format!( @@ -4236,7 +4242,8 @@ mod tests { } #[test] - fn neighborhood_does_not_update_past_neighbors_without_password_even_when_neighbor_list_changes() { + fn neighborhood_does_not_update_past_neighbors_without_password_even_when_neighbor_list_changes( + ) { let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A let old_neighbor = make_node_record(1111, true); let new_neighbor = make_node_record(2222, true); @@ -4424,7 +4431,7 @@ mod tests { full_neighbor.public_key(), &MessageType::Gossip(gossip.clone().into()), ) - .unwrap() + .unwrap() ), ( half_neighbor.public_key().clone(), @@ -4433,7 +4440,7 @@ mod tests { half_neighbor.public_key(), &MessageType::Gossip(gossip.into()), ) - .unwrap() + .unwrap() ), ]), digest_set @@ -4444,14 +4451,14 @@ mod tests { "INFO: Neighborhood: Sending update Gossip about 0 Nodes to Node {}", full_neighbor.public_key() ) - .as_str(), + .as_str(), ); tlh.exists_log_containing( format!( "INFO: Neighborhood: Sending update Gossip about 0 Nodes to Node {}", half_neighbor.public_key() ) - .as_str(), + .as_str(), ); let key_as_str = format!("{}", main_cryptde().public_key()); tlh.exists_log_containing(&format!("Sent Gossip: digraph db {{ \"src\" [label=\"Gossip From:\\n{}\\n5.5.5.5\"]; \"dest\" [label=\"Gossip To:\\nAQIDBA\\n1.2.3.4\"]; \"src\" -> \"dest\" [arrowhead=empty]; }}", &key_as_str[..8])); @@ -4461,8 +4468,8 @@ mod tests { #[test] fn neighborhood_sends_no_gossip_when_target_does_not_exist() { let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A - // This is ungossippable not because of any attribute of its own, but because the - // GossipProducerMock is set to return None when ordered to target it. + // This is ungossippable not because of any attribute of its own, but because the + // GossipProducerMock is set to return None when ordered to target it. let ungossippable = make_node_record(1050, true); let mut subject = neighborhood_from_nodes(&subject_node, Some(&ungossippable)); subject @@ -4756,7 +4763,7 @@ mod tests { main_cryptde(), // Used to provide default cryptde "masq://eth-ropsten:AQIDBA@1.2.3.4:1234", )) - .unwrap(); + .unwrap(); let (hopper, _, hopper_recording) = make_recorder(); let mut subject = Neighborhood::new( cryptde, @@ -4846,7 +4853,7 @@ mod tests { assert_eq!(neighborhood.min_hops, min_hops_in_persistent_configuration); }), }) - .unwrap(); + .unwrap(); System::current().stop(); system.run(); } @@ -4952,7 +4959,7 @@ mod tests { addr.try_send(RemoveNeighborMessage { public_key: a.public_key().clone(), }) - .unwrap(); + .unwrap(); let three_hop_route_request = RouteQueryMessage { target_key_opt: Some(c.public_key().clone()), @@ -5014,7 +5021,7 @@ mod tests { }, recipient, }) - .unwrap(); + .unwrap(); system.run(); }); @@ -5077,7 +5084,7 @@ mod tests { }, recipient, }) - .unwrap(); + .unwrap(); system.run(); }); @@ -5138,7 +5145,7 @@ mod tests { context, recipient, }) - .unwrap(); + .unwrap(); system.run(); }); @@ -5157,7 +5164,8 @@ mod tests { } #[test] - fn neighborhood_sends_node_query_response_with_none_when_ip_address_query_matches_no_configured_data() { + fn neighborhood_sends_node_query_response_with_none_when_ip_address_query_matches_no_configured_data( + ) { let cryptde: &dyn CryptDE = main_cryptde(); let earning_wallet = make_wallet("earning"); let consuming_wallet = Some(make_paying_wallet(b"consuming")); @@ -5205,7 +5213,7 @@ mod tests { }, recipient, }) - .unwrap(); + .unwrap(); system.run(); }); @@ -5218,7 +5226,8 @@ mod tests { } #[test] - fn neighborhood_sends_node_query_response_with_result_when_ip_address_query_matches_configured_data() { + fn neighborhood_sends_node_query_response_with_result_when_ip_address_query_matches_configured_data( + ) { let cryptde: &dyn CryptDE = main_cryptde(); let (recorder, awaiter, recording_arc) = make_recorder(); let node_record = make_node_record(1234, true); @@ -5267,7 +5276,7 @@ mod tests { context, recipient, }) - .unwrap(); + .unwrap(); system.run(); }); @@ -5810,7 +5819,7 @@ mod tests { body: UiConnectionStatusResponse { stage: stage.into() } - .tmb(context_id), + .tmb(context_id), }) ) } @@ -5835,7 +5844,7 @@ mod tests { body: UiConnectionStatusResponse { stage: stage.into() } - .tmb(context_id), + .tmb(context_id), }) ) } @@ -5860,7 +5869,7 @@ mod tests { body: UiConnectionStatusResponse { stage: stage.into() } - .tmb(context_id), + .tmb(context_id), }) ) } @@ -5877,7 +5886,8 @@ mod tests { } #[test] - fn curate_past_neighbors_does_not_write_to_database_if_neighbors_are_same_but_order_has_changed() { + fn curate_past_neighbors_does_not_write_to_database_if_neighbors_are_same_but_order_has_changed( + ) { let mut subject = make_standard_subject(); // This mock is completely unprepared: any call to it should cause a panic let persistent_config = PersistentConfigurationMock::new(); From 1be26426745f3e70add586ea2c5a83f7d9eaef5a Mon Sep 17 00:00:00 2001 From: utkarshg6 Date: Fri, 15 Nov 2024 12:58:52 +0530 Subject: [PATCH 23/56] GH-744: add some TODOs as discussed on Wed and Thu --- node/src/blockchain/blockchain_bridge.rs | 1 + .../blockchain_interface_web3/lower_level_interface_web3.rs | 4 ++-- .../blockchain_interface/blockchain_interface_web3/mod.rs | 1 + node/src/sub_lib/wallet.rs | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index d9df66bfb..038b8b1eb 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -412,6 +412,7 @@ impl BlockchainBridge { response_skeleton_opt: msg.response_skeleton_opt, }) .expect("Accountant is dead"); + // TODO: GH-744: Let's log it, instead of triggering an error if length != transactions_found { return Err(format!( "Aborting scanning; {} transactions succeed and {} transactions failed", diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index 134a15b10..b843c3216 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -17,8 +17,8 @@ use web3::{Error, Web3}; pub enum TransactionReceiptResult { NotPresent, Found(TransactionReceipt), - TransactionFailed(TransactionReceipt), - Error(String), + TransactionFailed(TransactionReceipt), // RemoteFailure + Error(String), // LocalFailure } pub struct LowBlockchainIntWeb3 { diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index f245cade2..088d909e0 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -164,6 +164,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { let get_service_fee_balance = self .lower_interface() .get_service_fee_balance(wallet_address); + // TODO: GH-744: Remove it from submit_batch call or from here, it's a duplicate let get_transaction_id = self.lower_interface().get_transaction_id(wallet_address); Box::new( diff --git a/node/src/sub_lib/wallet.rs b/node/src/sub_lib/wallet.rs index feb0667ec..4663e4938 100644 --- a/node/src/sub_lib/wallet.rs +++ b/node/src/sub_lib/wallet.rs @@ -128,7 +128,7 @@ impl Wallet { WalletKind::Address(address) => H160(address.0), WalletKind::PublicKey(public) => H160(*public.address()), WalletKind::SecretKey(key_provider) => key_provider.address(), - WalletKind::Uninitialized => panic!("No address for an uninitialized wallet!"), + WalletKind::Uninitialized => panic!("No address for an uninitialized wallet!"), // TODO: If we can get rid of it, it'll be awesome! } } From 8d22c61a5315b27e17ad974c57d9fe7c550d115b Mon Sep 17 00:00:00 2001 From: Syther007 Date: Fri, 15 Nov 2024 20:42:07 +1300 Subject: [PATCH 24/56] GH-744: handle_request_transaction_receipts chaged error to a DEBUG log --- node/src/blockchain/blockchain_bridge.rs | 74 +++++++----------------- 1 file changed, 22 insertions(+), 52 deletions(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 038b8b1eb..b8fb69856 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -246,7 +246,7 @@ impl BlockchainBridge { fn handle_qualified_payable_msg( &mut self, incoming_message: QualifiedPayablesMessage, - ) -> Box> { + ) -> Box> { // TODO rewrite this into a batch call as soon as GH-629 gets into master let accountant_recipient = self.payable_payments_setup_subs_opt.clone(); return Box::new( @@ -271,7 +271,7 @@ impl BlockchainBridge { fn handle_outbound_payments_instructions( &mut self, msg: OutboundPaymentsInstructions, - ) -> Box> { + ) -> Box> { let skeleton_opt = msg.response_skeleton_opt; let sent_payable_subs = self .sent_payable_subs_opt @@ -306,7 +306,7 @@ impl BlockchainBridge { fn handle_retrieve_transactions( &mut self, msg: RetrieveTransactions, - ) -> Box> { + ) -> Box> { let start_block_nbr = match self.persistent_config.start_block() { Ok(sb) => sb, Err(e) => panic!("Cannot retrieve start block from database; payments to you may not be processed: {:?}", e) @@ -377,7 +377,8 @@ impl BlockchainBridge { fn handle_request_transaction_receipts( &mut self, msg: RequestTransactionReceipts, - ) -> Box> { + ) -> Box> { + let logger = self.logger.clone(); let accountant_recipient = self .pending_payable_confirmation .report_transaction_receipts_sub_opt @@ -412,13 +413,11 @@ impl BlockchainBridge { response_skeleton_opt: msg.response_skeleton_opt, }) .expect("Accountant is dead"); - // TODO: GH-744: Let's log it, instead of triggering an error if length != transactions_found { - return Err(format!( - "Aborting scanning; {} transactions succeed and {} transactions failed", + debug!(logger, "Aborting scanning; {} transactions succeed and {} transactions failed", transactions_found, length - transactions_found - )); + ); }; Ok(()) }), @@ -427,7 +426,7 @@ impl BlockchainBridge { fn handle_scan_future(&mut self, handler: F, scan_type: ScanType, msg: M) where - F: FnOnce(&mut BlockchainBridge, M) -> Box>, + F: FnOnce(&mut BlockchainBridge, M) -> Box>, M: SkeletonOptHolder, { let skeleton_opt = msg.skeleton_opt(); @@ -453,7 +452,7 @@ impl BlockchainBridge { &self, agent: Box, affordable_accounts: Vec, - ) -> Box, Error = PayableTransactionError>> + ) -> Box, Error=PayableTransactionError>> { let new_fingerprints_recipient = self.new_fingerprints_recipient(); let logger = self.logger.clone(); @@ -597,7 +596,7 @@ mod tests { addr.try_send(BindMessage { peer_actors: peer_actors_builder().build(), }) - .unwrap(); + .unwrap(); System::current().stop(); system.run(); @@ -640,8 +639,7 @@ mod tests { } #[test] - fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant( - ) { + fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant() { let system = System::new( "qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant", ); @@ -808,8 +806,7 @@ mod tests { } #[test] - fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant( - ) { + fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant() { let system = System::new( "handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant", ); @@ -877,7 +874,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap() + .unwrap() })]), response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, @@ -893,7 +890,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -967,7 +964,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -1032,7 +1029,7 @@ mod tests { hash: H256::from_str( "cc73f3d5fe9fc3dac28b510ddeb157b0f8030b201e809014967396cdf365488a" ) - .unwrap() + .unwrap() }) ); assert_eq!( @@ -1042,7 +1039,7 @@ mod tests { hash: H256::from_str( "891d9ffa838aedc0bb2f6f7e9737128ce98bb33d07b4c8aa5645871e20d6cd13" ) - .unwrap() + .unwrap() }) ); let recording = accountant_recording.lock().unwrap(); @@ -1196,10 +1193,9 @@ mod tests { let system = System::new("transaction receipts"); system.run(); let accountant_recording = accountant_recording_arc.lock().unwrap(); - assert_eq!(accountant_recording.len(), 2); + assert_eq!(accountant_recording.len(), 1); let report_transaction_receipt_message = accountant_recording.get_record::(0); - let scan_error_message = accountant_recording.get_record::(1); let mut expected_receipt = TransactionReceipt::default(); expected_receipt.transaction_hash = hash_1; expected_receipt.status = Some(U64::from(1)); @@ -1222,18 +1218,6 @@ mod tests { }), } ); - assert_eq!( - scan_error_message, - &ScanError { - scan_type: ScanType::PendingPayables, - response_skeleton_opt: Some(ResponseSkeleton { - client_id: 1234, - context_id: 4321 - }), - msg: "Aborting scanning; 1 transactions succeed and 1 transactions failed" - .to_string(), - } - ) } #[test] @@ -1293,8 +1277,7 @@ mod tests { } #[test] - fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort( - ) { + fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort() { init_test_logging(); let port = find_free_port(); let block_number = U64::from(4545454); @@ -1387,7 +1370,7 @@ mod tests { assert_eq!(system.run(), 0); let accountant_recording = accountant_recording_arc.lock().unwrap(); - assert_eq!(accountant_recording.len(), 2); + assert_eq!(accountant_recording.len(), 1); let report_receipts_msg = accountant_recording.get_record::(0); assert_eq!( *report_receipts_msg, @@ -1404,20 +1387,7 @@ mod tests { }), } ); - let scan_error_msg = accountant_recording.get_record::(1); - assert_eq!( - *scan_error_msg, - ScanError { - scan_type: ScanType::PendingPayables, - response_skeleton_opt: Some(ResponseSkeleton { - client_id: 1234, - context_id: 4321 - }), - msg: "Aborting scanning; 1 transactions succeed and 3 transactions failed" - .to_string() - } - ); - TestLogHandler::new().exists_log_containing("WARN: BlockchainBridge: Aborting scanning; 1 transactions succeed and 3 transactions failed"); + TestLogHandler::new().exists_log_containing("DEBUG: BlockchainBridge: Aborting scanning; 1 transactions succeed and 3 transactions failed"); } #[test] @@ -2005,7 +1975,7 @@ pub mod exportable_test_parts { use crate::test_utils::unshared_test_utils::SubsFactoryTestAddrLeaker; impl SubsFactory - for SubsFactoryTestAddrLeaker + for SubsFactoryTestAddrLeaker { fn make(&self, addr: &Addr) -> BlockchainBridgeSubs { self.send_leaker_msg_and_return_meaningless_subs( From b3cafe49b5f8c8c5524b028c3a36bc0fcffb8cff Mon Sep 17 00:00:00 2001 From: Syther007 Date: Fri, 15 Nov 2024 23:49:44 +1300 Subject: [PATCH 25/56] GH-744: handle_retrieve_transactions inbeded extract_max_block_count --- node/src/accountant/mod.rs | 2 +- node/src/blockchain/blockchain_bridge.rs | 268 ++++++++++++++++------- node/src/sub_lib/blockchain_bridge.rs | 3 +- 3 files changed, 187 insertions(+), 86 deletions(-) diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index ac1689209..5ea78a9d9 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -3553,7 +3553,7 @@ mod tests { .set_arbitrary_id_stamp(persistent_config_id_stamp); let blockchain_bridge = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); let account_1 = PayableAccount { diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index b8fb69856..684c749b9 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -42,6 +42,7 @@ use masq_lib::ui_gateway::NodeFromUiMessage; use regex::Regex; use std::path::Path; use std::string::ToString; +use std::sync::{Arc, Mutex}; use std::time::SystemTime; use ethabi::Hash; use web3::types::{BlockNumber, H256}; @@ -55,7 +56,7 @@ pub const DEFAULT_BLOCKCHAIN_SERVICE_URL: &str = "https://0.0.0.0"; pub struct BlockchainBridge { blockchain_interface: Box, logger: Logger, - persistent_config: Box, + persistent_config_arc: Arc>, sent_payable_subs_opt: Option>, payable_payments_setup_subs_opt: Option>, received_payments_subs_opt: Option>, @@ -182,12 +183,12 @@ impl Handler for BlockchainBridge { impl BlockchainBridge { pub fn new( blockchain_interface: Box, - persistent_config: Box, + persistent_config: Arc>, crashable: bool, ) -> BlockchainBridge { BlockchainBridge { blockchain_interface, - persistent_config, + persistent_config_arc: persistent_config, sent_payable_subs_opt: None, payable_payments_setup_subs_opt: None, received_payments_subs_opt: None, @@ -203,13 +204,13 @@ impl BlockchainBridge { pub fn initialize_persistent_configuration( data_directory: &Path, - ) -> Box { + ) -> Arc> { let config_dao = Box::new(ConfigDaoReal::new( DbInitializerReal::default() .initialize(data_directory, DbInitializationConfig::panic_on_migration()) .unwrap_or_else(|err| db_connection_launch_panic(err, data_directory)), )); - Box::new(PersistentConfigurationReal::new(config_dao)) + Arc::new(Mutex::new(PersistentConfigurationReal::new(config_dao))) } pub fn initialize_blockchain_interface( @@ -307,24 +308,33 @@ impl BlockchainBridge { &mut self, msg: RetrieveTransactions, ) -> Box> { - let start_block_nbr = match self.persistent_config.start_block() { - Ok(sb) => sb, - Err(e) => panic!("Cannot retrieve start block from database; payments to you may not be processed: {:?}", e) - }; - let max_block_count = match self.persistent_config.max_block_count() { - Ok(Some(mbc)) => mbc, - _ => u64::MAX, + let (start_block_nbr, max_block_count) = { + let persistent_config_lock = self + .persistent_config_arc + .lock() + .expect("Unable to lock persistent config in BlockchainBridge"); + + let start_block_nbr = match persistent_config_lock.start_block() { + Ok(sb) => sb, + Err(e) => panic!("Cannot retrieve start block from database; payments to you may not be processed: {:?}", e) + }; + let max_block_count = match persistent_config_lock.max_block_count() { + Ok(Some(mbc)) => mbc, + _ => u64::MAX, + }; + (start_block_nbr, max_block_count) }; + let logger = self.logger.clone(); let fallback_next_start_block_number = calculate_fallback_start_block_number(start_block_nbr, max_block_count); let start_block = BlockNumber::Number(start_block_nbr.into()); - let received_payments_subs_ok_case = self + let received_payments_subs = self .received_payments_subs_opt .as_ref() .expect("Accountant is unbound") .clone(); - let received_payments_subs_error_case = received_payments_subs_ok_case.clone(); + let mut persistent_config_arc = self.persistent_config_arc.clone(); Box::new( self.blockchain_interface @@ -334,27 +344,25 @@ impl BlockchainBridge { msg.recipient.address(), ) .map_err(move |e| { - let received_payments_error = - match BlockchainBridge::extract_max_block_count(e.clone()) { - Some(max_block_count) => { - ReceivedPaymentsError::ExceededBlockScanLimit(max_block_count) + if let Some(max_block_count) = BlockchainBridge::extract_max_block_count(e.clone()) { + match persistent_config_arc.lock().expect("Unable to lock persistent config in BlockchainBridge").set_max_block_count(Some(max_block_count)) + { + Ok(()) => { + debug!( + logger, + "Updated max_block_count to {} in database.", + max_block_count + ); } - None => ReceivedPaymentsError::OtherRPCError(format!( - "Attempted to retrieve received payments but failed: {:?}", - e - )), - }; - received_payments_subs_error_case - .try_send(ReceivedPayments { - timestamp: SystemTime::now(), - scan_result: Err(received_payments_error.clone()), - response_skeleton_opt: msg.response_skeleton_opt, - }) - .expect("Accountant is dead."); - format!( - "Error while retrieving transactions: {:?}", - received_payments_error - ) + Err(e) => { + panic!( + "Attempt to set new max block to {} failed due to: {:?}", + max_block_count, e + ) + } + } + } + format!("Error while retrieving transactions: {:?}", e) }) .and_then(move |transactions| { let payments_and_start_block = PaymentsAndStartBlock { @@ -362,7 +370,7 @@ impl BlockchainBridge { new_start_block: transactions.new_start_block, }; - received_payments_subs_ok_case + received_payments_subs .try_send(ReceivedPayments { timestamp: SystemTime::now(), scan_result: Ok(payments_and_start_block), @@ -414,7 +422,9 @@ impl BlockchainBridge { }) .expect("Accountant is dead"); if length != transactions_found { - debug!(logger, "Aborting scanning; {} transactions succeed and {} transactions failed", + debug!( + logger, + "Aborting scanning; {} transactions succeed and {} transactions failed", transactions_found, length - transactions_found ); @@ -587,7 +597,7 @@ mod tests { init_test_logging(); let subject = BlockchainBridge::new( stub_bi(), - Box::new(configure_default_persistent_config(ZERO)), + Arc::new(Mutex::new(configure_default_persistent_config(ZERO))), false, ); let system = System::new("blockchain_bridge_receives_bind_message"); @@ -680,7 +690,7 @@ mod tests { ]; let mut subject = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(persistent_configuration), + Arc::new(Mutex::new(persistent_configuration)), false, ); subject.payable_payments_setup_subs_opt = Some(accountant_recipient); @@ -769,7 +779,7 @@ mod tests { let consuming_wallet = make_paying_wallet(b"somewallet"); let mut subject = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(PersistentConfigurationMock::default()), + Arc::new(Mutex::new(PersistentConfigurationMock::default())), false, ); subject.payable_payments_setup_subs_opt = Some(accountant_recipient); @@ -828,7 +838,7 @@ mod tests { let persistent_configuration_mock = PersistentConfigurationMock::default(); let subject = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(persistent_configuration_mock), + Arc::new(Mutex::new(persistent_configuration_mock)), false, ); let addr = subject.start(); @@ -917,7 +927,7 @@ mod tests { let persistent_configuration_mock = PersistentConfigurationMock::default(); let subject = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(persistent_configuration_mock), + Arc::new(Mutex::new(persistent_configuration_mock)), false, ); let addr = subject.start(); @@ -1007,7 +1017,7 @@ mod tests { let persistent_config = PersistentConfigurationMock::new(); let mut subject = BlockchainBridge::new( Box::new(blockchain_interface_web3), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); let (accountant, _, accountant_recording) = make_recorder(); @@ -1061,7 +1071,7 @@ mod tests { let persistent_config = configure_default_persistent_config(ZERO); let mut subject = BlockchainBridge::new( Box::new(blockchain_interface_web3), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); let (accountant, _, accountant_recording) = make_recorder(); @@ -1102,7 +1112,7 @@ mod tests { let persistent_config = PersistentConfigurationMock::new(); let mut subject = BlockchainBridge::new( Box::new(blockchain_interface_web3), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); let (accountant, _, accountant_recording) = make_recorder(); @@ -1170,7 +1180,7 @@ mod tests { let blockchain_interface = make_blockchain_interface_web3(Some(port)); let subject = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(PersistentConfigurationMock::default()), + Arc::new(Mutex::new(PersistentConfigurationMock::default())), false, ); let addr = subject.start(); @@ -1240,7 +1250,7 @@ mod tests { .start_block_result(Ok(5)); // no set_start_block_result: set_start_block() must not be called let mut subject = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); subject.scan_error_subs_opt = Some(scan_error_recipient); @@ -1256,23 +1266,18 @@ mod tests { system.run(); let recording = accountant_recording_arc.lock().unwrap(); - let message = recording.get_record::(0); + let scan_error = recording.get_record::(0); assert_eq!( - message.scan_result, - Err(ReceivedPaymentsError::OtherRPCError("Attempted to retrieve received payments but failed: QueryFailed(\"Transport error: Error(IncompleteMessage)\")".to_string())) - ); - let message_2 = recording.get_record::(1); - assert_eq!( - message_2, + scan_error, &ScanError { scan_type: ScanType::Receivables, response_skeleton_opt: None, - msg: "Error while retrieving transactions: OtherRPCError(\"Attempted to retrieve received payments but failed: QueryFailed(\\\"Transport error: Error(IncompleteMessage)\\\")\")".to_string() + msg: "Error while retrieving transactions: QueryFailed(\"Transport error: Error(IncompleteMessage)\")".to_string() } ); - assert_eq!(recording.len(), 2); + assert_eq!(recording.len(), 1); TestLogHandler::new().exists_log_containing( - "WARN: BlockchainBridge: Error while retrieving transactions: OtherRPCError(\"Attempted to retrieve received payments but failed: QueryFailed(\\\"Transport error: Error(IncompleteMessage)\\\")\")", + "WARN: BlockchainBridge: Error while retrieving transactions: QueryFailed(\"Transport error: Error(IncompleteMessage)\")", ); } @@ -1345,7 +1350,7 @@ mod tests { let system = System::new("test_transaction_receipts"); let mut subject = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(PersistentConfigurationMock::default()), + Arc::new(Mutex::new(PersistentConfigurationMock::default())), false, ); subject @@ -1422,7 +1427,7 @@ mod tests { let blockchain_interface = make_blockchain_interface_web3(Some(port)); let mut subject = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(PersistentConfigurationMock::default()), + Arc::new(Mutex::new(PersistentConfigurationMock::default())), false, ); subject @@ -1490,7 +1495,7 @@ mod tests { .start_block_result(Ok(6)); let mut subject = BlockchainBridge::new( Box::new(blockchain_interface_mock), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); subject.received_payments_subs_opt = Some(accountant.start().recipient()); @@ -1594,7 +1599,7 @@ mod tests { .max_block_count_result(Err(PersistentConfigError::NotPresent)); let subject = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); let addr = subject.start(); @@ -1665,7 +1670,7 @@ mod tests { .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant_addr = - accountant.system_stop_conditions(match_every_type_id!(ReceivedPayments)); + accountant.system_stop_conditions(match_every_type_id!(ScanError)); let earning_wallet = make_wallet("earning_wallet"); let mut blockchain_interface = make_blockchain_interface_web3(Some(port)); blockchain_interface.logger = logger; @@ -1676,7 +1681,7 @@ mod tests { ))); let subject = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); let addr = subject.start(); @@ -1690,30 +1695,22 @@ mod tests { context_id: 4321, }), }; - let before = SystemTime::now(); let _ = addr.try_send(retrieve_transactions).unwrap(); system.run(); - let after = SystemTime::now(); - let accountant_recording = accountant_recording_arc.lock().unwrap(); - assert_eq!(accountant_recording.len(), 2); - let received_payments_error_message = - accountant_recording.get_record::(0); - check_timestamp(before, received_payments_error_message.timestamp, after); + assert_eq!(accountant_recording.len(), 1); + let scan_error_msg = accountant_recording.get_record::(0); assert_eq!( - received_payments_error_message, - &ReceivedPayments { - timestamp: received_payments_error_message.timestamp, - scan_result: Err(OtherRPCError( - "Attempted to retrieve received payments but failed: InvalidResponse" - .to_string() - )), + scan_error_msg, + &ScanError { + scan_type: ScanType::Receivables, response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, context_id: 4321 }), + msg: "Error while retrieving transactions: InvalidResponse".to_string(), } ); TestLogHandler::new().exists_log_containing(&format!( @@ -1721,6 +1718,109 @@ mod tests { )); } + #[test] + fn handle_retrieve_transactions_receives_query_failed_and_updates_max_block() { + init_test_logging(); + let test_name = "handle_retrieve_transactions_receives_query_failed_and_updates_max_block"; + let system = System::new(test_name); + let port = find_free_port(); + let _blockchain_client_server = MBCSBuilder::new(port) + .response("0x3B9ACA00".to_string(), 0) + .err_response(-32005, "Blockheight too far in the past. Check params passed to eth_getLogs or eth_call requests.Range of blocks allowed for your plan: 1000", 0) + .start(); + let (accountant, _, accountant_recording_arc) = make_recorder(); + let accountant = + accountant.system_stop_conditions(match_every_type_id!(ScanError)); + let earning_wallet = make_wallet("earning_wallet"); + let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let persistent_config = PersistentConfigurationMock::new() + .start_block_result(Ok(6)) + .max_block_count_result(Err(PersistentConfigError::DatabaseError( + "my tummy hurts".to_string(), + ))) + .set_max_block_count_result(Ok(())); + let mut subject = BlockchainBridge::new( + Box::new(blockchain_interface), + Arc::new(Mutex::new(persistent_config)), + false, + ); + subject.logger = Logger::new(test_name); + let addr = subject.start(); + let subject_subs = BlockchainBridge::make_subs_from(&addr); + let peer_actors = peer_actors_builder().accountant(accountant).build(); + send_bind_message!(subject_subs, peer_actors); + let retrieve_transactions = RetrieveTransactions { + recipient: earning_wallet.clone(), + response_skeleton_opt: Some(ResponseSkeleton { + client_id: 1234, + context_id: 4321, + }), + }; + + let _ = addr.try_send(retrieve_transactions).unwrap(); + + system.run(); + let accountant_recording = accountant_recording_arc.lock().unwrap(); + assert_eq!(accountant_recording.len(), 1); + let scan_error_msg = accountant_recording.get_record::(0); + assert_eq!( + scan_error_msg, + &ScanError { + scan_type: ScanType::Receivables, + response_skeleton_opt: Some(ResponseSkeleton { + client_id: 1234, + context_id: 4321 + }), + msg: "Error while retrieving transactions: QueryFailed(\"RPC error: Error { code: ServerError(-32005), message: \\\"Blockheight too far in the past. Check params passed to eth_getLogs or eth_call requests.Range of blocks allowed for your plan: 1000\\\", data: None }\")".to_string(), + } + ); + TestLogHandler::new().exists_log_containing(&format!( + "DEBUG: {test_name}: Updated max_block_count to 1000 in database" + )); + } + + #[test] + #[should_panic( + expected = "Attempt to set new max block to 1000 failed due to: DatabaseError(\"my brain hurst\")" + )] + fn handle_retrieve_transactions_receives_query_failed_and_failed_update_max_block() { + let system = System::new("test"); + let port = find_free_port(); + let _blockchain_client_server = MBCSBuilder::new(port) + .response("0x3B9ACA00".to_string(), 0) + .err_response(-32005, "Blockheight too far in the past. Check params passed to eth_getLogs or eth_call requests.Range of blocks allowed for your plan: 1000", 0) + .start(); + let (accountant, _, _) = make_recorder(); + let earning_wallet = make_wallet("earning_wallet"); + let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let persistent_config = PersistentConfigurationMock::new() + .start_block_result(Ok(6)) + .max_block_count_result(Err(PersistentConfigError::DatabaseError( + "my tummy hurts".to_string(), + ))) + .set_max_block_count_result(Err(PersistentConfigError::DatabaseError("my brain hurst".to_string()))); + let subject = BlockchainBridge::new( + Box::new(blockchain_interface), + Arc::new(Mutex::new(persistent_config)), + false, + ); + let addr = subject.start(); + let subject_subs = BlockchainBridge::make_subs_from(&addr); + let peer_actors = peer_actors_builder().accountant(accountant).build(); + send_bind_message!(subject_subs, peer_actors); + let retrieve_transactions = RetrieveTransactions { + recipient: earning_wallet.clone(), + response_skeleton_opt: Some(ResponseSkeleton { + client_id: 1234, + context_id: 4321, + }), + }; + + let _ = addr.try_send(retrieve_transactions).unwrap(); + + system.run(); + } + #[test] #[should_panic( expected = "Cannot retrieve start block from database; payments to you may not be processed: TransactionError" @@ -1730,7 +1830,7 @@ mod tests { .start_block_result(Err(PersistentConfigError::TransactionError)); let mut subject = BlockchainBridge::new( Box::new(BlockchainInterfaceMock::default()), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); let retrieve_transactions = RetrieveTransactions { @@ -1771,7 +1871,7 @@ mod tests { BlockchainInterfaceMock::default() .retrieve_transactions_result(Ok(retrieved_blockchain_transactions)), ), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); let system = System::new("test"); @@ -1821,7 +1921,7 @@ mod tests { BlockchainError::QueryFailed("My tummy hurts".to_string()), )), ), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); let system = System::new("test"); @@ -1839,17 +1939,17 @@ mod tests { system.run(); let accountant_recording = accountant_recording_arc.lock().unwrap(); - let message = accountant_recording.get_record::(1); + let message = accountant_recording.get_record::(0); assert_eq!( message, &ScanError { scan_type: ScanType::Receivables, response_skeleton_opt: msg.response_skeleton_opt, - msg: "Error while retrieving transactions: OtherRPCError(\"Attempted to retrieve received payments but failed: QueryFailed(\\\"My tummy hurts\\\")\")".to_string() + msg: "Error while retrieving transactions: QueryFailed(\"My tummy hurts\")".to_string() } ); - assert_eq!(accountant_recording.len(), 2); - TestLogHandler::new().exists_log_containing("WARN: BlockchainBridge: Error while retrieving transactions: OtherRPCError(\"Attempted to retrieve received payments but failed: QueryFailed(\\\"My tummy hurts\\\")\")"); + assert_eq!(accountant_recording.len(), 1); + TestLogHandler::new().exists_log_containing("WARN: BlockchainBridge: Error while retrieving transactions: QueryFailed(\"My tummy hurts\")"); } #[test] @@ -1860,7 +1960,7 @@ mod tests { let crashable = true; let subject = BlockchainBridge::new( Box::new(BlockchainInterfaceMock::default()), - Box::new(PersistentConfigurationMock::default()), + Arc::new(Mutex::new(PersistentConfigurationMock::default())), crashable, ); diff --git a/node/src/sub_lib/blockchain_bridge.rs b/node/src/sub_lib/blockchain_bridge.rs index 6d43ea47b..e31760a7b 100644 --- a/node/src/sub_lib/blockchain_bridge.rs +++ b/node/src/sub_lib/blockchain_bridge.rs @@ -89,6 +89,7 @@ mod tests { use crate::test_utils::persistent_configuration_mock::PersistentConfigurationMock; use crate::test_utils::recorder::{make_blockchain_bridge_subs_from_recorder, Recorder}; use actix::Actor; + use std::sync::{Arc, Mutex}; #[test] fn blockchain_bridge_subs_debug() { @@ -106,7 +107,7 @@ mod tests { let persistent_config = PersistentConfigurationMock::new(); let accountant = BlockchainBridge::new( Box::new(blockchain_interface), - Box::new(persistent_config), + Arc::new(Mutex::new(persistent_config)), false, ); let addr = accountant.start(); From ab32fb68e6c42d78322056dc2fd2e1af30793d43 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Sat, 16 Nov 2024 00:19:26 +1300 Subject: [PATCH 26/56] GH-744: code refactor --- node/src/accountant/mod.rs | 80 ++++++------ node/src/accountant/scanners/mod.rs | 156 ++++------------------- node/src/actor_system_factory.rs | 31 +++-- node/src/blockchain/blockchain_bridge.rs | 19 ++- 4 files changed, 86 insertions(+), 200 deletions(-) diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index 5ea78a9d9..f64c7ebc9 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -137,7 +137,7 @@ pub struct ReceivedPayments { // detects any upcoming delinquency later than the more accurate version would. Is this // a problem? Do we want to correct the timestamp? Discuss. pub timestamp: SystemTime, - pub scan_result: Result, + pub payments_and_start_block: PaymentsAndStartBlock, pub response_skeleton_opt: Option, } @@ -743,7 +743,7 @@ impl Accountant { stats_opt, query_results_opt, } - .tmb(context_id) + .tmb(context_id) } fn request_payable_accounts_by_specific_mode( @@ -1032,11 +1032,11 @@ pub fn checked_conversion>(num: T) -> S { politely_checked_conversion(num).unwrap_or_else(|msg| panic!("{}", msg)) } -pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { +pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { (T::from(gwei)).mul(T::from(WEIS_IN_GWEI as u32)) } -pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { +pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { checked_conversion::(wei.div(S::from(WEIS_IN_GWEI as u32))) } @@ -1364,7 +1364,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Receivables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1404,7 +1404,7 @@ mod tests { subject_addr.try_send(BindMessage { peer_actors }).unwrap(); let received_payments = ReceivedPayments { timestamp: SystemTime::now(), - scan_result: Ok(make_empty_payments_and_start_block()), + payments_and_start_block: make_empty_payments_and_start_block(), response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, context_id: 4321, @@ -1456,7 +1456,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Payables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1523,8 +1523,7 @@ mod tests { } #[test] - fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge( - ) { + fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge() { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1616,8 +1615,7 @@ mod tests { } #[test] - fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge( - ) { + fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge() { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1765,7 +1763,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1820,7 +1818,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; let second_message = first_message.clone(); let peer_actors = peer_actors_builder() @@ -2011,8 +2009,7 @@ mod tests { } #[test] - fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block( - ) { + fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block() { let more_money_received_params_arc = Arc::new(Mutex::new(vec![])); let commit_params_arc = Arc::new(Mutex::new(vec![])); let set_by_guest_transaction_params_arc = Arc::new(Mutex::new(vec![])); @@ -2047,13 +2044,13 @@ mod tests { .build(); let system = System::new("accountant_uses_receivables_dao_to_process_received_payments"); let subject = accountant.start(); - let mut scan_result = make_empty_payments_and_start_block(); - scan_result.payments = vec![expected_receivable_1.clone(), expected_receivable_2.clone()]; - scan_result.new_start_block = 123456789; + let mut payments_and_start_block = make_empty_payments_and_start_block(); + payments_and_start_block.payments = vec![expected_receivable_1.clone(), expected_receivable_2.clone()]; + payments_and_start_block.new_start_block = 123456789; subject .try_send(ReceivedPayments { timestamp: now, - scan_result: Ok(scan_result), + payments_and_start_block, response_skeleton_opt: None, }) .expect("unexpected actix error"); @@ -2711,7 +2708,7 @@ mod tests { addr.try_send(ScanForPayables { response_skeleton_opt: None, }) - .unwrap(); + .unwrap(); // We ignored the second ScanForPayables message because the first message meant a scan // was already in progress; now let's make it look like that scan has ended so that we @@ -2724,7 +2721,7 @@ mod tests { .mark_as_ended(&Logger::new("irrelevant")) }), }) - .unwrap(); + .unwrap(); addr.try_send(message_after.clone()).unwrap(); system.run(); let recording = blockchain_bridge_recording.lock().unwrap(); @@ -4033,7 +4030,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4117,7 +4114,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4180,7 +4177,7 @@ mod tests { }), query_results_opt: None } - .tmb(context_id) + .tmb(context_id) ) } @@ -4257,12 +4254,12 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 58, pending_payable_hash_opt: None - },]), + }, ]), receivable_opt: Some(vec![UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), age_s: extracted_receivable_ages[0], balance_gwei: 3_788_455 - },]) + }, ]) }), } ); @@ -4423,7 +4420,7 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 5, pending_payable_hash_opt: None - },]), + }, ]), receivable_opt: Some(vec![ UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), @@ -4612,8 +4609,7 @@ mod tests { expected = "Broken code: PayableAccount with less than 1 gwei passed through db query \ constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 8686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei( - ) { + fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei() { let payable_accounts_retrieved = vec![PayableAccount { wallet: make_wallet("abcd123"), balance_wei: 8_686_005, @@ -4649,8 +4645,7 @@ mod tests { expected = "Broken code: ReceivableAccount with balance between 1 and 0 gwei passed through \ db query constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 7686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei( - ) { + fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei() { let receivable_accounts_retrieved = vec![ReceivableAccount { wallet: make_wallet("abcd123"), balance_wei: 7_686_005, @@ -4889,11 +4884,10 @@ pub mod exportable_test_parts { } } - fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao( - ) -> ShouldWeRunTheTest { + fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao() -> ShouldWeRunTheTest { fn skip_down_to_first_line_saying_new_delinquencies( - previous: impl Iterator, - ) -> impl Iterator { + previous: impl Iterator, + ) -> impl Iterator { previous .skip_while(|line| { let adjusted_line: String = line @@ -4904,7 +4898,7 @@ pub mod exportable_test_parts { }) .skip(1) } - fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { + fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { fn yield_if_contains_semicolon(line: &str) -> Option { line.contains(';').then(|| line.to_string()) } @@ -4943,13 +4937,13 @@ pub mod exportable_test_parts { skip_down_to_first_line_saying_new_delinquencies( lines_with_cut_fn_trait_definition, ) - .take_while(|line| { - let adjusted_line: String = line - .chars() - .skip_while(|char| char.is_whitespace()) - .collect(); - !adjusted_line.starts_with("fn") - }); + .take_while(|line| { + let adjusted_line: String = line + .chars() + .skip_while(|char| char.is_whitespace()) + .collect(); + !adjusted_line.starts_with("fn") + }); assert_is_not_trait_definition(assumed_implemented_function_body) } fn user_defined_functions_detected(line_undivided_fn_body: &str) -> bool { diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index 2aa146cdc..f992a9d36 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -22,7 +22,7 @@ use crate::accountant::scanners::scanners_utils::pending_payable_scanner_utils:: PendingPayableScanReport, }; use crate::accountant::scanners::scanners_utils::receivable_scanner_utils::balance_and_age; -use crate::accountant::{PaymentsAndStartBlock, PendingPayableId, ReceivedPaymentsError}; +use crate::accountant::{PaymentsAndStartBlock, PendingPayableId}; use crate::accountant::{ comma_joined_stringifiable, gwei_to_wei, Accountant, ReceivedPayments, ReportTransactionReceipts, RequestTransactionReceipts, ResponseSkeleton, ScanForPayables, @@ -321,7 +321,7 @@ impl PayableScanner { logger: &Logger, ) -> Vec { fn pass_payables_and_drop_points( - qp_tp: impl Iterator, + qp_tp: impl Iterator, ) -> Vec { let (payables, _) = qp_tp.unzip::<_, _, Vec, Vec<_>>(); payables @@ -833,15 +833,7 @@ impl Scanner for ReceivableScanner { } fn finish_scan(&mut self, msg: ReceivedPayments, logger: &Logger) -> Option { - match msg.scan_result { - Ok(payments_and_start_block) => { - self.handle_new_received_payments(&payments_and_start_block, msg.timestamp, logger); - } - Err(e) => { - self.handle_new_received_payments_scan_error(e, logger); - } - } - + self.handle_new_received_payments(&msg.payments_and_start_block, msg.timestamp, logger); self.mark_as_ended(logger); msg.response_skeleton_opt .map(|response_skeleton| NodeToUiMessage { @@ -930,41 +922,6 @@ impl ReceivableScanner { } } - fn handle_new_received_payments_scan_error( - &mut self, - error: ReceivedPaymentsError, - logger: &Logger, - ) { - match error { - ReceivedPaymentsError::ExceededBlockScanLimit(max_block_count) => { - match self - .persistent_configuration - .set_max_block_count(Some(max_block_count)) - { - Ok(()) => { - debug!( - logger, - "Updated max_block_count to {} in database.", max_block_count - ); - } - Err(e) => { - panic!( - "Attempt to set new max block to {} failed due to: {:?}", - max_block_count, e - ) - } - } - } - ReceivedPaymentsError::OtherRPCError(rpc_error) => { - warning!( - logger, - "Attempted to retrieve received payments but failed: {:?}", - rpc_error - ); - } - } - } - pub fn scan_for_delinquencies(&self, timestamp: SystemTime, logger: &Logger) { info!(logger, "Scanning for delinquencies"); self.find_and_ban_delinquents(timestamp, logger); @@ -1181,7 +1138,6 @@ mod tests { use std::time::{Duration, SystemTime}; use web3::types::{TransactionReceipt, H256}; use web3::Error; - use crate::accountant::ReceivedPaymentsError::{ExceededBlockScanLimit, OtherRPCError}; use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; #[test] @@ -1631,9 +1587,9 @@ mod tests { (vals.intruder_for_hash_2, 5), (vals.common_hash_3, 6), ] - .iter() - .map(|(hash, _rowid)| *hash) - .collect::>(); + .iter() + .map(|(hash, _rowid)| *hash) + .collect::>(); let result = PayableScanner::is_symmetrical( pending_payables_ref_from_blockchain_bridge, @@ -2519,7 +2475,7 @@ mod tests { result, PendingPayableScanReport { still_pending: vec![], - failures: vec![PendingPayableId::new(777777, hash,)], + failures: vec![PendingPayableId::new(777777, hash, )], confirmed: vec![] } ); @@ -3094,11 +3050,11 @@ mod tests { let mut subject = ReceivableScannerBuilder::new() .persistent_configuration(persistent_config) .build(); - let mut scan_result = make_empty_payments_and_start_block(); - scan_result.new_start_block = new_start_block; + let mut payments_and_start_block = make_empty_payments_and_start_block(); + payments_and_start_block.new_start_block = new_start_block; let msg = ReceivedPayments { timestamp: SystemTime::now(), - scan_result: Ok(scan_result), + payments_and_start_block, response_skeleton_opt: None, }; @@ -3125,11 +3081,11 @@ mod tests { let mut subject = ReceivableScannerBuilder::new() .persistent_configuration(persistent_config) .build(); - let mut scan_result = make_empty_payments_and_start_block(); - scan_result.new_start_block = 6709; + let mut payments_and_start_block = make_empty_payments_and_start_block(); + payments_and_start_block.new_start_block = 6709; let msg = ReceivedPayments { timestamp: now, - scan_result: Ok(scan_result), + payments_and_start_block, response_skeleton_opt: None, }; @@ -3178,12 +3134,12 @@ mod tests { wei_amount: 3_333_345, }, ]; - let mut scan_result = make_empty_payments_and_start_block(); - scan_result.new_start_block = 7890123; - scan_result.payments = receivables.clone(); + let mut payments_and_start_block = make_empty_payments_and_start_block(); + payments_and_start_block.new_start_block = 7890123; + payments_and_start_block.payments = receivables.clone(); let msg = ReceivedPayments { timestamp: now, - scan_result: Ok(scan_result), + payments_and_start_block, response_skeleton_opt: None, }; subject.mark_as_started(SystemTime::now()); @@ -3235,10 +3191,10 @@ mod tests { }]; let msg = ReceivedPayments { timestamp: now, - scan_result: Ok(PaymentsAndStartBlock { + payments_and_start_block: PaymentsAndStartBlock { payments: receivables, new_start_block: 7890123, - }), + }, response_skeleton_opt: None, }; // Not necessary, rather for preciseness @@ -3278,11 +3234,11 @@ mod tests { from: make_wallet("abc"), wei_amount: 45_780, }]; - let mut scan_result = make_empty_payments_and_start_block(); - scan_result.payments = receivables; + let mut payments_and_start_block = make_empty_payments_and_start_block(); + payments_and_start_block.payments = receivables; let msg = ReceivedPayments { timestamp: now, - scan_result: Ok(scan_result), + payments_and_start_block, response_skeleton_opt: None, }; // Not necessary, rather for preciseness @@ -3291,74 +3247,6 @@ mod tests { subject.finish_scan(msg, &Logger::new(test_name)); } - #[test] - fn receivable_scanner_receives_exceeded_block_scan_limit_error() { - init_test_logging(); - let test_name = "receivable_scanner_receives_exceeded_block_scan_limit_error"; - let set_max_block_params_arc = Arc::new(Mutex::new(vec![])); - let new_max_block = 100_000u64; - let persistent_config = PersistentConfigurationMock::new() - .set_max_block_count_params(&set_max_block_params_arc) - .set_max_block_count_result(Ok(())); - let mut subject = ReceivableScannerBuilder::new() - .persistent_configuration(persistent_config) - .build(); - let msg = ReceivedPayments { - timestamp: SystemTime::now(), - scan_result: Err(ExceededBlockScanLimit(new_max_block)), - response_skeleton_opt: None, - }; - - let message_opt = subject.finish_scan(msg, &Logger::new(test_name)); - - assert_eq!(message_opt, None); - let set_max_block_params = set_max_block_params_arc.lock().unwrap(); - assert_eq!(*set_max_block_params, vec![Some(new_max_block)]); - TestLogHandler::new().exists_log_containing(&format!( - "DEBUG: {test_name}: Updated max_block_count to 100000 in database." - )); - } - - #[test] - #[should_panic( - expected = "Attempt to set new max block to 100000 failed due to: DatabaseError(\"Some bad stuff happened\")" - )] - fn receivable_scanner_receives_exceeded_block_scan_limit_error_and_database_wright_fails() { - let new_max_block = 100_000u64; - let persistent_config = PersistentConfigurationMock::new().set_max_block_count_result(Err( - PersistentConfigError::DatabaseError("Some bad stuff happened".to_string()), - )); - let mut subject = ReceivableScannerBuilder::new() - .persistent_configuration(persistent_config) - .build(); - let msg = ReceivedPayments { - timestamp: SystemTime::now(), - scan_result: Err(ExceededBlockScanLimit(new_max_block)), - response_skeleton_opt: None, - }; - - let _ = subject.finish_scan(msg, &Logger::new("test")); - } - - #[test] - fn receivable_scanner_receives_other_rpc_error() { - init_test_logging(); - let test_name = "receivable_scanner_receives_other_rpc_error"; - let mut subject = ReceivableScannerBuilder::new().build(); - let msg = ReceivedPayments { - timestamp: SystemTime::now(), - scan_result: Err(OtherRPCError("Dead RPC".to_string())), - response_skeleton_opt: None, - }; - - let message_opt = subject.finish_scan(msg, &Logger::new(test_name)); - - assert_eq!(message_opt, None); - TestLogHandler::new().exists_log_containing(&format!( - "WARN: {test_name}: Attempted to retrieve received payments but failed: \"Dead RPC\"" - )); - } - #[test] fn signal_scanner_completion_and_log_if_timestamp_is_correct() { init_test_logging(); diff --git a/node/src/actor_system_factory.rs b/node/src/actor_system_factory.rs index d85104e21..189d1fd71 100644 --- a/node/src/actor_system_factory.rs +++ b/node/src/actor_system_factory.rs @@ -256,7 +256,7 @@ impl ActorSystemFactoryToolsReal { r.try_send(NewPublicIp { new_ip: new_public_ip, }) - .expect("NewPublicIp recipient is dead") + .expect("NewPublicIp recipient is dead") }); } @@ -308,7 +308,7 @@ impl ActorSystemFactoryToolsReal { AutomapChange::NewIp(new_public_ip) => { exit_process( 1, - format! ("IP change to {} reported from ISP. We can't handle that until GH-499. Going down...", new_public_ip).as_str() + format!("IP change to {} reported from ISP. We can't handle that until GH-499. Going down...", new_public_ip).as_str(), ); } AutomapChange::Error(e) => Self::handle_housekeeping_thread_error(e), @@ -635,7 +635,7 @@ where mod tests { use super::*; use crate::accountant::exportable_test_parts::test_accountant_is_constructed_with_upgraded_db_connection_recognizing_our_extra_sqlite_functions; - use crate::accountant::{ReceivedPayments, DEFAULT_PENDING_TOO_LONG_SEC}; + use crate::accountant::{PaymentsAndStartBlock, ReceivedPayments, DEFAULT_PENDING_TOO_LONG_SEC}; use crate::blockchain::blockchain_bridge::RetrieveTransactions; use crate::bootstrapper::{Bootstrapper, RealUser}; use crate::db_config::persistent_configuration::PersistentConfigurationReal; @@ -710,6 +710,8 @@ mod tests { use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; + use crate::blockchain::blockchain_interface::data_structures::BlockchainTransaction; + use crate::sub_lib::wallet::Wallet; struct LogRecipientSetterNull {} @@ -1257,7 +1259,7 @@ mod tests { earning_wallet: make_wallet("earning"), consuming_wallet_opt: Some(make_wallet("consuming")), data_directory: PathBuf::new(), - node_descriptor: NodeDescriptor::try_from ((main_cryptde(), "masq://polygon-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@172.50.48.6:9342")).unwrap(), + node_descriptor: NodeDescriptor::try_from((main_cryptde(), "masq://polygon-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@172.50.48.6:9342")).unwrap(), main_cryptde_null_opt: None, alias_cryptde_null_opt: None, mapping_protocol_opt: Some(AutomapProtocol::Igdp), @@ -1271,7 +1273,7 @@ mod tests { min_hops: MIN_HOPS_FOR_TEST, }, payment_thresholds_opt: Default::default(), - when_pending_too_long_sec: DEFAULT_PENDING_TOO_LONG_SEC + when_pending_too_long_sec: DEFAULT_PENDING_TOO_LONG_SEC, }; let add_mapping_params_arc = Arc::new(Mutex::new(vec![])); let mut subject = make_subject_with_null_setter(); @@ -1358,7 +1360,7 @@ mod tests { let dispatcher_param = Parameters::get(parameters.dispatcher_params); assert_eq!( dispatcher_param.node_descriptor, - NodeDescriptor::try_from ((main_cryptde(), "masq://polygon-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@172.50.48.6:9342")).unwrap() + NodeDescriptor::try_from((main_cryptde(), "masq://polygon-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@172.50.48.6:9342")).unwrap() ); let blockchain_bridge_param = Parameters::get(parameters.blockchain_bridge_params); assert_eq!( @@ -1570,7 +1572,7 @@ mod tests { min_hops: MIN_HOPS_FOR_TEST, }, payment_thresholds_opt: Default::default(), - when_pending_too_long_sec: DEFAULT_PENDING_TOO_LONG_SEC + when_pending_too_long_sec: DEFAULT_PENDING_TOO_LONG_SEC, }; let system = System::new("MASQNode"); let mut subject = make_subject_with_null_setter(); @@ -1723,8 +1725,7 @@ mod tests { } #[test] - fn prepare_initial_messages_generates_no_consuming_wallet_balance_if_no_consuming_wallet_is_specified( - ) { + fn prepare_initial_messages_generates_no_consuming_wallet_balance_if_no_consuming_wallet_is_specified() { let actor_factory = ActorFactoryMock::new(); let parameters = actor_factory.make_parameters(); let config = BootstrapperConfig { @@ -1976,8 +1977,7 @@ mod tests { } #[test] - fn accountant_is_constructed_with_upgraded_db_connection_recognizing_our_extra_sqlite_functions( - ) { + fn accountant_is_constructed_with_upgraded_db_connection_recognizing_our_extra_sqlite_functions() { let act = |bootstrapper_config: BootstrapperConfig, db_initializer: DbInitializerReal, banned_cache_loader: BannedCacheLoaderMock, @@ -2063,14 +2063,19 @@ mod tests { .unwrap(); blockchain_bridge_addr .try_send(RetrieveTransactions { - recipient: wallet, + recipient: wallet.clone(), response_skeleton_opt: None, }) .unwrap(); assert_eq!(system.run(), 0); let recording = accountant_recording.lock().unwrap(); let received_payments_message = recording.get_record::(0); - assert!(received_payments_message.scan_result.is_ok()); + assert_eq!(received_payments_message.payments_and_start_block, + PaymentsAndStartBlock { + payments: vec![BlockchainTransaction { block_number: 2000, from: Wallet::new("0x0000000000006561726e696e675f77616c6c6574"), wei_amount: 996000000 }], + new_start_block: 1000000000 + } + ); } #[test] diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 684c749b9..d1a259093 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -4,7 +4,7 @@ use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::msgs::{ BlockchainAgentWithContextMessage, QualifiedPayablesMessage, }; use crate::accountant::{ - PaymentsAndStartBlock, ReceivedPayments, ReceivedPaymentsError, ResponseSkeleton, ScanError, + PaymentsAndStartBlock, ReceivedPayments, ResponseSkeleton, ScanError, SentPayables, SkeletonOptHolder, }; use crate::accountant::{ReportTransactionReceipts, RequestTransactionReceipts}; @@ -334,7 +334,7 @@ impl BlockchainBridge { .as_ref() .expect("Accountant is unbound") .clone(); - let mut persistent_config_arc = self.persistent_config_arc.clone(); + let persistent_config_arc = self.persistent_config_arc.clone(); Box::new( self.blockchain_interface @@ -373,7 +373,7 @@ impl BlockchainBridge { received_payments_subs .try_send(ReceivedPayments { timestamp: SystemTime::now(), - scan_result: Ok(payments_and_start_block), + payments_and_start_block, response_skeleton_opt: msg.response_skeleton_opt, }) .expect("Accountant is dead."); @@ -564,7 +564,6 @@ mod tests { use web3::types::{BlockNumber, TransactionReceipt, H160}; use masq_lib::test_utils::mock_blockchain_client_server::MBCSBuilder; use crate::accountant::db_access_objects::pending_payable_dao::PendingPayable; - use crate::accountant::ReceivedPaymentsError::OtherRPCError; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::test_utils::BlockchainAgentMock; use crate::blockchain::blockchain_interface::data_structures::errors::PayableTransactionError::{GasPriceQueryFailed, TransactionID}; use crate::blockchain::blockchain_interface::data_structures::ProcessedPayableFallible::Correct; @@ -1529,14 +1528,14 @@ mod tests { assert_eq!(accountant_received_payment.len(), 1); let received_payments = accountant_received_payment.get_record::(0); check_timestamp(before, received_payments.timestamp, after); - let mut scan_result = make_empty_payments_and_start_block(); - scan_result.payments = expected_transactions.transactions; - scan_result.new_start_block = 8675309u64; + let mut payments_and_start_block = make_empty_payments_and_start_block(); + payments_and_start_block.payments = expected_transactions.transactions; + payments_and_start_block.new_start_block = 8675309u64; assert_eq!( received_payments, &ReceivedPayments { timestamp: received_payments.timestamp, - scan_result: Ok(scan_result), + payments_and_start_block, response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, context_id: 4321 @@ -1628,10 +1627,10 @@ mod tests { received_payments_message, &ReceivedPayments { timestamp: received_payments_message.timestamp, - scan_result: Ok(PaymentsAndStartBlock { + payments_and_start_block: PaymentsAndStartBlock { payments: expected_transactions.transactions, new_start_block: expected_transactions.new_start_block, - }), + }, response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, context_id: 4321 From 1a92588a18ca5a679b3f92d5fbe76f0e0798a5d4 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 18 Nov 2024 21:05:26 +1300 Subject: [PATCH 27/56] GH-744: removed transaction_id from Agent --- node/src/accountant/mod.rs | 2 - .../payable_scanner/agent_null.rs | 18 ---- .../payable_scanner/agent_web3.rs | 12 --- .../payable_scanner/blockchain_agent.rs | 2 +- .../payable_scanner/test_utils.rs | 12 --- node/src/blockchain/blockchain_bridge.rs | 19 +--- .../blockchain_interface_web3/mod.rs | 92 +++++-------------- .../data_structures/errors.rs | 8 -- .../blockchain/blockchain_interface_utils.rs | 64 +++++++------ 9 files changed, 58 insertions(+), 171 deletions(-) diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index f64c7ebc9..609181485 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -3451,8 +3451,6 @@ mod tests { "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), 0, ) - // Blockchain Agent tx_id - .response("0x2".to_string(), 1) // gas_price .response("0x3B9ACA00".to_string(), 1) // Submit payments to blockchain diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs index 5510ec2af..036d1d72f 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs @@ -37,11 +37,6 @@ impl BlockchainAgent for BlockchainAgentNull { &self.wallet } - fn pending_transaction_id(&self) -> U256 { - self.log_function_call("pending_transaction_id()"); - U256::zero() - } - #[cfg(test)] fn dup(&self) -> Box { intentionally_blank!() @@ -176,17 +171,4 @@ mod tests { assert_eq!(result, &Wallet::null()); assert_error_log(test_name, "consuming_wallet") } - - #[test] - fn null_agent_pending_transaction_id() { - init_test_logging(); - let test_name = "null_agent_pending_transaction_id"; - let mut subject = BlockchainAgentNull::new(); - subject.logger = Logger::new(test_name); - - let result = subject.pending_transaction_id(); - - assert_eq!(result, U256::zero()); - assert_error_log(test_name, "pending_transaction_id"); - } } diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs index 4fffa91c7..7c69878fc 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs @@ -12,7 +12,6 @@ pub struct BlockchainAgentWeb3 { maximum_added_gas_margin: u128, consuming_wallet: Wallet, consuming_wallet_balances: ConsumingWalletBalances, - pending_transaction_id: U256, // TODO: GH-744: This should be changed from U256 to something more generic } impl BlockchainAgent for BlockchainAgentWeb3 { @@ -33,10 +32,6 @@ impl BlockchainAgent for BlockchainAgentWeb3 { fn consuming_wallet(&self) -> &Wallet { &self.consuming_wallet } - - fn pending_transaction_id(&self) -> U256 { - self.pending_transaction_id - } } // 64 * (64 - 12) ... std transaction has data of 64 bytes and 12 bytes are never used with us; @@ -49,7 +44,6 @@ impl BlockchainAgentWeb3 { gas_limit_const_part: u128, consuming_wallet: Wallet, consuming_wallet_balances: ConsumingWalletBalances, - pending_transaction_id: U256, ) -> Self { Self { gas_price_wei, @@ -57,7 +51,6 @@ impl BlockchainAgentWeb3 { consuming_wallet, maximum_added_gas_margin: WEB3_MAXIMAL_GAS_LIMIT_MARGIN, consuming_wallet_balances, - pending_transaction_id, } } } @@ -88,14 +81,12 @@ mod tests { transaction_fee_balance_in_minor_units: U256::from(456_789), masq_token_balance_in_minor_units: U256::from(123_000_000), }; - let pending_transaction_id = U256::from(777); let subject = BlockchainAgentWeb3::new( gas_price_gwei, gas_limit_const_part, consuming_wallet.clone(), consuming_wallet_balances, - pending_transaction_id, ); assert_eq!(subject.agreed_fee_per_computation_unit(), gas_price_gwei); @@ -104,7 +95,6 @@ mod tests { subject.consuming_wallet_balances(), consuming_wallet_balances ); - assert_eq!(subject.pending_transaction_id(), pending_transaction_id) } #[test] @@ -114,13 +104,11 @@ mod tests { transaction_fee_balance_in_minor_units: Default::default(), masq_token_balance_in_minor_units: Default::default(), }; - let nonce = U256::from(55); let agent = BlockchainAgentWeb3::new( 444, 77_777, consuming_wallet, consuming_wallet_balances, - nonce, ); let result = agent.estimated_transaction_fee_total(3); diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs index 099035ade..caeb355ce 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs @@ -26,7 +26,7 @@ pub trait BlockchainAgent: Send { fn consuming_wallet_balances(&self) -> ConsumingWalletBalances; fn agreed_fee_per_computation_unit(&self) -> u128; fn consuming_wallet(&self) -> &Wallet; - fn pending_transaction_id(&self) -> U256; + #[cfg(test)] fn dup(&self) -> Box { diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs index a7af418f6..c84c719dc 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs @@ -15,7 +15,6 @@ pub struct BlockchainAgentMock { consuming_wallet_balances_results: RefCell>, agreed_fee_per_computation_unit_results: RefCell>, consuming_wallet_result_opt: Option, - pending_transaction_id_results: RefCell>, arbitrary_id_stamp_opt: Option, } @@ -38,10 +37,6 @@ impl BlockchainAgent for BlockchainAgentMock { self.consuming_wallet_result_opt.as_ref().unwrap() } - fn pending_transaction_id(&self) -> U256 { - self.pending_transaction_id_results.borrow_mut().remove(0) - } - fn dup(&self) -> Box { intentionally_blank!() } @@ -69,12 +64,5 @@ impl BlockchainAgentMock { self } - pub fn pending_transaction_id_result(self, result: U256) -> Self { - self.pending_transaction_id_results - .borrow_mut() - .push(result); - self - } - set_arbitrary_id_stamp_in_mock_impl!(); } diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index d1a259093..0e1791d56 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -660,7 +660,6 @@ mod tests { "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), 0, ) - .response("0x23".to_string(), 1) .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant_recipient = accountant.start().recipient(); @@ -724,12 +723,6 @@ mod tests { .consuming_wallet(), &consuming_wallet ); - assert_eq!( - blockchain_agent_with_context_msg_actual - .agent - .pending_transaction_id(), - 35.into() - ); assert_eq!( blockchain_agent_with_context_msg_actual .agent @@ -763,14 +756,10 @@ mod tests { let system = System::new("qualified_payables_msg_is_handled_but_fails_on_build_blockchain_agent"); let port = find_free_port(); - // build blockchain agent fails by not providing the fourth response. + // build blockchain agent fails by not providing the third response. let _blockchain_client_server = MBCSBuilder::new(port) .response("0x23".to_string(), 1) .response("0x23".to_string(), 1) - .response( - "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), - 0, - ) .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant_recipient = accountant.start().recipient(); @@ -802,15 +791,15 @@ mod tests { let accountant_recording = accountant_recording_arc.lock().unwrap(); assert_eq!(accountant_recording.len(), 0); - let transaction_id_error = BlockchainAgentBuildError::TransactionID( + let service_fee_balance_error = BlockchainAgentBuildError::ServiceFeeBalance( consuming_wallet.address(), BlockchainError::QueryFailed( - "Transport error: Error(IncompleteMessage) for wallet 0xc4e2…3ac6".to_string(), + "Api error: Transport error: Error(IncompleteMessage)".to_string(), ), ); assert_eq!( error_msg, - format!("Blockchain agent build error: {:?}", transaction_id_error) + format!("Blockchain agent build error: {:?}", service_fee_balance_error) ) } diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 088d909e0..c3e6c936d 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -93,7 +93,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { start_block: BlockNumber, fallback_start_block_number: u64, recipient: Address, - ) -> Box> { + ) -> Box> { let lower_level_interface = self.lower_interface(); let logger = self.logger.clone(); let contract_address = lower_level_interface.get_contract().address(); @@ -151,12 +151,11 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { fn build_blockchain_agent( &self, - // TODO: Change wallet to address in the future consuming_wallet: Wallet, - ) -> Box, Error = BlockchainAgentBuildError>> { + ) -> Box, Error=BlockchainAgentBuildError>> { let wallet_address = consuming_wallet.address(); let gas_limit_const_part = self.gas_limit_const_part; - // TODO: Would it be better to wrap these 4 calls into a single batch call? + // TODO: Would it be better to wrap these 3 calls into a single batch call? let get_gas_price = self.lower_interface().get_gas_price(); let get_transaction_fee_balance = self .lower_interface() @@ -164,8 +163,6 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { let get_service_fee_balance = self .lower_interface() .get_service_fee_balance(wallet_address); - // TODO: GH-744: Remove it from submit_batch call or from here, it's a duplicate - let get_transaction_id = self.lower_interface().get_transaction_id(wallet_address); Box::new( get_gas_price @@ -181,27 +178,17 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { BlockchainAgentBuildError::ServiceFeeBalance(wallet_address, e) }) .and_then(move |masq_token_balance| { - get_transaction_id - .map_err(move |e| { - BlockchainAgentBuildError::TransactionID( - wallet_address, - e, - ) - }) - .and_then(move |pending_transaction_id| { - let blockchain_agent_future_result = - BlockchainAgentFutureResult { - gas_price_wei, - transaction_fee_balance, - masq_token_balance, - pending_transaction_id, - }; - Ok(create_blockchain_agent_web3( - gas_limit_const_part, - blockchain_agent_future_result, - consuming_wallet, - )) - }) + let blockchain_agent_future_result = + BlockchainAgentFutureResult { + gas_price_wei, + transaction_fee_balance, + masq_token_balance, + }; + Ok(create_blockchain_agent_web3( + gas_limit_const_part, + blockchain_agent_future_result, + consuming_wallet, + )) }) }) }), @@ -211,7 +198,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { fn process_transaction_receipts( &self, transaction_hashes: Vec, - ) -> Box, Error = BlockchainError>> { + ) -> Box, Error=BlockchainError>> { Box::new( self.lower_interface() .get_transaction_receipt_in_batch(transaction_hashes) @@ -255,7 +242,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { consuming_wallet: Wallet, fingerprints_recipient: Recipient, affordable_accounts: Vec, - ) -> Box, Error = PayableTransactionError>> + ) -> Box, Error=PayableTransactionError>> { let web3_batch = self.lower_interface().get_web3_batch(); let get_transaction_id = self @@ -627,8 +614,7 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned( - ) { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -653,8 +639,7 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned( - ) { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -676,8 +661,7 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number( - ) { + fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x400", 1) @@ -688,7 +672,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let end_block_nbr = 1024u64; let subject = @@ -718,8 +702,7 @@ mod tests { } #[test] - fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one( - ) { + fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("trash", 1) @@ -763,8 +746,6 @@ mod tests { "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), // 65535 0, ) - // transaction_id - .response("0x23".to_string(), 1) .start(); let chain = Chain::PolyMainnet; let wallet = make_wallet("abc"); @@ -777,10 +758,8 @@ mod tests { let expected_transaction_fee_balance = U256::from(65_520); let expected_masq_balance = U256::from(65_535); - let expected_transaction_id = U256::from(35); let expected_gas_price_wei = 1_000_000_000; assert_eq!(result.consuming_wallet(), &wallet); - assert_eq!(result.pending_transaction_id(), expected_transaction_id); assert_eq!( result.consuming_wallet_balances(), ConsumingWalletBalances { @@ -794,7 +773,7 @@ mod tests { ); let expected_fee_estimation = (3 * (BlockchainInterfaceWeb3::web3_gas_limit_const_part(chain) - + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) + + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) * expected_gas_price_wei) as u128; assert_eq!( result.estimated_transaction_fee_total(3), @@ -880,33 +859,6 @@ mod tests { ); } - #[test] - fn build_of_the_blockchain_agent_fails_on_transaction_id() { - let port = find_free_port(); - let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0) - .response("0xFFF0".to_string(), 0) - .response( - "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), - 0, - ) - .start(); - - let expected_err_factory = |wallet: &Wallet| { - BlockchainAgentBuildError::TransactionID( - wallet.address(), - BlockchainError::QueryFailed( - "Transport error: Error(IncompleteMessage) for wallet 0x0000…6364".to_string(), - ), - ) - }; - - build_of_the_blockchain_agent_fails_on_blockchain_interface_error( - port, - expected_err_factory, - ); - } - #[test] fn process_transaction_receipts_works() { let port = find_free_port(); diff --git a/node/src/blockchain/blockchain_interface/data_structures/errors.rs b/node/src/blockchain/blockchain_interface/data_structures/errors.rs index 8b4e1f914..3084accfb 100644 --- a/node/src/blockchain/blockchain_interface/data_structures/errors.rs +++ b/node/src/blockchain/blockchain_interface/data_structures/errors.rs @@ -81,7 +81,6 @@ pub enum BlockchainAgentBuildError { GasPrice(BlockchainError), TransactionFeeBalance(Address, BlockchainError), ServiceFeeBalance(Address, BlockchainError), - TransactionID(Address, BlockchainError), UninitializedBlockchainInterface, } @@ -99,10 +98,6 @@ impl Display for BlockchainAgentBuildError { "masq balance for our earning wallet {:#x} due to {}", address, blockchain_e )), - Self::TransactionID(address, blockchain_e) => Either::Left(format!( - "transaction id for our earning wallet {:#x} due to {}", - address, blockchain_e - )), Self::UninitializedBlockchainInterface => { Either::Right(BLOCKCHAIN_SERVICE_URL_NOT_SPECIFIED.to_string()) } @@ -227,7 +222,6 @@ mod tests { wallet.address(), BlockchainError::InvalidAddress, ), - BlockchainAgentBuildError::TransactionID(wallet.address(), BlockchainError::InvalidUrl), BlockchainAgentBuildError::UninitializedBlockchainInterface, ]; @@ -246,8 +240,6 @@ mod tests { wallet 0x0000000000000000000000000000000000616263 due to: Blockchain error: Invalid response", "Blockchain agent construction failed at fetching masq balance for our earning wallet \ 0x0000000000000000000000000000000000616263 due to Blockchain error: Invalid address", - "Blockchain agent construction failed at fetching transaction id for our earning wallet \ - 0x0000000000000000000000000000000000616263 due to Blockchain error: Invalid url", BLOCKCHAIN_SERVICE_URL_NOT_SPECIFIED ]) ) diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index 6411cd180..2965e2231 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -36,7 +36,6 @@ pub struct BlockchainAgentFutureResult { pub gas_price_wei: U256, pub transaction_fee_balance: U256, pub masq_token_balance: U256, - pub pending_transaction_id: U256, } pub fn advance_used_nonce(current_nonce: U256) -> U256 { current_nonce @@ -133,7 +132,7 @@ pub fn gas_limit(data: [u8; 68], chain: Chain) -> U256 { ethereum_types::U256::try_from(data.iter().fold(base_gas_limit, |acc, v| { acc + if v == &0u8 { 4 } else { 68 } })) - .expect("Internal error") + .expect("Internal error") } pub fn sign_transaction( @@ -281,7 +280,7 @@ pub fn send_payables_within_batch( pending_nonce: U256, new_fingerprints_recipient: Recipient, accounts: Vec, -) -> Box, Error = PayableTransactionError> + 'static> +) -> Box, Error=PayableTransactionError> + 'static> { debug!( logger, @@ -359,7 +358,6 @@ pub fn create_blockchain_agent_web3( .transaction_fee_balance, masq_token_balance_in_minor_units: blockchain_agent_future_result.masq_token_balance, }, - blockchain_agent_future_result.pending_transaction_id, )) } @@ -431,7 +429,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3_batch = Web3::new(Batch::new(transport)); let pending_nonce = 1; let chain = TEST_DEFAULT_CHAIN; @@ -476,7 +474,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let pending_nonce = 1; let chain = DEFAULT_CHAIN; let gas_price = DEFAULT_GAS_PRICE; @@ -516,7 +514,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3_batch = Web3::new(Batch::new(transport)); let pending_nonce = 1; let chain = DEFAULT_CHAIN; @@ -538,7 +536,7 @@ mod tests { hash: H256::from_str( "94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2", ) - .unwrap(), + .unwrap(), amount, }; assert_eq!(result, expected_hash_and_amount); @@ -552,7 +550,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3_batch = Web3::new(Batch::new(transport)); let chain = DEFAULT_CHAIN; let gas_price = DEFAULT_GAS_PRICE; @@ -579,14 +577,14 @@ mod tests { hash: H256::from_str( "94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2" ) - .unwrap(), + .unwrap(), amount: 1000000000 }, HashAndAmount { hash: H256::from_str( "3811874d2b73cecd51234c94af46bcce918d0cb4de7d946c01d7da606fe761b5" ) - .unwrap(), + .unwrap(), amount: 2000000000 } ] @@ -707,7 +705,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .response("rpc_result".to_string(), 7) @@ -738,7 +736,7 @@ mod tests { new_fingerprints_recipient, accounts.clone(), ) - .wait(); + .wait(); System::current().stop(); system.run(); @@ -756,14 +754,14 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap(), + .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap(), + .unwrap(), amount: accounts_2.balance_wei }, ] @@ -776,7 +774,7 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap() + .unwrap() }) ); assert_eq!( @@ -786,7 +784,7 @@ mod tests { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap() + .unwrap() }) ); let tlh = TestLogHandler::new(); @@ -811,7 +809,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let consuming_wallet_secret_raw_bytes = b"okay-wallet"; let recipient_wallet = make_wallet("blah123"); let unimportant_recipient = Recorder::new().start().recipient(); @@ -836,7 +834,7 @@ mod tests { unimportant_recipient, vec![account], ) - .wait(); + .wait(); assert_eq!( result, @@ -868,7 +866,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let recipient_wallet = make_wallet("unlucky man"); let consuming_wallet = make_wallet("bad_wallet"); let gas_price = U256::from(123_000_000_000u64); @@ -895,7 +893,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .err_response( @@ -936,7 +934,7 @@ mod tests { new_fingerprints_recipient, accounts.clone(), ) - .wait(); + .wait(); System::current().stop(); system.run(); @@ -954,14 +952,14 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap(), + .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap(), + .unwrap(), amount: accounts_2.balance_wei }, ] @@ -1009,7 +1007,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .response("rpc_result".to_string(), 7) @@ -1045,7 +1043,7 @@ mod tests { new_fingerprints_recipient, accounts.clone(), ) - .wait(); + .wait(); System::current().stop(); system.run(); @@ -1063,14 +1061,14 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap(), + .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap(), + .unwrap(), amount: accounts_2.balance_wei }, ] @@ -1083,7 +1081,7 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap() + .unwrap() }) ); assert_eq!(processed_payments[1], ProcessedPayableFallible::Failed(RpcPayableFailure { @@ -1117,7 +1115,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3 = Web3::new(transport.clone()); let chain = DEFAULT_CHAIN; let amount = 11_222_333_444; @@ -1163,7 +1161,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let chain = DEFAULT_CHAIN; let amount = 11_222_333_444; let gas_limit = U256::from(5); @@ -1291,13 +1289,13 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let consuming_wallet = { let key_pair = Bip32EncryptionKeyProvider::from_raw_secret( &decode_hex("97923d8fd8de4a00f912bfb77ef483141dec551bd73ea59343ef5c4aac965d04") .unwrap(), ) - .unwrap(); + .unwrap(); Wallet::from(key_pair) }; let recipient_wallet = { From 5172c82a3401898a21944d98fd807a16eede50dc Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 18 Nov 2024 21:57:12 +1300 Subject: [PATCH 28/56] GH-744: Removed get_gas_price from submit_batch call --- node/src/accountant/mod.rs | 89 +++++----- .../payable_scanner/agent_web3.rs | 9 +- .../payable_scanner/blockchain_agent.rs | 2 - .../payable_scanner/test_utils.rs | 1 - node/src/accountant/scanners/mod.rs | 10 +- node/src/actor_system_factory.rs | 31 ++-- node/src/blockchain/blockchain_bridge.rs | 152 ++++++++---------- .../blockchain_interface_web3/mod.rs | 55 ++++--- .../blockchain/blockchain_interface/mod.rs | 2 +- .../blockchain/blockchain_interface_utils.rs | 112 ++++++------- node/src/blockchain/test_utils.rs | 2 +- 11 files changed, 226 insertions(+), 239 deletions(-) diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index 609181485..7aeff1793 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -743,7 +743,7 @@ impl Accountant { stats_opt, query_results_opt, } - .tmb(context_id) + .tmb(context_id) } fn request_payable_accounts_by_specific_mode( @@ -1032,11 +1032,11 @@ pub fn checked_conversion>(num: T) -> S { politely_checked_conversion(num).unwrap_or_else(|msg| panic!("{}", msg)) } -pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { +pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { (T::from(gwei)).mul(T::from(WEIS_IN_GWEI as u32)) } -pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { +pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { checked_conversion::(wei.div(S::from(WEIS_IN_GWEI as u32))) } @@ -1364,7 +1364,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Receivables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1456,7 +1456,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Payables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1523,7 +1523,8 @@ mod tests { } #[test] - fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge() { + fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge( + ) { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1615,7 +1616,8 @@ mod tests { } #[test] - fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge() { + fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge( + ) { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1763,7 +1765,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1818,7 +1820,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; let second_message = first_message.clone(); let peer_actors = peer_actors_builder() @@ -2009,7 +2011,8 @@ mod tests { } #[test] - fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block() { + fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block( + ) { let more_money_received_params_arc = Arc::new(Mutex::new(vec![])); let commit_params_arc = Arc::new(Mutex::new(vec![])); let set_by_guest_transaction_params_arc = Arc::new(Mutex::new(vec![])); @@ -2045,7 +2048,8 @@ mod tests { let system = System::new("accountant_uses_receivables_dao_to_process_received_payments"); let subject = accountant.start(); let mut payments_and_start_block = make_empty_payments_and_start_block(); - payments_and_start_block.payments = vec![expected_receivable_1.clone(), expected_receivable_2.clone()]; + payments_and_start_block.payments = + vec![expected_receivable_1.clone(), expected_receivable_2.clone()]; payments_and_start_block.new_start_block = 123456789; subject .try_send(ReceivedPayments { @@ -2708,7 +2712,7 @@ mod tests { addr.try_send(ScanForPayables { response_skeleton_opt: None, }) - .unwrap(); + .unwrap(); // We ignored the second ScanForPayables message because the first message meant a scan // was already in progress; now let's make it look like that scan has ended so that we @@ -2721,7 +2725,7 @@ mod tests { .mark_as_ended(&Logger::new("irrelevant")) }), }) - .unwrap(); + .unwrap(); addr.try_send(message_after.clone()).unwrap(); system.run(); let recording = blockchain_bridge_recording.lock().unwrap(); @@ -3436,10 +3440,10 @@ mod tests { init_test_logging(); let port = find_free_port(); let pending_tx_hash_1 = - H256::from_str("713332975a17b82439312ddff602d254f21b7d312dce3a8fbfd83587fe361e15") + H256::from_str("e66814b2812a80d619813f51aa999c0df84eb79d10f4923b2b7667b30d6b33d3") .unwrap(); let pending_tx_hash_2 = - H256::from_str("caefcf3d42b45f948e8e823e4ae959811e50b219640c3f1580d4471e9b501f1b") + H256::from_str("0288ef000581b3bca8a2017eac9aea696366f8f1b7437f18d1aad57bccb7032c") .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) // Blockchain Agent Gas Price @@ -3451,8 +3455,6 @@ mod tests { "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), 0, ) - // gas_price - .response("0x3B9ACA00".to_string(), 1) // Submit payments to blockchain .response("0xFFF0".to_string(), 1) .begin_batch() @@ -3769,16 +3771,16 @@ mod tests { ); let log_handler = TestLogHandler::new(); log_handler.exists_log_containing( - "WARN: Accountant: Broken transactions 0x713332975a17b82439312ddff602d254f21b7d312\ - dce3a8fbfd83587fe361e15 marked as an error. You should take over the care of those to make sure \ + "WARN: Accountant: Broken transactions 0xe66814b2812a80d619813f51aa999c0df84eb79d10f\ + 4923b2b7667b30d6b33d3 marked as an error. You should take over the care of those to make sure \ your debts are going to be settled properly. At the moment, there is no automated process \ fixing that without your assistance"); - log_handler.exists_log_matching("INFO: Accountant: Transaction 0xcaefcf3d42b45f948e8e823e4ae\ - 959811e50b219640c3f1580d4471e9b501f1b has been added to the blockchain; detected locally at \ + log_handler.exists_log_matching("INFO: Accountant: Transaction 0x0288ef000581b3bca8a2017eac9\ + aea696366f8f1b7437f18d1aad57bccb7032c has been added to the blockchain; detected locally at \ attempt 4 at \\d{2,}ms after its sending"); log_handler.exists_log_containing( - "INFO: Accountant: Transactions 0xcaefcf3d42b45f948e8e823e4ae959811e50b2\ - 19640c3f1580d4471e9b501f1b completed their confirmation process succeeding", + "INFO: Accountant: Transactions 0x0288ef000581b3bca8a2017eac9aea696366f8f1b7437f18d1aad5\ + 7bccb7032c completed their confirmation process succeeding", ); } @@ -4028,7 +4030,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4112,7 +4114,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4175,7 +4177,7 @@ mod tests { }), query_results_opt: None } - .tmb(context_id) + .tmb(context_id) ) } @@ -4252,12 +4254,12 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 58, pending_payable_hash_opt: None - }, ]), + },]), receivable_opt: Some(vec![UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), age_s: extracted_receivable_ages[0], balance_gwei: 3_788_455 - }, ]) + },]) }), } ); @@ -4418,7 +4420,7 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 5, pending_payable_hash_opt: None - }, ]), + },]), receivable_opt: Some(vec![ UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), @@ -4607,7 +4609,8 @@ mod tests { expected = "Broken code: PayableAccount with less than 1 gwei passed through db query \ constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 8686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei() { + fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei( + ) { let payable_accounts_retrieved = vec![PayableAccount { wallet: make_wallet("abcd123"), balance_wei: 8_686_005, @@ -4643,7 +4646,8 @@ mod tests { expected = "Broken code: ReceivableAccount with balance between 1 and 0 gwei passed through \ db query constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 7686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei() { + fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei( + ) { let receivable_accounts_retrieved = vec![ReceivableAccount { wallet: make_wallet("abcd123"), balance_wei: 7_686_005, @@ -4882,10 +4886,11 @@ pub mod exportable_test_parts { } } - fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao() -> ShouldWeRunTheTest { + fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao( + ) -> ShouldWeRunTheTest { fn skip_down_to_first_line_saying_new_delinquencies( - previous: impl Iterator, - ) -> impl Iterator { + previous: impl Iterator, + ) -> impl Iterator { previous .skip_while(|line| { let adjusted_line: String = line @@ -4896,7 +4901,7 @@ pub mod exportable_test_parts { }) .skip(1) } - fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { + fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { fn yield_if_contains_semicolon(line: &str) -> Option { line.contains(';').then(|| line.to_string()) } @@ -4935,13 +4940,13 @@ pub mod exportable_test_parts { skip_down_to_first_line_saying_new_delinquencies( lines_with_cut_fn_trait_definition, ) - .take_while(|line| { - let adjusted_line: String = line - .chars() - .skip_while(|char| char.is_whitespace()) - .collect(); - !adjusted_line.starts_with("fn") - }); + .take_while(|line| { + let adjusted_line: String = line + .chars() + .skip_while(|char| char.is_whitespace()) + .collect(); + !adjusted_line.starts_with("fn") + }); assert_is_not_trait_definition(assumed_implemented_function_body) } fn user_defined_functions_detected(line_undivided_fn_body: &str) -> bool { diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs index 7c69878fc..c31c7ebbb 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs @@ -3,7 +3,6 @@ use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; -use web3::types::U256; #[derive(Debug, Clone)] pub struct BlockchainAgentWeb3 { @@ -104,12 +103,8 @@ mod tests { transaction_fee_balance_in_minor_units: Default::default(), masq_token_balance_in_minor_units: Default::default(), }; - let agent = BlockchainAgentWeb3::new( - 444, - 77_777, - consuming_wallet, - consuming_wallet_balances, - ); + let agent = + BlockchainAgentWeb3::new(444, 77_777, consuming_wallet, consuming_wallet_balances); let result = agent.estimated_transaction_fee_total(3); diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs index caeb355ce..70918ed77 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs @@ -3,7 +3,6 @@ use crate::arbitrary_id_stamp_in_trait; use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; -use web3::types::U256; // Table of chains by // @@ -27,7 +26,6 @@ pub trait BlockchainAgent: Send { fn agreed_fee_per_computation_unit(&self) -> u128; fn consuming_wallet(&self) -> &Wallet; - #[cfg(test)] fn dup(&self) -> Box { intentionally_blank!() diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs index c84c719dc..ee1706b36 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs @@ -7,7 +7,6 @@ use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp; use crate::{arbitrary_id_stamp_in_trait_impl, set_arbitrary_id_stamp_in_mock_impl}; -use ethereum_types::U256; use std::cell::RefCell; #[derive(Default)] diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index f992a9d36..52fea5877 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -321,7 +321,7 @@ impl PayableScanner { logger: &Logger, ) -> Vec { fn pass_payables_and_drop_points( - qp_tp: impl Iterator, + qp_tp: impl Iterator, ) -> Vec { let (payables, _) = qp_tp.unzip::<_, _, Vec, Vec<_>>(); payables @@ -1587,9 +1587,9 @@ mod tests { (vals.intruder_for_hash_2, 5), (vals.common_hash_3, 6), ] - .iter() - .map(|(hash, _rowid)| *hash) - .collect::>(); + .iter() + .map(|(hash, _rowid)| *hash) + .collect::>(); let result = PayableScanner::is_symmetrical( pending_payables_ref_from_blockchain_bridge, @@ -2475,7 +2475,7 @@ mod tests { result, PendingPayableScanReport { still_pending: vec![], - failures: vec![PendingPayableId::new(777777, hash, )], + failures: vec![PendingPayableId::new(777777, hash,)], confirmed: vec![] } ); diff --git a/node/src/actor_system_factory.rs b/node/src/actor_system_factory.rs index 189d1fd71..70f00c92b 100644 --- a/node/src/actor_system_factory.rs +++ b/node/src/actor_system_factory.rs @@ -256,7 +256,7 @@ impl ActorSystemFactoryToolsReal { r.try_send(NewPublicIp { new_ip: new_public_ip, }) - .expect("NewPublicIp recipient is dead") + .expect("NewPublicIp recipient is dead") }); } @@ -635,8 +635,11 @@ where mod tests { use super::*; use crate::accountant::exportable_test_parts::test_accountant_is_constructed_with_upgraded_db_connection_recognizing_our_extra_sqlite_functions; - use crate::accountant::{PaymentsAndStartBlock, ReceivedPayments, DEFAULT_PENDING_TOO_LONG_SEC}; + use crate::accountant::{ + PaymentsAndStartBlock, ReceivedPayments, DEFAULT_PENDING_TOO_LONG_SEC, + }; use crate::blockchain::blockchain_bridge::RetrieveTransactions; + use crate::blockchain::blockchain_interface::data_structures::BlockchainTransaction; use crate::bootstrapper::{Bootstrapper, RealUser}; use crate::db_config::persistent_configuration::PersistentConfigurationReal; use crate::node_test_utils::{ @@ -654,6 +657,7 @@ mod tests { use crate::sub_lib::peer_actors::StartMessage; use crate::sub_lib::stream_handler_pool::TransmitDataMsg; use crate::sub_lib::ui_gateway::UiGatewayConfig; + use crate::sub_lib::wallet::Wallet; use crate::test_utils::actor_system_factory::BannedCacheLoaderMock; use crate::test_utils::automap_mocks::{AutomapControlFactoryMock, AutomapControlMock}; use crate::test_utils::make_wallet; @@ -710,8 +714,6 @@ mod tests { use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; - use crate::blockchain::blockchain_interface::data_structures::BlockchainTransaction; - use crate::sub_lib::wallet::Wallet; struct LogRecipientSetterNull {} @@ -1725,7 +1727,8 @@ mod tests { } #[test] - fn prepare_initial_messages_generates_no_consuming_wallet_balance_if_no_consuming_wallet_is_specified() { + fn prepare_initial_messages_generates_no_consuming_wallet_balance_if_no_consuming_wallet_is_specified( + ) { let actor_factory = ActorFactoryMock::new(); let parameters = actor_factory.make_parameters(); let config = BootstrapperConfig { @@ -1977,7 +1980,8 @@ mod tests { } #[test] - fn accountant_is_constructed_with_upgraded_db_connection_recognizing_our_extra_sqlite_functions() { + fn accountant_is_constructed_with_upgraded_db_connection_recognizing_our_extra_sqlite_functions( + ) { let act = |bootstrapper_config: BootstrapperConfig, db_initializer: DbInitializerReal, banned_cache_loader: BannedCacheLoaderMock, @@ -2070,11 +2074,16 @@ mod tests { assert_eq!(system.run(), 0); let recording = accountant_recording.lock().unwrap(); let received_payments_message = recording.get_record::(0); - assert_eq!(received_payments_message.payments_and_start_block, - PaymentsAndStartBlock { - payments: vec![BlockchainTransaction { block_number: 2000, from: Wallet::new("0x0000000000006561726e696e675f77616c6c6574"), wei_amount: 996000000 }], - new_start_block: 1000000000 - } + assert_eq!( + received_payments_message.payments_and_start_block, + PaymentsAndStartBlock { + payments: vec![BlockchainTransaction { + block_number: 2000, + from: Wallet::new("0x0000000000006561726e696e675f77616c6c6574"), + wei_amount: 996000000 + }], + new_start_block: 1000000000 + } ); } diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 0e1791d56..7163eb155 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -247,7 +247,7 @@ impl BlockchainBridge { fn handle_qualified_payable_msg( &mut self, incoming_message: QualifiedPayablesMessage, - ) -> Box> { + ) -> Box> { // TODO rewrite this into a batch call as soon as GH-629 gets into master let accountant_recipient = self.payable_payments_setup_subs_opt.clone(); return Box::new( @@ -272,7 +272,7 @@ impl BlockchainBridge { fn handle_outbound_payments_instructions( &mut self, msg: OutboundPaymentsInstructions, - ) -> Box> { + ) -> Box> { let skeleton_opt = msg.response_skeleton_opt; let sent_payable_subs = self .sent_payable_subs_opt @@ -307,7 +307,7 @@ impl BlockchainBridge { fn handle_retrieve_transactions( &mut self, msg: RetrieveTransactions, - ) -> Box> { + ) -> Box> { let (start_block_nbr, max_block_count) = { let persistent_config_lock = self .persistent_config_arc @@ -344,14 +344,18 @@ impl BlockchainBridge { msg.recipient.address(), ) .map_err(move |e| { - if let Some(max_block_count) = BlockchainBridge::extract_max_block_count(e.clone()) { - match persistent_config_arc.lock().expect("Unable to lock persistent config in BlockchainBridge").set_max_block_count(Some(max_block_count)) + if let Some(max_block_count) = + BlockchainBridge::extract_max_block_count(e.clone()) + { + match persistent_config_arc + .lock() + .expect("Unable to lock persistent config in BlockchainBridge") + .set_max_block_count(Some(max_block_count)) { Ok(()) => { debug!( logger, - "Updated max_block_count to {} in database.", - max_block_count + "Updated max_block_count to {} in database.", max_block_count ); } Err(e) => { @@ -385,7 +389,7 @@ impl BlockchainBridge { fn handle_request_transaction_receipts( &mut self, msg: RequestTransactionReceipts, - ) -> Box> { + ) -> Box> { let logger = self.logger.clone(); let accountant_recipient = self .pending_payable_confirmation @@ -436,7 +440,7 @@ impl BlockchainBridge { fn handle_scan_future(&mut self, handler: F, scan_type: ScanType, msg: M) where - F: FnOnce(&mut BlockchainBridge, M) -> Box>, + F: FnOnce(&mut BlockchainBridge, M) -> Box>, M: SkeletonOptHolder, { let skeleton_opt = msg.skeleton_opt(); @@ -462,7 +466,7 @@ impl BlockchainBridge { &self, agent: Box, affordable_accounts: Vec, - ) -> Box, Error=PayableTransactionError>> + ) -> Box, Error = PayableTransactionError>> { let new_fingerprints_recipient = self.new_fingerprints_recipient(); let logger = self.logger.clone(); @@ -470,7 +474,7 @@ impl BlockchainBridge { self.blockchain_interface.submit_payables_in_batch( logger, chain, - agent.consuming_wallet().clone(), + agent, new_fingerprints_recipient, affordable_accounts, ) @@ -525,21 +529,29 @@ impl SubsFactory for BlockchainBridgeSub mod tests { use super::*; use crate::accountant::db_access_objects::payable_dao::PayableAccount; + use crate::accountant::db_access_objects::pending_payable_dao::PendingPayable; use crate::accountant::db_access_objects::utils::from_time_t; + use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::test_utils::BlockchainAgentMock; use crate::accountant::scanners::test_utils::{ make_empty_payments_and_start_block, protect_payables_in_test, }; use crate::accountant::test_utils::{make_payable_account, make_pending_payable_fingerprint}; + use crate::blockchain::blockchain_interface::data_structures::errors::PayableTransactionError::TransactionID; use crate::blockchain::blockchain_interface::data_structures::errors::{ BlockchainAgentBuildError, PayableTransactionError, }; + use crate::blockchain::blockchain_interface::data_structures::ProcessedPayableFallible::Correct; use crate::blockchain::blockchain_interface::data_structures::{ BlockchainTransaction, RetrievedBlockchainTransactions, }; - use crate::blockchain::test_utils::{make_tx_hash, make_blockchain_interface_web3, BlockchainInterfaceMock, ReceiptResponseBuilder}; + use crate::blockchain::test_utils::{ + make_blockchain_interface_web3, make_tx_hash, BlockchainInterfaceMock, + ReceiptResponseBuilder, + }; use crate::db_config::persistent_configuration::PersistentConfigError; use crate::match_every_type_id; use crate::node_test_utils::check_timestamp; + use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::test_utils::persistent_configuration_mock::PersistentConfigurationMock; use crate::test_utils::recorder::{ make_accountant_subs_from_recorder, make_recorder, peer_actors_builder, @@ -547,14 +559,20 @@ mod tests { use crate::test_utils::recorder_stop_conditions::StopCondition; use crate::test_utils::recorder_stop_conditions::StopConditions; use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp; - use crate::test_utils::unshared_test_utils::{assert_on_initialization_with_panic_on_migration, prove_that_crash_request_handler_is_hooked_up, AssertionsMessage, configure_default_persistent_config, ZERO}; + use crate::test_utils::unshared_test_utils::{ + assert_on_initialization_with_panic_on_migration, configure_default_persistent_config, + prove_that_crash_request_handler_is_hooked_up, AssertionsMessage, ZERO, + }; use crate::test_utils::{make_paying_wallet, make_wallet}; use actix::System; - use ethereum_types::{U64}; + use ethereum_types::U64; use masq_lib::messages::ScanType; use masq_lib::test_utils::logging::init_test_logging; use masq_lib::test_utils::logging::TestLogHandler; - use masq_lib::test_utils::utils::{ensure_node_home_directory_exists, LogObject, TEST_DEFAULT_CHAIN}; + use masq_lib::test_utils::mock_blockchain_client_server::MBCSBuilder; + use masq_lib::test_utils::utils::{ + ensure_node_home_directory_exists, LogObject, TEST_DEFAULT_CHAIN, + }; use masq_lib::utils::find_free_port; use std::any::TypeId; use std::path::Path; @@ -562,12 +580,6 @@ mod tests { use std::sync::{Arc, Mutex}; use std::time::{Duration, SystemTime}; use web3::types::{BlockNumber, TransactionReceipt, H160}; - use masq_lib::test_utils::mock_blockchain_client_server::MBCSBuilder; - use crate::accountant::db_access_objects::pending_payable_dao::PendingPayable; - use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::test_utils::BlockchainAgentMock; - use crate::blockchain::blockchain_interface::data_structures::errors::PayableTransactionError::{GasPriceQueryFailed, TransactionID}; - use crate::blockchain::blockchain_interface::data_structures::ProcessedPayableFallible::Correct; - use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; impl Handler> for BlockchainBridge { type Result = (); @@ -605,7 +617,7 @@ mod tests { addr.try_send(BindMessage { peer_actors: peer_actors_builder().build(), }) - .unwrap(); + .unwrap(); System::current().stop(); system.run(); @@ -648,7 +660,8 @@ mod tests { } #[test] - fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant() { + fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant( + ) { let system = System::new( "qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant", ); @@ -799,19 +812,22 @@ mod tests { ); assert_eq!( error_msg, - format!("Blockchain agent build error: {:?}", service_fee_balance_error) + format!( + "Blockchain agent build error: {:?}", + service_fee_balance_error + ) ) } #[test] - fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant() { + fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant( + ) { let system = System::new( "handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant", ); let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x20".to_string(), 1) - .response("0x7B".to_string(), 1) .begin_batch() .response("rpc result".to_string(), 1) .end_batch() @@ -842,6 +858,7 @@ mod tests { let agent_id_stamp = ArbitraryIdStamp::new(); let agent = BlockchainAgentMock::default() .set_arbitrary_id_stamp(agent_id_stamp) + .agreed_fee_per_computation_unit_result(123) .consuming_wallet_result(consuming_wallet); send_bind_message!(subject_subs, peer_actors); @@ -872,7 +889,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap() + .unwrap() })]), response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, @@ -888,7 +905,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -904,7 +921,6 @@ mod tests { // To make submit_batch failed we didn't provide any responses for batch calls let _blockchain_client_server = MBCSBuilder::new(port) .response("0x20".to_string(), 1) - .response("0x7B".to_string(), 1) .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant_addr = accountant @@ -929,7 +945,9 @@ mod tests { pending_payable_opt: None, }]; let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let agent = BlockchainAgentMock::default().consuming_wallet_result(consuming_wallet); + let agent = BlockchainAgentMock::default() + .consuming_wallet_result(consuming_wallet) + .agreed_fee_per_computation_unit_result(123); send_bind_message!(subject_subs, peer_actors); let _ = addr @@ -962,7 +980,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -987,7 +1005,6 @@ mod tests { let test_name = "process_payments_works"; let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x01".to_string(), 1) .response("0x01".to_string(), 1) .begin_batch() .response("rpc_result".to_string(), 7) @@ -1000,7 +1017,9 @@ mod tests { let accounts_2 = make_payable_account(2); let accounts = vec![accounts_1.clone(), accounts_2.clone()]; let system = System::new(test_name); - let agent = BlockchainAgentMock::default().consuming_wallet_result(consuming_wallet); + let agent = BlockchainAgentMock::default() + .consuming_wallet_result(consuming_wallet) + .agreed_fee_per_computation_unit_result(1); let msg = OutboundPaymentsInstructions::new(accounts, Box::new(agent), None); let persistent_config = PersistentConfigurationMock::new(); let mut subject = BlockchainBridge::new( @@ -1027,7 +1046,7 @@ mod tests { hash: H256::from_str( "cc73f3d5fe9fc3dac28b510ddeb157b0f8030b201e809014967396cdf365488a" ) - .unwrap() + .unwrap() }) ); assert_eq!( @@ -1037,7 +1056,7 @@ mod tests { hash: H256::from_str( "891d9ffa838aedc0bb2f6f7e9737128ce98bb33d07b4c8aa5645871e20d6cd13" ) - .unwrap() + .unwrap() }) ); let recording = accountant_recording.lock().unwrap(); @@ -1054,7 +1073,9 @@ mod tests { let blockchain_interface_web3 = make_blockchain_interface_web3(Some(port)); let consuming_wallet = make_paying_wallet(b"consuming_wallet"); let system = System::new(test_name); - let agent = BlockchainAgentMock::default().consuming_wallet_result(consuming_wallet); + let agent = BlockchainAgentMock::default() + .consuming_wallet_result(consuming_wallet) + .agreed_fee_per_computation_unit_result(123); let msg = OutboundPaymentsInstructions::new(vec![], Box::new(agent), None); let persistent_config = configure_default_persistent_config(ZERO); let mut subject = BlockchainBridge::new( @@ -1084,47 +1105,6 @@ mod tests { assert_eq!(recording.len(), 0); } - #[test] - fn process_payments_fails_on_missing_gas_price() { - let test_name = "process_payments_fails_on_missing_gas_price"; - let port = find_free_port(); - let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x20".to_string(), 0) - .response("Trash Gas Price".to_string(), 0) - .start(); - let blockchain_interface_web3 = make_blockchain_interface_web3(Some(port)); - let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let system = System::new(test_name); - let agent = BlockchainAgentMock::default().consuming_wallet_result(consuming_wallet); - let msg = OutboundPaymentsInstructions::new(vec![], Box::new(agent), None); - let persistent_config = PersistentConfigurationMock::new(); - let mut subject = BlockchainBridge::new( - Box::new(blockchain_interface_web3), - Arc::new(Mutex::new(persistent_config)), - false, - ); - let (accountant, _, accountant_recording) = make_recorder(); - subject - .pending_payable_confirmation - .new_pp_fingerprints_sub_opt = Some(accountant.start().recipient()); - - let result = subject - .process_payments(msg.agent, msg.affordable_accounts) - .wait(); - - System::current().stop(); - system.run(); - let error_result = result.unwrap_err(); - assert_eq!( - error_result, - GasPriceQueryFailed(BlockchainError::QueryFailed( - "Decoder error: Error(\"0x prefix is missing\", line: 0, column: 0)".to_string() - )) - ); - let recording = accountant_recording.lock().unwrap(); - assert_eq!(recording.len(), 0); - } - fn assert_sending_error(error: &PayableTransactionError, error_msg: &str) { if let PayableTransactionError::Sending { msg, .. } = error { assert!( @@ -1270,7 +1250,8 @@ mod tests { } #[test] - fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort() { + fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort( + ) { init_test_logging(); let port = find_free_port(); let block_number = U64::from(4545454); @@ -1657,8 +1638,7 @@ mod tests { .response(expected_response_logs, 1) .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); - let accountant_addr = - accountant.system_stop_conditions(match_every_type_id!(ScanError)); + let accountant_addr = accountant.system_stop_conditions(match_every_type_id!(ScanError)); let earning_wallet = make_wallet("earning_wallet"); let mut blockchain_interface = make_blockchain_interface_web3(Some(port)); blockchain_interface.logger = logger; @@ -1717,8 +1697,7 @@ mod tests { .err_response(-32005, "Blockheight too far in the past. Check params passed to eth_getLogs or eth_call requests.Range of blocks allowed for your plan: 1000", 0) .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); - let accountant = - accountant.system_stop_conditions(match_every_type_id!(ScanError)); + let accountant = accountant.system_stop_conditions(match_every_type_id!(ScanError)); let earning_wallet = make_wallet("earning_wallet"); let blockchain_interface = make_blockchain_interface_web3(Some(port)); let persistent_config = PersistentConfigurationMock::new() @@ -1786,7 +1765,9 @@ mod tests { .max_block_count_result(Err(PersistentConfigError::DatabaseError( "my tummy hurts".to_string(), ))) - .set_max_block_count_result(Err(PersistentConfigError::DatabaseError("my brain hurst".to_string()))); + .set_max_block_count_result(Err(PersistentConfigError::DatabaseError( + "my brain hurst".to_string(), + ))); let subject = BlockchainBridge::new( Box::new(blockchain_interface), Arc::new(Mutex::new(persistent_config)), @@ -1933,7 +1914,8 @@ mod tests { &ScanError { scan_type: ScanType::Receivables, response_skeleton_opt: msg.response_skeleton_opt, - msg: "Error while retrieving transactions: QueryFailed(\"My tummy hurts\")".to_string() + msg: "Error while retrieving transactions: QueryFailed(\"My tummy hurts\")" + .to_string() } ); assert_eq!(accountant_recording.len(), 1); @@ -2063,7 +2045,7 @@ pub mod exportable_test_parts { use crate::test_utils::unshared_test_utils::SubsFactoryTestAddrLeaker; impl SubsFactory - for SubsFactoryTestAddrLeaker + for SubsFactoryTestAddrLeaker { fn make(&self, addr: &Addr) -> BlockchainBridgeSubs { self.send_leaker_msg_and_return_meaningless_subs( diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index c3e6c936d..4a5ff7a7b 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -93,7 +93,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { start_block: BlockNumber, fallback_start_block_number: u64, recipient: Address, - ) -> Box> { + ) -> Box> { let lower_level_interface = self.lower_interface(); let logger = self.logger.clone(); let contract_address = lower_level_interface.get_contract().address(); @@ -152,7 +152,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { fn build_blockchain_agent( &self, consuming_wallet: Wallet, - ) -> Box, Error=BlockchainAgentBuildError>> { + ) -> Box, Error = BlockchainAgentBuildError>> { let wallet_address = consuming_wallet.address(); let gas_limit_const_part = self.gas_limit_const_part; // TODO: Would it be better to wrap these 3 calls into a single batch call? @@ -198,7 +198,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { fn process_transaction_receipts( &self, transaction_hashes: Vec, - ) -> Box, Error=BlockchainError>> { + ) -> Box, Error = BlockchainError>> { Box::new( self.lower_interface() .get_transaction_receipt_in_batch(transaction_hashes) @@ -239,37 +239,32 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { &self, logger: Logger, chain: Chain, - consuming_wallet: Wallet, + agent: Box, fingerprints_recipient: Recipient, affordable_accounts: Vec, - ) -> Box, Error=PayableTransactionError>> + ) -> Box, Error = PayableTransactionError>> { + let consuming_wallet = agent.consuming_wallet().clone(); let web3_batch = self.lower_interface().get_web3_batch(); let get_transaction_id = self .lower_interface() .get_transaction_id(consuming_wallet.address()); - // We are not relying on Database and fetching the values straight from the blockchain. - // Modify according to the Payment adjusters new design - let get_gas_price = self.lower_interface().get_gas_price(); + let gas_price_wei = agent.agreed_fee_per_computation_unit(); Box::new( get_transaction_id .map_err(PayableTransactionError::TransactionID) .and_then(move |pending_nonce| { - get_gas_price - .map_err(PayableTransactionError::GasPriceQueryFailed) - .and_then(move |gas_price_wei| { - send_payables_within_batch( - logger, - chain, - web3_batch, - consuming_wallet, - gas_price_wei, - pending_nonce, - fingerprints_recipient, - affordable_accounts, - ) - }) + send_payables_within_batch( + logger, + chain, + web3_batch, + consuming_wallet, + gas_price_wei, + pending_nonce, + fingerprints_recipient, + affordable_accounts, + ) }), ) } @@ -614,7 +609,8 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned() { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -639,7 +635,8 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned() { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -661,7 +658,8 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number() { + fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x400", 1) @@ -672,7 +670,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let end_block_nbr = 1024u64; let subject = @@ -702,7 +700,8 @@ mod tests { } #[test] - fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one() { + fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("trash", 1) @@ -773,7 +772,7 @@ mod tests { ); let expected_fee_estimation = (3 * (BlockchainInterfaceWeb3::web3_gas_limit_const_part(chain) - + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) + + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) * expected_gas_price_wei) as u128; assert_eq!( result.estimated_transaction_fee_total(3), diff --git a/node/src/blockchain/blockchain_interface/mod.rs b/node/src/blockchain/blockchain_interface/mod.rs index 6873443bd..fda6157ab 100644 --- a/node/src/blockchain/blockchain_interface/mod.rs +++ b/node/src/blockchain/blockchain_interface/mod.rs @@ -50,7 +50,7 @@ pub trait BlockchainInterface { &self, logger: Logger, chain: Chain, - consuming_wallet: Wallet, + agent: Box, fingerprints_recipient: Recipient, affordable_accounts: Vec, ) -> Box, Error = PayableTransactionError>>; diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index 2965e2231..b8cbd4c46 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -132,7 +132,7 @@ pub fn gas_limit(data: [u8; 68], chain: Chain) -> U256 { ethereum_types::U256::try_from(data.iter().fold(base_gas_limit, |acc, v| { acc + if v == &0u8 { 4 } else { 68 } })) - .expect("Internal error") + .expect("Internal error") } pub fn sign_transaction( @@ -142,7 +142,7 @@ pub fn sign_transaction( consuming_wallet: Wallet, amount: u128, nonce: U256, - gas_price_in_wei: U256, + gas_price_in_wei: u128, ) -> SignedTransaction { let data = sign_transaction_data(amount, recipient_wallet); let gas_limit = gas_limit(data, chain); @@ -151,7 +151,7 @@ pub fn sign_transaction( nonce: Some(nonce), to: Some(chain.rec().contract), gas: gas_limit, - gas_price: Some(gas_price_in_wei), + gas_price: Some(U256::from(gas_price_in_wei)), value: ethereum_types::U256::zero(), data: Bytes(data.to_vec()), chain_id: Some(chain.rec().num_chain_id), @@ -190,7 +190,7 @@ pub fn sign_and_append_payment( consuming_wallet: Wallet, amount: u128, nonce: U256, - gas_price_in_wei: U256, + gas_price_in_wei: u128, ) -> H256 { let signed_tx = sign_transaction( chain, @@ -215,7 +215,7 @@ pub fn handle_new_transaction( web3_batch: Web3>, consuming_wallet: Wallet, nonce: U256, - gas_price_in_wei: U256, + gas_price_in_wei: u128, account: PayableAccount, ) -> HashAndAmount { let hash = sign_and_append_payment( @@ -238,7 +238,7 @@ pub fn sign_and_append_multiple_payments( chain: Chain, web3_batch: Web3>, consuming_wallet: Wallet, - gas_price_in_wei: U256, + gas_price_in_wei: u128, mut pending_nonce: U256, accounts: Vec, ) -> Vec { @@ -276,11 +276,11 @@ pub fn send_payables_within_batch( chain: Chain, web3_batch: Web3>, consuming_wallet: Wallet, - gas_price_in_wei: U256, + gas_price_in_wei: u128, pending_nonce: U256, new_fingerprints_recipient: Recipient, accounts: Vec, -) -> Box, Error=PayableTransactionError> + 'static> +) -> Box, Error = PayableTransactionError> + 'static> { debug!( logger, @@ -316,7 +316,7 @@ pub fn send_payables_within_batch( info!( logger, "{}", - transmission_log(chain, &accounts, gas_price_in_wei.as_u128()) + transmission_log(chain, &accounts, gas_price_in_wei) ); return Box::new( @@ -429,7 +429,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3_batch = Web3::new(Batch::new(transport)); let pending_nonce = 1; let chain = TEST_DEFAULT_CHAIN; @@ -443,7 +443,7 @@ mod tests { consuming_wallet, account.balance_wei, pending_nonce.into(), - U256::from(gas_price * 1_000_000_000), + (gas_price * 1_000_000_000) as u128, ); append_signed_transaction_to_batch(web3_batch.clone(), signed_transaction.raw_transaction); @@ -474,7 +474,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let pending_nonce = 1; let chain = DEFAULT_CHAIN; let gas_price = DEFAULT_GAS_PRICE; @@ -489,7 +489,7 @@ mod tests { consuming_wallet, account.balance_wei, pending_nonce.into(), - U256::from(gas_price * 1_000_000_000), + (gas_price * 1_000_000_000) as u128, ); let mut batch_result = web3_batch.eth().transport().submit_batch().wait().unwrap(); @@ -514,7 +514,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3_batch = Web3::new(Batch::new(transport)); let pending_nonce = 1; let chain = DEFAULT_CHAIN; @@ -528,7 +528,7 @@ mod tests { web3_batch, consuming_wallet, pending_nonce.into(), - U256::from(gas_price * 1_000_000_000), + (gas_price * 1_000_000_000) as u128, account, ); @@ -536,7 +536,7 @@ mod tests { hash: H256::from_str( "94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2", ) - .unwrap(), + .unwrap(), amount, }; assert_eq!(result, expected_hash_and_amount); @@ -550,7 +550,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3_batch = Web3::new(Batch::new(transport)); let chain = DEFAULT_CHAIN; let gas_price = DEFAULT_GAS_PRICE; @@ -565,7 +565,7 @@ mod tests { chain, web3_batch, consuming_wallet, - U256::from(gas_price * 1_000_000_000), + (gas_price * 1_000_000_000) as u128, pending_nonce.into(), accounts, ); @@ -577,14 +577,14 @@ mod tests { hash: H256::from_str( "94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2" ) - .unwrap(), + .unwrap(), amount: 1000000000 }, HashAndAmount { hash: H256::from_str( "3811874d2b73cecd51234c94af46bcce918d0cb4de7d946c01d7da606fe761b5" ) - .unwrap(), + .unwrap(), amount: 2000000000 } ] @@ -705,7 +705,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .response("rpc_result".to_string(), 7) @@ -717,7 +717,7 @@ mod tests { let logger = Logger::new(test_name); let chain = DEFAULT_CHAIN; let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let gas_price = U256::from(1_000_000_000); + let gas_price = 1_000_000_000; let pending_nonce: U256 = 1.into(); let new_fingerprints_recipient = accountant.start().recipient(); let accounts_1 = make_payable_account(1); @@ -731,12 +731,12 @@ mod tests { chain, web3_batch, consuming_wallet.clone(), - gas_price.clone(), + gas_price, pending_nonce, new_fingerprints_recipient, accounts.clone(), ) - .wait(); + .wait(); System::current().stop(); system.run(); @@ -754,14 +754,14 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap(), + .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap(), + .unwrap(), amount: accounts_2.balance_wei }, ] @@ -774,7 +774,7 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap() + .unwrap() }) ); assert_eq!( @@ -784,7 +784,7 @@ mod tests { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap() + .unwrap() }) ); let tlh = TestLogHandler::new(); @@ -798,7 +798,7 @@ mod tests { ); tlh.exists_log_containing(&format!( "INFO: {test_name}: {}", - transmission_log(chain, &accounts, gas_price.as_u128()) + transmission_log(chain, &accounts, gas_price) )); } @@ -809,7 +809,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let consuming_wallet_secret_raw_bytes = b"okay-wallet"; let recipient_wallet = make_wallet("blah123"); let unimportant_recipient = Recorder::new().start().recipient(); @@ -819,7 +819,7 @@ mod tests { None, ); let consuming_wallet = make_paying_wallet(consuming_wallet_secret_raw_bytes); - let gas_price = U256::from(123_000_000_000u64); + let gas_price = 123_000_000_000; let nonce = U256::from(1); let os_code = transport_error_code(); let os_msg = transport_error_message(); @@ -834,7 +834,7 @@ mod tests { unimportant_recipient, vec![account], ) - .wait(); + .wait(); assert_eq!( result, @@ -866,10 +866,10 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let recipient_wallet = make_wallet("unlucky man"); let consuming_wallet = make_wallet("bad_wallet"); - let gas_price = U256::from(123_000_000_000u64); + let gas_price = 123_000_000_000; let nonce = U256::from(1); sign_transaction( @@ -893,7 +893,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .err_response( @@ -915,7 +915,7 @@ mod tests { let logger = Logger::new(test_name); let chain = DEFAULT_CHAIN; let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let gas_price = U256::from(1_000_000_000); + let gas_price = 1_000_000_000; let pending_nonce: U256 = 1.into(); let new_fingerprints_recipient = accountant.start().recipient(); let accounts_1 = make_payable_account(1); @@ -929,12 +929,12 @@ mod tests { chain, web3_batch, consuming_wallet.clone(), - gas_price.clone(), + gas_price, pending_nonce, new_fingerprints_recipient, accounts.clone(), ) - .wait(); + .wait(); System::current().stop(); system.run(); @@ -952,14 +952,14 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap(), + .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap(), + .unwrap(), amount: accounts_2.balance_wei }, ] @@ -994,7 +994,7 @@ mod tests { ); tlh.exists_log_containing(&format!( "INFO: {test_name}: {}", - transmission_log(chain, &accounts, gas_price.as_u128()) + transmission_log(chain, &accounts, gas_price) )); } @@ -1007,7 +1007,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .response("rpc_result".to_string(), 7) @@ -1024,7 +1024,7 @@ mod tests { let logger = Logger::new(test_name); let chain = DEFAULT_CHAIN; let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let gas_price = U256::from(1_000_000_000); + let gas_price = 1_000_000_000; let pending_nonce: U256 = 1.into(); let new_fingerprints_recipient = accountant.start().recipient(); let accounts_1 = make_payable_account(1); @@ -1038,12 +1038,12 @@ mod tests { chain, web3_batch, consuming_wallet.clone(), - gas_price.clone(), + gas_price, pending_nonce, new_fingerprints_recipient, accounts.clone(), ) - .wait(); + .wait(); System::current().stop(); system.run(); @@ -1061,14 +1061,14 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap(), + .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap(), + .unwrap(), amount: accounts_2.balance_wei }, ] @@ -1081,7 +1081,7 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap() + .unwrap() }) ); assert_eq!(processed_payments[1], ProcessedPayableFallible::Failed(RpcPayableFailure { @@ -1104,7 +1104,7 @@ mod tests { ); tlh.exists_log_containing(&format!( "INFO: {test_name}: {}", - transmission_log(chain, &accounts, gas_price.as_u128()) + transmission_log(chain, &accounts, gas_price) )); } @@ -1115,11 +1115,11 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3 = Web3::new(transport.clone()); let chain = DEFAULT_CHAIN; let amount = 11_222_333_444; - let gas_price_in_wei = U256::from(123_000_000_000_000_000_000u128); + let gas_price_in_wei = 123_000_000_000_000_000_000; let nonce = U256::from(5); let recipient_wallet = make_wallet("recipient_wallet"); let consuming_wallet = make_paying_wallet(b"consuming_wallet"); @@ -1129,7 +1129,7 @@ mod tests { nonce: Some(nonce), to: Some(chain.rec().contract), gas: gas_limit(data, chain), - gas_price: Some(gas_price_in_wei), + gas_price: Some(U256::from(gas_price_in_wei)), value: U256::zero(), data: Bytes(data.to_vec()), chain_id: Some(chain.rec().num_chain_id), @@ -1161,7 +1161,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let chain = DEFAULT_CHAIN; let amount = 11_222_333_444; let gas_limit = U256::from(5); @@ -1289,13 +1289,13 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let consuming_wallet = { let key_pair = Bip32EncryptionKeyProvider::from_raw_secret( &decode_hex("97923d8fd8de4a00f912bfb77ef483141dec551bd73ea59343ef5c4aac965d04") .unwrap(), ) - .unwrap(); + .unwrap(); Wallet::from(key_pair) }; let recipient_wallet = { @@ -1325,7 +1325,7 @@ mod tests { consuming_wallet, payable_account.balance_wei, nonce_correct_type, - U256::from(gas_price * 1_000_000_000), + (gas_price * 1_000_000_000) as u128, ); let byte_set_to_compare = signed_transaction.raw_transaction.0; diff --git a/node/src/blockchain/test_utils.rs b/node/src/blockchain/test_utils.rs index eed9c2b39..d2c595a75 100644 --- a/node/src/blockchain/test_utils.rs +++ b/node/src/blockchain/test_utils.rs @@ -250,7 +250,7 @@ impl BlockchainInterface for BlockchainInterfaceMock { &self, _logger: Logger, _chain: Chain, - _consuming_wallet: Wallet, + _agent: Box, _fingerprints_recipient: Recipient, _affordable_accounts: Vec, ) -> Box, Error = PayableTransactionError>> From 89419ed2131f83709a3089ba9288e9d29b41b4f7 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 18 Nov 2024 23:20:35 +1300 Subject: [PATCH 29/56] GH-744: logger is now a reference in send_payables_within_batch --- .../blockchain_interface_web3/mod.rs | 26 +++--- .../blockchain/blockchain_interface_utils.rs | 83 +++++++++---------- 2 files changed, 52 insertions(+), 57 deletions(-) diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 4a5ff7a7b..12917aaef 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -93,7 +93,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { start_block: BlockNumber, fallback_start_block_number: u64, recipient: Address, - ) -> Box> { + ) -> Box> { let lower_level_interface = self.lower_interface(); let logger = self.logger.clone(); let contract_address = lower_level_interface.get_contract().address(); @@ -152,7 +152,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { fn build_blockchain_agent( &self, consuming_wallet: Wallet, - ) -> Box, Error = BlockchainAgentBuildError>> { + ) -> Box, Error=BlockchainAgentBuildError>> { let wallet_address = consuming_wallet.address(); let gas_limit_const_part = self.gas_limit_const_part; // TODO: Would it be better to wrap these 3 calls into a single batch call? @@ -198,7 +198,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { fn process_transaction_receipts( &self, transaction_hashes: Vec, - ) -> Box, Error = BlockchainError>> { + ) -> Box, Error=BlockchainError>> { Box::new( self.lower_interface() .get_transaction_receipt_in_batch(transaction_hashes) @@ -242,7 +242,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { agent: Box, fingerprints_recipient: Recipient, affordable_accounts: Vec, - ) -> Box, Error = PayableTransactionError>> + ) -> Box, Error=PayableTransactionError>> { let consuming_wallet = agent.consuming_wallet().clone(); let web3_batch = self.lower_interface().get_web3_batch(); @@ -256,7 +256,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { .map_err(PayableTransactionError::TransactionID) .and_then(move |pending_nonce| { send_payables_within_batch( - logger, + &logger, chain, web3_batch, consuming_wallet, @@ -609,8 +609,7 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned( - ) { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -635,8 +634,7 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned( - ) { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -658,8 +656,7 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number( - ) { + fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x400", 1) @@ -670,7 +667,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let end_block_nbr = 1024u64; let subject = @@ -700,8 +697,7 @@ mod tests { } #[test] - fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one( - ) { + fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("trash", 1) @@ -772,7 +768,7 @@ mod tests { ); let expected_fee_estimation = (3 * (BlockchainInterfaceWeb3::web3_gas_limit_const_part(chain) - + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) + + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) * expected_gas_price_wei) as u128; assert_eq!( result.estimated_transaction_fee_total(3), diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index b8cbd4c46..f67000d6a 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -132,7 +132,7 @@ pub fn gas_limit(data: [u8; 68], chain: Chain) -> U256 { ethereum_types::U256::try_from(data.iter().fold(base_gas_limit, |acc, v| { acc + if v == &0u8 { 4 } else { 68 } })) - .expect("Internal error") + .expect("Internal error") } pub fn sign_transaction( @@ -234,7 +234,7 @@ pub fn handle_new_transaction( } pub fn sign_and_append_multiple_payments( - logger: Logger, + logger: &Logger, chain: Chain, web3_batch: Web3>, consuming_wallet: Wallet, @@ -267,12 +267,11 @@ pub fn sign_and_append_multiple_payments( hash_and_amount_list } -// TODO: GH-744: Use reference to logger, and check other functions are also using a reference to logger. // TODO: GH-744: check if we can use a reference to web3_batch also. // TODO: GH-744: same for accounts, can we also use a reference? #[allow(clippy::too_many_arguments)] pub fn send_payables_within_batch( - logger: Logger, + logger: &Logger, chain: Chain, web3_batch: Web3>, consuming_wallet: Wallet, @@ -280,7 +279,7 @@ pub fn send_payables_within_batch( pending_nonce: U256, new_fingerprints_recipient: Recipient, accounts: Vec, -) -> Box, Error = PayableTransactionError> + 'static> +) -> Box, Error=PayableTransactionError> + 'static> { debug!( logger, @@ -292,7 +291,7 @@ pub fn send_payables_within_batch( ); let hashes_and_paid_amounts = sign_and_append_multiple_payments( - logger.clone(), + logger, chain, web3_batch.clone(), consuming_wallet, @@ -319,7 +318,7 @@ pub fn send_payables_within_batch( transmission_log(chain, &accounts, gas_price_in_wei) ); - return Box::new( + Box::new( web3_batch .transport() .submit_batch() @@ -331,7 +330,7 @@ pub fn send_payables_within_batch( accounts, )) }), - ); + ) } // TODO: GH-744: Migrate this to blockchain/blockchain_bridge.rs and remove pub @@ -429,7 +428,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3_batch = Web3::new(Batch::new(transport)); let pending_nonce = 1; let chain = TEST_DEFAULT_CHAIN; @@ -474,7 +473,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let pending_nonce = 1; let chain = DEFAULT_CHAIN; let gas_price = DEFAULT_GAS_PRICE; @@ -514,7 +513,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3_batch = Web3::new(Batch::new(transport)); let pending_nonce = 1; let chain = DEFAULT_CHAIN; @@ -536,7 +535,7 @@ mod tests { hash: H256::from_str( "94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2", ) - .unwrap(), + .unwrap(), amount, }; assert_eq!(result, expected_hash_and_amount); @@ -550,7 +549,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3_batch = Web3::new(Batch::new(transport)); let chain = DEFAULT_CHAIN; let gas_price = DEFAULT_GAS_PRICE; @@ -561,7 +560,7 @@ mod tests { let accounts = vec![account_1, account_2]; let result = sign_and_append_multiple_payments( - logger, + &logger, chain, web3_batch, consuming_wallet, @@ -577,14 +576,14 @@ mod tests { hash: H256::from_str( "94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2" ) - .unwrap(), + .unwrap(), amount: 1000000000 }, HashAndAmount { hash: H256::from_str( "3811874d2b73cecd51234c94af46bcce918d0cb4de7d946c01d7da606fe761b5" ) - .unwrap(), + .unwrap(), amount: 2000000000 } ] @@ -705,7 +704,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .response("rpc_result".to_string(), 7) @@ -727,7 +726,7 @@ mod tests { let timestamp_before = SystemTime::now(); let result = send_payables_within_batch( - logger, + &logger, chain, web3_batch, consuming_wallet.clone(), @@ -736,7 +735,7 @@ mod tests { new_fingerprints_recipient, accounts.clone(), ) - .wait(); + .wait(); System::current().stop(); system.run(); @@ -754,14 +753,14 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap(), + .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap(), + .unwrap(), amount: accounts_2.balance_wei }, ] @@ -774,7 +773,7 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap() + .unwrap() }) ); assert_eq!( @@ -784,7 +783,7 @@ mod tests { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap() + .unwrap() }) ); let tlh = TestLogHandler::new(); @@ -809,7 +808,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let consuming_wallet_secret_raw_bytes = b"okay-wallet"; let recipient_wallet = make_wallet("blah123"); let unimportant_recipient = Recorder::new().start().recipient(); @@ -825,7 +824,7 @@ mod tests { let os_msg = transport_error_message(); let result = send_payables_within_batch( - Logger::new("test"), + &Logger::new("test"), TEST_DEFAULT_CHAIN, Web3::new(Batch::new(transport)), consuming_wallet, @@ -834,7 +833,7 @@ mod tests { unimportant_recipient, vec![account], ) - .wait(); + .wait(); assert_eq!( result, @@ -866,7 +865,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let recipient_wallet = make_wallet("unlucky man"); let consuming_wallet = make_wallet("bad_wallet"); let gas_price = 123_000_000_000; @@ -893,7 +892,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .err_response( @@ -925,7 +924,7 @@ mod tests { let timestamp_before = SystemTime::now(); let result = send_payables_within_batch( - logger, + &logger, chain, web3_batch, consuming_wallet.clone(), @@ -934,7 +933,7 @@ mod tests { new_fingerprints_recipient, accounts.clone(), ) - .wait(); + .wait(); System::current().stop(); system.run(); @@ -952,14 +951,14 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap(), + .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap(), + .unwrap(), amount: accounts_2.balance_wei }, ] @@ -1007,7 +1006,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .response("rpc_result".to_string(), 7) @@ -1034,7 +1033,7 @@ mod tests { let timestamp_before = SystemTime::now(); let result = send_payables_within_batch( - logger, + &logger, chain, web3_batch, consuming_wallet.clone(), @@ -1043,7 +1042,7 @@ mod tests { new_fingerprints_recipient, accounts.clone(), ) - .wait(); + .wait(); System::current().stop(); system.run(); @@ -1061,14 +1060,14 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap(), + .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" ) - .unwrap(), + .unwrap(), amount: accounts_2.balance_wei }, ] @@ -1081,7 +1080,7 @@ mod tests { hash: H256::from_str( "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" ) - .unwrap() + .unwrap() }) ); assert_eq!(processed_payments[1], ProcessedPayableFallible::Failed(RpcPayableFailure { @@ -1115,7 +1114,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3 = Web3::new(transport.clone()); let chain = DEFAULT_CHAIN; let amount = 11_222_333_444; @@ -1161,7 +1160,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let chain = DEFAULT_CHAIN; let amount = 11_222_333_444; let gas_limit = U256::from(5); @@ -1289,13 +1288,13 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let consuming_wallet = { let key_pair = Bip32EncryptionKeyProvider::from_raw_secret( &decode_hex("97923d8fd8de4a00f912bfb77ef483141dec551bd73ea59343ef5c4aac965d04") .unwrap(), ) - .unwrap(); + .unwrap(); Wallet::from(key_pair) }; let recipient_wallet = { From 5181f1c31fa72229958bdcaeb02331305c37f8a2 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 18 Nov 2024 23:27:38 +1300 Subject: [PATCH 30/56] GH-744: send_payables_within_batch web3_batch is now a reference --- .../blockchain_interface_web3/mod.rs | 2 +- .../blockchain/blockchain_interface_utils.rs | 46 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 12917aaef..e702e967b 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -258,7 +258,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { send_payables_within_batch( &logger, chain, - web3_batch, + &web3_batch, consuming_wallet, gas_price_wei, pending_nonce, diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index f67000d6a..9d6aacf44 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -137,7 +137,7 @@ pub fn gas_limit(data: [u8; 68], chain: Chain) -> U256 { pub fn sign_transaction( chain: Chain, - web3_batch: Web3>, + web3_batch: &Web3>, recipient_wallet: Wallet, consuming_wallet: Wallet, amount: u128, @@ -164,7 +164,7 @@ pub fn sign_transaction( } pub fn sign_transaction_locally( - web3_batch: Web3>, + web3_batch: &Web3>, transaction_parameters: TransactionParameters, key: &SecretKey, ) -> SignedTransaction { @@ -185,7 +185,7 @@ pub fn sign_transaction_locally( pub fn sign_and_append_payment( chain: Chain, - web3_batch: Web3>, + web3_batch: &Web3>, recipient_wallet: Wallet, consuming_wallet: Wallet, amount: u128, @@ -194,7 +194,7 @@ pub fn sign_and_append_payment( ) -> H256 { let signed_tx = sign_transaction( chain, - web3_batch.clone(), + web3_batch, recipient_wallet, consuming_wallet, amount, @@ -205,14 +205,14 @@ pub fn sign_and_append_payment( signed_tx.transaction_hash } -pub fn append_signed_transaction_to_batch(web3_batch: Web3>, raw_transaction: Bytes) { +pub fn append_signed_transaction_to_batch(web3_batch: &Web3>, raw_transaction: Bytes) { // This function only prepares a raw transaction for a batch call and doesn't actually send it right here. web3_batch.eth().send_raw_transaction(raw_transaction); } pub fn handle_new_transaction( chain: Chain, - web3_batch: Web3>, + web3_batch: &Web3>, consuming_wallet: Wallet, nonce: U256, gas_price_in_wei: u128, @@ -236,7 +236,7 @@ pub fn handle_new_transaction( pub fn sign_and_append_multiple_payments( logger: &Logger, chain: Chain, - web3_batch: Web3>, + web3_batch: &Web3>, consuming_wallet: Wallet, gas_price_in_wei: u128, mut pending_nonce: U256, @@ -254,7 +254,7 @@ pub fn sign_and_append_multiple_payments( let hash_and_amount = handle_new_transaction( chain, - web3_batch.clone(), + web3_batch, consuming_wallet.clone(), pending_nonce, gas_price_in_wei, @@ -273,7 +273,7 @@ pub fn sign_and_append_multiple_payments( pub fn send_payables_within_batch( logger: &Logger, chain: Chain, - web3_batch: Web3>, + web3_batch: &Web3>, consuming_wallet: Wallet, gas_price_in_wei: u128, pending_nonce: U256, @@ -293,7 +293,7 @@ pub fn send_payables_within_batch( let hashes_and_paid_amounts = sign_and_append_multiple_payments( logger, chain, - web3_batch.clone(), + web3_batch, consuming_wallet, gas_price_in_wei, pending_nonce, @@ -437,7 +437,7 @@ mod tests { let account = make_payable_account(1); let signed_transaction = sign_transaction( chain, - web3_batch.clone(), + &web3_batch, account.wallet, consuming_wallet, account.balance_wei, @@ -445,7 +445,7 @@ mod tests { (gas_price * 1_000_000_000) as u128, ); - append_signed_transaction_to_batch(web3_batch.clone(), signed_transaction.raw_transaction); + append_signed_transaction_to_batch(&web3_batch, signed_transaction.raw_transaction); let mut batch_result = web3_batch.eth().transport().submit_batch().wait().unwrap(); let result = batch_result.pop().unwrap().unwrap(); @@ -483,7 +483,7 @@ mod tests { let result = sign_and_append_payment( chain, - web3_batch.clone(), + &web3_batch, account.wallet, consuming_wallet, account.balance_wei, @@ -524,7 +524,7 @@ mod tests { let result = handle_new_transaction( chain, - web3_batch, + &web3_batch, consuming_wallet, pending_nonce.into(), (gas_price * 1_000_000_000) as u128, @@ -562,7 +562,7 @@ mod tests { let result = sign_and_append_multiple_payments( &logger, chain, - web3_batch, + &web3_batch, consuming_wallet, (gas_price * 1_000_000_000) as u128, pending_nonce.into(), @@ -728,7 +728,7 @@ mod tests { let result = send_payables_within_batch( &logger, chain, - web3_batch, + &web3_batch, consuming_wallet.clone(), gas_price, pending_nonce, @@ -826,7 +826,7 @@ mod tests { let result = send_payables_within_batch( &Logger::new("test"), TEST_DEFAULT_CHAIN, - Web3::new(Batch::new(transport)), + &Web3::new(Batch::new(transport)), consuming_wallet, gas_price, nonce, @@ -873,7 +873,7 @@ mod tests { sign_transaction( Chain::PolyAmoy, - Web3::new(Batch::new(transport)), + &Web3::new(Batch::new(transport)), recipient_wallet, consuming_wallet, 444444, @@ -926,7 +926,7 @@ mod tests { let result = send_payables_within_batch( &logger, chain, - web3_batch, + &web3_batch, consuming_wallet.clone(), gas_price, pending_nonce, @@ -1035,7 +1035,7 @@ mod tests { let result = send_payables_within_batch( &logger, chain, - web3_batch, + &web3_batch, consuming_wallet.clone(), gas_price, pending_nonce, @@ -1135,7 +1135,7 @@ mod tests { }; let result = sign_transaction( chain, - Web3::new(Batch::new(transport)), + &Web3::new(Batch::new(transport)), recipient_wallet, consuming_wallet, amount, @@ -1183,7 +1183,7 @@ mod tests { .expect("Consuming wallet doesn't contain a secret key"); let _result = sign_transaction_locally( - Web3::new(Batch::new(transport)), + &Web3::new(Batch::new(transport)), transaction_parameters, &key, ); @@ -1319,7 +1319,7 @@ mod tests { let signed_transaction = sign_transaction( chain, - Web3::new(Batch::new(transport)), + &Web3::new(Batch::new(transport)), payable_account.wallet, consuming_wallet, payable_account.balance_wei, From 54ab85e5946ad05ed1002553a602206c83318078 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 18 Nov 2024 23:38:19 +1300 Subject: [PATCH 31/56] GH-744: sign_and_append_multiple_payments accounts is now a reference --- node/src/blockchain/blockchain_interface_utils.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index 9d6aacf44..97e48a344 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -216,7 +216,7 @@ pub fn handle_new_transaction( consuming_wallet: Wallet, nonce: U256, gas_price_in_wei: u128, - account: PayableAccount, + account: &PayableAccount, ) -> HashAndAmount { let hash = sign_and_append_payment( chain, @@ -240,7 +240,7 @@ pub fn sign_and_append_multiple_payments( consuming_wallet: Wallet, gas_price_in_wei: u128, mut pending_nonce: U256, - accounts: Vec, + accounts: &Vec, ) -> Vec { let mut hash_and_amount_list = vec![]; accounts.into_iter().for_each(|payable| { @@ -267,8 +267,6 @@ pub fn sign_and_append_multiple_payments( hash_and_amount_list } -// TODO: GH-744: check if we can use a reference to web3_batch also. -// TODO: GH-744: same for accounts, can we also use a reference? #[allow(clippy::too_many_arguments)] pub fn send_payables_within_batch( logger: &Logger, @@ -297,7 +295,7 @@ pub fn send_payables_within_batch( consuming_wallet, gas_price_in_wei, pending_nonce, - accounts.clone(), + &accounts, ); let timestamp = SystemTime::now(); @@ -316,7 +314,7 @@ pub fn send_payables_within_batch( logger, "{}", transmission_log(chain, &accounts, gas_price_in_wei) - ); + ); Box::new( web3_batch @@ -528,7 +526,7 @@ mod tests { consuming_wallet, pending_nonce.into(), (gas_price * 1_000_000_000) as u128, - account, + &account, ); let expected_hash_and_amount = HashAndAmount { @@ -566,7 +564,7 @@ mod tests { consuming_wallet, (gas_price * 1_000_000_000) as u128, pending_nonce.into(), - accounts, + &accounts, ); assert_eq!( From e93c0f19e3d7a3ce31841c209eb1fd1eceb7be3b Mon Sep 17 00:00:00 2001 From: Syther007 Date: Wed, 20 Nov 2024 00:12:57 +1300 Subject: [PATCH 32/56] GH-744 removed Blockchan_interface_mock --- node/src/accountant/mod.rs | 70 +++-- node/src/blockchain/blockchain_bridge.rs | 264 +++++++++++------- .../lower_level_interface_web3.rs | 54 ++-- .../blockchain_interface_web3/mod.rs | 35 ++- .../lower_level_interface.rs | 16 +- .../blockchain/blockchain_interface_utils.rs | 171 ++---------- node/src/blockchain/test_utils.rs | 128 +-------- node/src/sub_lib/blockchain_bridge.rs | 5 +- 8 files changed, 277 insertions(+), 466 deletions(-) diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index 7aeff1793..0ac3c69d7 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -743,7 +743,7 @@ impl Accountant { stats_opt, query_results_opt, } - .tmb(context_id) + .tmb(context_id) } fn request_payable_accounts_by_specific_mode( @@ -1032,11 +1032,11 @@ pub fn checked_conversion>(num: T) -> S { politely_checked_conversion(num).unwrap_or_else(|msg| panic!("{}", msg)) } -pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { +pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { (T::from(gwei)).mul(T::from(WEIS_IN_GWEI as u32)) } -pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { +pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { checked_conversion::(wei.div(S::from(WEIS_IN_GWEI as u32))) } @@ -1364,7 +1364,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Receivables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1456,7 +1456,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Payables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1523,8 +1523,7 @@ mod tests { } #[test] - fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge( - ) { + fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge() { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1616,8 +1615,7 @@ mod tests { } #[test] - fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge( - ) { + fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge() { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1765,7 +1763,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1820,7 +1818,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; let second_message = first_message.clone(); let peer_actors = peer_actors_builder() @@ -2011,8 +2009,7 @@ mod tests { } #[test] - fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block( - ) { + fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block() { let more_money_received_params_arc = Arc::new(Mutex::new(vec![])); let commit_params_arc = Arc::new(Mutex::new(vec![])); let set_by_guest_transaction_params_arc = Arc::new(Mutex::new(vec![])); @@ -2712,7 +2709,7 @@ mod tests { addr.try_send(ScanForPayables { response_skeleton_opt: None, }) - .unwrap(); + .unwrap(); // We ignored the second ScanForPayables message because the first message meant a scan // was already in progress; now let's make it look like that scan has ended so that we @@ -2725,7 +2722,7 @@ mod tests { .mark_as_ended(&Logger::new("irrelevant")) }), }) - .unwrap(); + .unwrap(); addr.try_send(message_after.clone()).unwrap(); system.run(); let recording = blockchain_bridge_recording.lock().unwrap(); @@ -3542,7 +3539,7 @@ mod tests { gwei_to_wei(DEFAULT_PAYMENT_THRESHOLDS.debt_threshold_gwei + 666); let wallet_account_1 = make_wallet("creditor1"); let wallet_account_2 = make_wallet("creditor2"); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let consuming_wallet = make_paying_wallet(b"wallet"); let system = System::new("pending_transaction"); let persistent_config_id_stamp = ArbitraryIdStamp::new(); @@ -4030,7 +4027,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4114,7 +4111,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4177,7 +4174,7 @@ mod tests { }), query_results_opt: None } - .tmb(context_id) + .tmb(context_id) ) } @@ -4254,12 +4251,12 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 58, pending_payable_hash_opt: None - },]), + }, ]), receivable_opt: Some(vec![UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), age_s: extracted_receivable_ages[0], balance_gwei: 3_788_455 - },]) + }, ]) }), } ); @@ -4420,7 +4417,7 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 5, pending_payable_hash_opt: None - },]), + }, ]), receivable_opt: Some(vec![ UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), @@ -4609,8 +4606,7 @@ mod tests { expected = "Broken code: PayableAccount with less than 1 gwei passed through db query \ constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 8686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei( - ) { + fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei() { let payable_accounts_retrieved = vec![PayableAccount { wallet: make_wallet("abcd123"), balance_wei: 8_686_005, @@ -4646,8 +4642,7 @@ mod tests { expected = "Broken code: ReceivableAccount with balance between 1 and 0 gwei passed through \ db query constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 7686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei( - ) { + fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei() { let receivable_accounts_retrieved = vec![ReceivableAccount { wallet: make_wallet("abcd123"), balance_wei: 7_686_005, @@ -4886,11 +4881,10 @@ pub mod exportable_test_parts { } } - fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao( - ) -> ShouldWeRunTheTest { + fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao() -> ShouldWeRunTheTest { fn skip_down_to_first_line_saying_new_delinquencies( - previous: impl Iterator, - ) -> impl Iterator { + previous: impl Iterator, + ) -> impl Iterator { previous .skip_while(|line| { let adjusted_line: String = line @@ -4901,7 +4895,7 @@ pub mod exportable_test_parts { }) .skip(1) } - fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { + fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { fn yield_if_contains_semicolon(line: &str) -> Option { line.contains(';').then(|| line.to_string()) } @@ -4940,13 +4934,13 @@ pub mod exportable_test_parts { skip_down_to_first_line_saying_new_delinquencies( lines_with_cut_fn_trait_definition, ) - .take_while(|line| { - let adjusted_line: String = line - .chars() - .skip_while(|char| char.is_whitespace()) - .collect(); - !adjusted_line.starts_with("fn") - }); + .take_while(|line| { + let adjusted_line: String = line + .chars() + .skip_while(|char| char.is_whitespace()) + .collect(); + !adjusted_line.starts_with("fn") + }); assert_is_not_trait_definition(assumed_implemented_function_body) } fn user_defined_functions_detected(line_undivided_fn_body: &str) -> bool { diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 7163eb155..80a35edb3 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -16,7 +16,6 @@ use crate::blockchain::blockchain_interface::data_structures::errors::{ use crate::blockchain::blockchain_interface::data_structures::ProcessedPayableFallible; use crate::blockchain::blockchain_interface::BlockchainInterface; use crate::blockchain::blockchain_interface_initializer::BlockchainInterfaceInitializer; -use crate::blockchain::blockchain_interface_utils::calculate_fallback_start_block_number; use crate::database::db_initializer::{DbInitializationConfig, DbInitializer, DbInitializerReal}; use crate::db_config::config_dao::ConfigDaoReal; use crate::db_config::persistent_configuration::{ @@ -247,10 +246,10 @@ impl BlockchainBridge { fn handle_qualified_payable_msg( &mut self, incoming_message: QualifiedPayablesMessage, - ) -> Box> { + ) -> Box> { // TODO rewrite this into a batch call as soon as GH-629 gets into master let accountant_recipient = self.payable_payments_setup_subs_opt.clone(); - return Box::new( + Box::new( self.blockchain_interface .build_blockchain_agent(incoming_message.consuming_wallet) .map_err(|e| format!("Blockchain agent build error: {:?}", e)) @@ -266,13 +265,13 @@ impl BlockchainBridge { .expect("Accountant is dead"); Ok(()) }), - ); + ) } fn handle_outbound_payments_instructions( &mut self, msg: OutboundPaymentsInstructions, - ) -> Box> { + ) -> Box> { let skeleton_opt = msg.response_skeleton_opt; let sent_payable_subs = self .sent_payable_subs_opt @@ -285,7 +284,7 @@ impl BlockchainBridge { }; let send_message_if_successful = send_message_if_failure.clone(); - return Box::new( + Box::new( self.process_payments(msg.agent, msg.affordable_accounts) .map_err(move |e: PayableTransactionError| { send_message_if_failure(SentPayables { @@ -301,13 +300,13 @@ impl BlockchainBridge { }); Ok(()) }), - ); + ) } fn handle_retrieve_transactions( &mut self, msg: RetrieveTransactions, - ) -> Box> { + ) -> Box> { let (start_block_nbr, max_block_count) = { let persistent_config_lock = self .persistent_config_arc @@ -327,7 +326,7 @@ impl BlockchainBridge { let logger = self.logger.clone(); let fallback_next_start_block_number = - calculate_fallback_start_block_number(start_block_nbr, max_block_count); + Self::calculate_fallback_start_block_number(start_block_nbr, max_block_count); let start_block = BlockNumber::Number(start_block_nbr.into()); let received_payments_subs = self .received_payments_subs_opt @@ -389,7 +388,7 @@ impl BlockchainBridge { fn handle_request_transaction_receipts( &mut self, msg: RequestTransactionReceipts, - ) -> Box> { + ) -> Box> { let logger = self.logger.clone(); let accountant_recipient = self .pending_payable_confirmation @@ -440,7 +439,7 @@ impl BlockchainBridge { fn handle_scan_future(&mut self, handler: F, scan_type: ScanType, msg: M) where - F: FnOnce(&mut BlockchainBridge, M) -> Box>, + F: FnOnce(&mut BlockchainBridge, M) -> Box>, M: SkeletonOptHolder, { let skeleton_opt = msg.skeleton_opt(); @@ -462,11 +461,19 @@ impl BlockchainBridge { actix::spawn(future); } + fn calculate_fallback_start_block_number(start_block_number: u64, max_block_count: u64) -> u64 { + if max_block_count == u64::MAX { + start_block_number + 1u64 + } else { + start_block_number + max_block_count + } + } + fn process_payments( &self, agent: Box, affordable_accounts: Vec, - ) -> Box, Error = PayableTransactionError>> + ) -> Box, Error=PayableTransactionError>> { let new_fingerprints_recipient = self.new_fingerprints_recipient(); let logger = self.logger.clone(); @@ -545,7 +552,7 @@ mod tests { BlockchainTransaction, RetrievedBlockchainTransactions, }; use crate::blockchain::test_utils::{ - make_blockchain_interface_web3, make_tx_hash, BlockchainInterfaceMock, + make_blockchain_interface_web3, make_tx_hash, ReceiptResponseBuilder, }; use crate::db_config::persistent_configuration::PersistentConfigError; @@ -579,7 +586,7 @@ mod tests { use std::str::FromStr; use std::sync::{Arc, Mutex}; use std::time::{Duration, SystemTime}; - use web3::types::{BlockNumber, TransactionReceipt, H160}; + use web3::types::{TransactionReceipt, H160}; impl Handler> for BlockchainBridge { type Result = (); @@ -600,7 +607,7 @@ mod tests { } fn stub_bi() -> Box { - Box::new(make_blockchain_interface_web3(None)) + Box::new(make_blockchain_interface_web3(find_free_port())) } #[test] @@ -617,7 +624,7 @@ mod tests { addr.try_send(BindMessage { peer_actors: peer_actors_builder().build(), }) - .unwrap(); + .unwrap(); System::current().stop(); system.run(); @@ -660,8 +667,7 @@ mod tests { } #[test] - fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant( - ) { + fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant() { let system = System::new( "qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant", ); @@ -676,7 +682,7 @@ mod tests { .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant_recipient = accountant.start().recipient(); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let consuming_wallet = make_paying_wallet(b"somewallet"); let persistent_configuration = PersistentConfigurationMock::default(); let wallet_1 = make_wallet("booga"); @@ -776,7 +782,7 @@ mod tests { .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant_recipient = accountant.start().recipient(); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let consuming_wallet = make_paying_wallet(b"somewallet"); let mut subject = BlockchainBridge::new( Box::new(blockchain_interface), @@ -820,8 +826,7 @@ mod tests { } #[test] - fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant( - ) { + fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant() { let system = System::new( "handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant", ); @@ -838,7 +843,7 @@ mod tests { .start(); let wallet_account = make_wallet("blah"); let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let persistent_configuration_mock = PersistentConfigurationMock::default(); let subject = BlockchainBridge::new( Box::new(blockchain_interface), @@ -889,7 +894,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap() + .unwrap() })]), response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, @@ -905,7 +910,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -927,7 +932,7 @@ mod tests { .system_stop_conditions(match_every_type_id!(SentPayables)) .start(); let wallet_account = make_wallet("blah"); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let persistent_configuration_mock = PersistentConfigurationMock::default(); let subject = BlockchainBridge::new( Box::new(blockchain_interface), @@ -980,7 +985,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -1011,7 +1016,7 @@ mod tests { .response("rpc_result_2".to_string(), 7) .end_batch() .start(); - let blockchain_interface_web3 = make_blockchain_interface_web3(Some(port)); + let blockchain_interface_web3 = make_blockchain_interface_web3(port); let consuming_wallet = make_paying_wallet(b"consuming_wallet"); let accounts_1 = make_payable_account(1); let accounts_2 = make_payable_account(2); @@ -1046,7 +1051,7 @@ mod tests { hash: H256::from_str( "cc73f3d5fe9fc3dac28b510ddeb157b0f8030b201e809014967396cdf365488a" ) - .unwrap() + .unwrap() }) ); assert_eq!( @@ -1056,7 +1061,7 @@ mod tests { hash: H256::from_str( "891d9ffa838aedc0bb2f6f7e9737128ce98bb33d07b4c8aa5645871e20d6cd13" ) - .unwrap() + .unwrap() }) ); let recording = accountant_recording.lock().unwrap(); @@ -1070,7 +1075,7 @@ mod tests { let _blockchain_client_server = MBCSBuilder::new(port) .response("trash transaction id".to_string(), 1) .start(); - let blockchain_interface_web3 = make_blockchain_interface_web3(Some(port)); + let blockchain_interface_web3 = make_blockchain_interface_web3(port); let consuming_wallet = make_paying_wallet(b"consuming_wallet"); let system = System::new(test_name); let agent = BlockchainAgentMock::default() @@ -1145,7 +1150,7 @@ mod tests { .raw_response(r#"{ "jsonrpc": "2.0", "id": 1, "result": null }"#.to_string()) .end_batch() .start(); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let subject = BlockchainBridge::new( Box::new(blockchain_interface), Arc::new(Mutex::new(PersistentConfigurationMock::default())), @@ -1212,7 +1217,7 @@ mod tests { .start(); let scan_error_recipient: Recipient = accountant_addr.clone().recipient(); let received_payments_subs: Recipient = accountant_addr.recipient(); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let persistent_config = PersistentConfigurationMock::new() .max_block_count_result(Ok(Some(100_000))) .start_block_result(Ok(5)); // no set_start_block_result: set_start_block() must not be called @@ -1250,8 +1255,7 @@ mod tests { } #[test] - fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort( - ) { + fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort() { init_test_logging(); let port = find_free_port(); let block_number = U64::from(4545454); @@ -1315,7 +1319,7 @@ mod tests { transaction_receipt.block_number = Some(block_number); transaction_receipt.contract_address = Some(contract_address); transaction_receipt.status = Some(U64::from(1)); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let system = System::new("test_transaction_receipts"); let mut subject = BlockchainBridge::new( Box::new(blockchain_interface), @@ -1393,7 +1397,7 @@ mod tests { }; let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port).start(); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let mut subject = BlockchainBridge::new( Box::new(blockchain_interface), Arc::new(Mutex::new(PersistentConfigurationMock::default())), @@ -1433,37 +1437,54 @@ mod tests { #[test] fn handle_retrieve_transactions_uses_latest_block_number_upon_get_block_number_error() { init_test_logging(); - let retrieve_transactions_params_arc = Arc::new(Mutex::new(vec![])); let system = System::new( "handle_retrieve_transactions_uses_latest_block_number_upon_get_block_number_error", ); + let port = find_free_port(); + let _blockchain_client_server = MBCSBuilder::new(port) + .response("0xC8".to_string(), 0) + .raw_response(r#"{ + "jsonrpc": "2.0", + "id": 1, + "result": [ + { + "address": "0x06012c8cf97bead5deae237070f9587f8e7a266d", + "blockHash": "0x7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70", + "blockNumber": "0x5c29fb", + "data": "0x0000000000000000000000000000002a", + "logIndex": "0x1d", + "removed": false, + "topics": [ + "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80", + "0x000000000000000000000000000000000000000066697273745f77616c6c6574" + ], + "transactionHash": "0x3dc91b98249fa9f2c5c37486a2427a3a7825be240c1c84961dfb3063d9c04d50", + "transactionIndex": "0x1d" + }, + { + "address": "0x06012c8cf97bead5deae237070f9587f8e7a266d", + "blockHash": "0x7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70", + "blockNumber": "0x5c29fc", + "data": "0x00000000000000000000000000000037", + "logIndex": "0x57", + "removed": false, + "topics": [ + "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80", + "0x000000000000000000000000000000000000007365636f6e645f77616c6c6574" + ], + "transactionHash": "0x788b1442414cb9c9a36dba2abe250763161a6f6395788a2e808f1b34e92beec1", + "transactionIndex": "0x54" + } + ] + }"#.to_string()) + .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let earning_wallet = make_wallet("somewallet"); - let amount = 42; - let amount2 = 55; - let expected_transactions = RetrievedBlockchainTransactions { - new_start_block: 8675309u64, - transactions: vec![ - BlockchainTransaction { - block_number: 7, - from: earning_wallet.clone(), - wei_amount: amount, - }, - BlockchainTransaction { - block_number: 9, - from: earning_wallet.clone(), - wei_amount: amount2, - }, - ], - }; - let blockchain_interface_mock = BlockchainInterfaceMock::default() - .retrieve_transactions_params(&retrieve_transactions_params_arc) - .retrieve_transactions_result(Ok(expected_transactions.clone())); let persistent_config = PersistentConfigurationMock::new() .max_block_count_result(Ok(Some(10000u64))) - .start_block_result(Ok(6)); + .start_block_result(Ok(100)); let mut subject = BlockchainBridge::new( - Box::new(blockchain_interface_mock), + Box::new(make_blockchain_interface_web3(port)), Arc::new(Mutex::new(persistent_config)), false, ); @@ -1485,22 +1506,28 @@ mod tests { System::current().stop(); system.run(); let after = SystemTime::now(); - let retrieve_transactions_params = retrieve_transactions_params_arc.lock().unwrap(); - assert_eq!( - *retrieve_transactions_params, - vec![( - BlockNumber::Number(6u64.into()), - 10006u64, - earning_wallet.address() - )] - ); + let expected_transactions = RetrievedBlockchainTransactions { + new_start_block: 6040060u64, + transactions: vec![ + BlockchainTransaction { + block_number: 6040059, + from: make_wallet("first_wallet"), // Points to topics of 1 + wei_amount: 42, // Its points to the field data + }, + BlockchainTransaction { + block_number: 6040060, + from: make_wallet("second_wallet"), // Points to topics of 1 + wei_amount: 55, // Its points to the field data + }, + ], + }; + let mut payments_and_start_block = make_empty_payments_and_start_block(); + payments_and_start_block.payments = expected_transactions.transactions; + payments_and_start_block.new_start_block = expected_transactions.new_start_block; let accountant_received_payment = accountant_recording_arc.lock().unwrap(); assert_eq!(accountant_received_payment.len(), 1); let received_payments = accountant_received_payment.get_record::(0); check_timestamp(before, received_payments.timestamp, after); - let mut payments_and_start_block = make_empty_payments_and_start_block(); - payments_and_start_block.payments = expected_transactions.transactions; - payments_and_start_block.new_start_block = 8675309u64; assert_eq!( received_payments, &ReceivedPayments { @@ -1562,7 +1589,7 @@ mod tests { wei_amount: amount, }], }; - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let persistent_config = PersistentConfigurationMock::new() .start_block_result(Ok(6)) .max_block_count_result(Err(PersistentConfigError::NotPresent)); @@ -1640,7 +1667,7 @@ mod tests { let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant_addr = accountant.system_stop_conditions(match_every_type_id!(ScanError)); let earning_wallet = make_wallet("earning_wallet"); - let mut blockchain_interface = make_blockchain_interface_web3(Some(port)); + let mut blockchain_interface = make_blockchain_interface_web3(port); blockchain_interface.logger = logger; let persistent_config = PersistentConfigurationMock::new() .start_block_result(Ok(6)) @@ -1699,7 +1726,7 @@ mod tests { let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant = accountant.system_stop_conditions(match_every_type_id!(ScanError)); let earning_wallet = make_wallet("earning_wallet"); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let persistent_config = PersistentConfigurationMock::new() .start_block_result(Ok(6)) .max_block_count_result(Err(PersistentConfigError::DatabaseError( @@ -1759,7 +1786,7 @@ mod tests { .start(); let (accountant, _, _) = make_recorder(); let earning_wallet = make_wallet("earning_wallet"); - let blockchain_interface = make_blockchain_interface_web3(Some(port)); + let blockchain_interface = make_blockchain_interface_web3(port); let persistent_config = PersistentConfigurationMock::new() .start_block_result(Ok(6)) .max_block_count_result(Err(PersistentConfigError::DatabaseError( @@ -1798,7 +1825,7 @@ mod tests { let persistent_config = PersistentConfigurationMock::new() .start_block_result(Err(PersistentConfigError::TransactionError)); let mut subject = BlockchainBridge::new( - Box::new(BlockchainInterfaceMock::default()), + Box::new(make_blockchain_interface_web3(find_free_port())), Arc::new(Mutex::new(persistent_config)), false, ); @@ -1813,6 +1840,44 @@ mod tests { // TODO: GH-555: Remove system_stop_conditions while also confirming the ScanError msg wasn't sent. #[test] fn handle_scan_future_handles_success() { + let port = find_free_port(); + let _blockchain_client_server = MBCSBuilder::new(port) + .response("0xC8".to_string(), 0) + .raw_response(r#"{ + "jsonrpc": "2.0", + "id": 1, + "result": [ + { + "address": "0x06012c8cf97bead5deae237070f9587f8e7a266d", + "blockHash": "0x7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70", + "blockNumber": "0x5c29fb", + "data": "0x0000000000000000000000000000002a", + "logIndex": "0x1d", + "removed": false, + "topics": [ + "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80", + "0x000000000000000000000000000000000000000066697273745f77616c6c6574" + ], + "transactionHash": "0x3dc91b98249fa9f2c5c37486a2427a3a7825be240c1c84961dfb3063d9c04d50", + "transactionIndex": "0x1d" + }, + { + "address": "0x06012c8cf97bead5deae237070f9587f8e7a266d", + "blockHash": "0x7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70", + "blockNumber": "0x5c29fc", + "data": "0x00000000000000000000000000000037", + "logIndex": "0x57", + "removed": false, + "topics": [ + "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80", + "0x000000000000000000000000000000000000007365636f6e645f77616c6c6574" + ], + "transactionHash": "0x788b1442414cb9c9a36dba2abe250763161a6f6395788a2e808f1b34e92beec1", + "transactionIndex": "0x54" + } + ] + }"#.to_string()) + .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let start_block = 2000; let wallet = make_wallet("somewallet"); @@ -1826,20 +1891,8 @@ mod tests { context_id: 4321, }), }; - let blockchain_transaction = BlockchainTransaction { - block_number: start_block, - from: wallet, - wei_amount: 20_000, - }; - let retrieved_blockchain_transactions = RetrievedBlockchainTransactions { - new_start_block: start_block, - transactions: vec![blockchain_transaction], - }; let mut subject = BlockchainBridge::new( - Box::new( - BlockchainInterfaceMock::default() - .retrieve_transactions_result(Ok(retrieved_blockchain_transactions)), - ), + Box::new(make_blockchain_interface_web3(port)), Arc::new(Mutex::new(persistent_config)), false, ); @@ -1879,17 +1932,18 @@ mod tests { fn assert_handle_scan_future_handles_failure(msg: RetrieveTransactions) { init_test_logging(); + let port = find_free_port(); + let _blockchain_client_server = MBCSBuilder::new(port) + .response("0xC8".to_string(), 0) + .err_response(-32005, "My tummy hurts", 0) + .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let start_block = 2000; let persistent_config = PersistentConfigurationMock::default() .start_block_result(Ok(start_block)) .max_block_count_result(Ok(None)); let mut subject = BlockchainBridge::new( - Box::new( - BlockchainInterfaceMock::default().retrieve_transactions_result(Err( - BlockchainError::QueryFailed("My tummy hurts".to_string()), - )), - ), + Box::new(make_blockchain_interface_web3(port)), Arc::new(Mutex::new(persistent_config)), false, ); @@ -1914,12 +1968,12 @@ mod tests { &ScanError { scan_type: ScanType::Receivables, response_skeleton_opt: msg.response_skeleton_opt, - msg: "Error while retrieving transactions: QueryFailed(\"My tummy hurts\")" + msg: "Error while retrieving transactions: QueryFailed(\"RPC error: Error { code: ServerError(-32005), message: \\\"My tummy hurts\\\", data: None }\")" .to_string() } ); assert_eq!(accountant_recording.len(), 1); - TestLogHandler::new().exists_log_containing("WARN: BlockchainBridge: Error while retrieving transactions: QueryFailed(\"My tummy hurts\")"); + TestLogHandler::new().exists_log_containing("WARN: BlockchainBridge: Error while retrieving transactions: QueryFailed(\"RPC error: Error { code: ServerError(-32005), message: \\\"My tummy hurts\\\", data: None }\")"); } #[test] @@ -1929,7 +1983,7 @@ mod tests { fn blockchain_bridge_can_be_crashed_properly_but_not_improperly() { let crashable = true; let subject = BlockchainBridge::new( - Box::new(BlockchainInterfaceMock::default()), + Box::new(make_blockchain_interface_web3(find_free_port())), Arc::new(Mutex::new(PersistentConfigurationMock::default())), crashable, ); @@ -2036,6 +2090,18 @@ mod tests { assert_on_initialization_with_panic_on_migration(&data_dir, &act); } + + #[test] + fn calculate_fallback_start_block_number_works() { + assert_eq!( + BlockchainBridge::calculate_fallback_start_block_number(10_000, u64::MAX), + 10_000 + 1 + ); + assert_eq!( + BlockchainBridge::calculate_fallback_start_block_number(5_000, 10_000), + 5_000 + 10_000 + ); + } } #[cfg(test)] @@ -2045,7 +2111,7 @@ pub mod exportable_test_parts { use crate::test_utils::unshared_test_utils::SubsFactoryTestAddrLeaker; impl SubsFactory - for SubsFactoryTestAddrLeaker + for SubsFactoryTestAddrLeaker { fn make(&self, addr: &Addr) -> BlockchainBridgeSubs { self.send_leaker_msg_and_return_meaningless_subs( diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index b843c3216..e86148c1d 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -32,7 +32,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_fee_balance( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.web3 .eth() @@ -44,7 +44,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_service_fee_balance( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.contract .query("balanceOf", address, None, Options::default(), None) @@ -52,7 +52,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } - fn get_gas_price(&self) -> Box> { + fn get_gas_price(&self) -> Box> { Box::new( self.web3 .eth() @@ -61,7 +61,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } - fn get_block_number(&self) -> Box> { + fn get_block_number(&self) -> Box> { Box::new( self.web3 .eth() @@ -73,7 +73,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_id( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.web3 .eth() @@ -85,7 +85,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_receipt_in_batch( &self, hash_vec: Vec, - ) -> Box>, Error = BlockchainError>> { + ) -> Box>, Error=BlockchainError>> { let _ = hash_vec.into_iter().map(|hash| { self.web3_batch.eth().transaction_receipt(hash); }); @@ -97,15 +97,14 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } - // TODO: GH-744: this should be just get_contract_address, we only need the address. - fn get_contract(&self) -> Contract { - self.contract.clone() + fn get_contract_address(&self) -> Address { + self.contract.address() } fn get_transaction_logs( &self, filter: Filter, - ) -> Box, Error = BlockchainError>> { + ) -> Box, Error=BlockchainError>> { Box::new( self.web3 .eth() @@ -156,7 +155,7 @@ mod tests { .response("0x23".to_string(), 1) .start(); let wallet = &Wallet::from_str("0x3f69f9efd4f2592fd70be8c32ecd9dce71c472fc").unwrap(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject .lower_interface() @@ -167,13 +166,12 @@ mod tests { } #[test] - fn get_transaction_fee_balance_returns_an_error_for_unintelligible_response_to_requesting_eth_balance( - ) { + fn get_transaction_fee_balance_returns_an_error_for_unintelligible_response_to_requesting_eth_balance() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0xFFFQ".to_string(), 0) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject .lower_interface() @@ -198,7 +196,7 @@ mod tests { let _blockchain_client_server = MBCSBuilder::new(port) .response("0x01".to_string(), 1) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject.lower_interface().get_gas_price().wait().unwrap(); @@ -209,7 +207,7 @@ mod tests { fn get_gas_price_returns_error() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port).start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let error = subject .lower_interface() @@ -229,7 +227,7 @@ mod tests { let _blockchain_client_server = MBCSBuilder::new(port) .response("0x23".to_string(), 1) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject.lower_interface().get_block_number().wait(); @@ -242,7 +240,7 @@ mod tests { let _blockchain_client_server = MBCSBuilder::new(port) .response("trash".to_string(), 1) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let error = subject .lower_interface() @@ -264,7 +262,7 @@ mod tests { let _blockchain_client_server = MBCSBuilder::new(port) .response("0x23".to_string(), 1) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let wallet = &Wallet::from_str("0x3f69f9efd4f2592fd70be8c32ecd9dce71c472fc").unwrap(); let result = subject @@ -281,7 +279,7 @@ mod tests { let _blockchain_client_server = MBCSBuilder::new(port) .response("0xFFFQ".to_string(), 0) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject .lower_interface() @@ -309,7 +307,7 @@ mod tests { 0, ) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject .lower_interface() @@ -334,7 +332,7 @@ mod tests { ) .start(); let expected_err_msg = "Invalid hex"; - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject .lower_interface() @@ -361,7 +359,7 @@ mod tests { fn transaction_receipt_batch_fails_on_submit_batch() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port).start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let tx_hash_1 = H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0e") .unwrap(); @@ -419,7 +417,7 @@ mod tests { ] }"#.to_string()) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let contract_address = subject.chain.rec().contract; let start_block = BlockNumber::Number(U64::from(100)); let response_block_number = BlockNumber::Number(U64::from(200)); @@ -450,7 +448,7 @@ mod tests { topics: vec![H256::from_str( "241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80" ) - .unwrap()], + .unwrap()], data: Bytes(vec![ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 51, 16, 114, 0, 88, 197, 31, 13, 228, 86, 226, 115, 198, 38, 205, 211 @@ -459,14 +457,14 @@ mod tests { H256::from_str( "7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70" ) - .unwrap() + .unwrap() ), block_number: Some(U64::from(6040059)), transaction_hash: Some( H256::from_str( "3dc91b98249fa9f2c5c37486a2427a3a7825be240c1c84961dfb3063d9c04d50" ) - .unwrap() + .unwrap() ), transaction_index: Some(U64::from(29)), log_index: Some(U256::from(29)), @@ -501,7 +499,7 @@ mod tests { ] }"#.to_string()) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let contract_address = subject.chain.rec().contract; let start_block = BlockNumber::Number(U64::from(100)); let response_block_number = BlockNumber::Number(U64::from(200)); diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index e702e967b..139539ce9 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -21,7 +21,7 @@ use web3::types::{Address, BlockNumber, Log, H256, U256, FilterBuilder, Transact use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{LowBlockchainIntWeb3, TransactionReceiptResult}; -use crate::blockchain::blockchain_interface_utils::{create_blockchain_agent_web3, send_payables_within_batch, BlockchainAgentFutureResult}; +use crate::blockchain::blockchain_interface_utils::{dynamically_create_blockchain_agent_web3, send_payables_within_batch, BlockchainAgentFutureResult}; const CONTRACT_ABI: &str = indoc!( r#"[{ @@ -96,14 +96,13 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { ) -> Box> { let lower_level_interface = self.lower_interface(); let logger = self.logger.clone(); - let contract_address = lower_level_interface.get_contract().address(); + let contract_address = lower_level_interface.get_contract_address(); let num_chain_id = self.chain.rec().num_chain_id; Box::new( lower_level_interface.get_block_number().then(move |response_block_number_result| { let response_block_number = match response_block_number_result { Ok(block_number) => { debug!(logger, "Latest block number: {}", block_number.as_u64()); - // TODO: GH-744: This could be Eths type U64 instead of u64 block_number.as_u64() } Err(_) => { @@ -133,8 +132,8 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { .build(); lower_level_interface.get_transaction_logs(filter) .then(move |logs| { - // TODO: GH-744: change the word Transactions for Logs and also to use trace! instead of debug! - debug!(logger, "Transaction retrieval completed: {:?}", logs); + trace!(logger, "Transaction logs retrieval completed: {:?}", logs); + future::result::( match logs { Ok(logs) => { @@ -184,7 +183,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { transaction_fee_balance, masq_token_balance, }; - Ok(create_blockchain_agent_web3( + Ok(dynamically_create_blockchain_agent_web3( gas_limit_const_part, blockchain_agent_future_result, consuming_wallet, @@ -386,7 +385,6 @@ mod tests { BlockchainAgentBuildError, BlockchainError, BlockchainInterface, RetrievedBlockchainTransactions, }; - use crate::blockchain::blockchain_interface_utils::calculate_fallback_start_block_number; use crate::blockchain::test_utils::{ all_chains, make_blockchain_interface_web3, ReceiptResponseBuilder, }; @@ -448,7 +446,7 @@ mod tests { #[test] fn blockchain_interface_web3_can_return_contract() { all_chains().iter().for_each(|chain| { - let mut subject = make_blockchain_interface_web3(None); + let mut subject = make_blockchain_interface_web3(find_free_port()); subject.chain = *chain; assert_eq!(subject.contract_address(), chain.rec().contract) @@ -501,7 +499,7 @@ mod tests { }"#.to_string() ) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let end_block_nbr = 1024u64; let result = subject @@ -562,7 +560,7 @@ mod tests { .response("0x178def".to_string(), 2) .response(empty_transactions_result, 2) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let end_block_nbr = 1024u64; let result = subject @@ -615,7 +613,7 @@ mod tests { .response("0x178def", 1) .raw_response(r#"{"jsonrpc":"2.0","id":3,"result":[{"address":"0xcd6c588e005032dd882cd43bf53a32129be81302","blockHash":"0x1a24b9169cbaec3f6effa1f600b70c7ab9e8e86db44062b49132a4415d26732a","blockNumber":"0x4be663","data":"0x0000000000000000000000000000000000000000000000056bc75e2d63100000","logIndex":"0x0","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],"transactionHash":"0x955cec6ac4f832911ab894ce16aa22c3003f46deff3f7165b32700d2f5ff0681","transactionIndex":"0x0"}]}"#.to_string()) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject .retrieve_transactions( @@ -640,7 +638,7 @@ mod tests { .response("0x178def", 1) .raw_response(r#"{"jsonrpc":"2.0","id":3,"result":[{"address":"0xcd6c588e005032dd882cd43bf53a32129be81302","blockHash":"0x1a24b9169cbaec3f6effa1f600b70c7ab9e8e86db44062b49132a4415d26732a","blockNumber":"0x4be663","data":"0x0000000000000000000000000000000000000000000000056bc75e2d6310000001","logIndex":"0x0","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000003f69f9efd4f2592fd70be8c32ecd9dce71c472fc","0x000000000000000000000000adc1853c7859369639eb414b6342b36288fe6092"],"transactionHash":"0x955cec6ac4f832911ab894ce16aa22c3003f46deff3f7165b32700d2f5ff0681","transactionIndex":"0x0"}]}"#.to_string()) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject .retrieve_transactions( @@ -703,10 +701,11 @@ mod tests { .response("trash", 1) .raw_response(r#"{"jsonrpc":"2.0","id":2,"result":[{"address":"0xcd6c588e005032dd882cd43bf53a32129be81302","blockHash":"0x1a24b9169cbaec3f6effa1f600b70c7ab9e8e86db44062b49132a4415d26732a","data":"0x0000000000000000000000000000000000000000000000000010000000000000","logIndex":"0x0","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000003f69f9efd4f2592fd70be8c32ecd9dce71c472fc","0x000000000000000000000000adc1853c7859369639eb414b6342b36288fe6092"],"transactionHash":"0x955cec6ac4f832911ab894ce16aa22c3003f46deff3f7165b32700d2f5ff0681","transactionIndex":"0x0"}]}"#.to_string()) .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let start_block_nbr = 42u64; let start_block = BlockNumber::Number(start_block_nbr.into()); - let fallback_number = calculate_fallback_start_block_number(start_block_nbr, u64::MAX); + // let fallback_number = BlockchainBridge::calculate_fallback_start_block_number(start_block_nbr, u64::MAX); + let fallback_number = start_block_nbr + 1; let result = subject .retrieve_transactions( @@ -744,7 +743,7 @@ mod tests { .start(); let chain = Chain::PolyMainnet; let wallet = make_wallet("abc"); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject .build_blockchain_agent(wallet.clone()) @@ -784,7 +783,7 @@ mod tests { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port).start(); let wallet = make_wallet("abc"); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let err = subject.build_blockchain_agent(wallet).wait().err().unwrap(); @@ -801,7 +800,7 @@ mod tests { F: FnOnce(&Wallet) -> BlockchainAgentBuildError, { let wallet = make_wallet("bcd"); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject.build_blockchain_agent(wallet.clone()).wait(); let err = match result { Err(e) => e, @@ -916,7 +915,7 @@ mod tests { .raw_response(tx_receipt_response_success) .end_batch() .start(); - let subject = make_blockchain_interface_web3(Some(port)); + let subject = make_blockchain_interface_web3(port); let result = subject .process_transaction_receipts(tx_hash_vec) diff --git a/node/src/blockchain/blockchain_interface/lower_level_interface.rs b/node/src/blockchain/blockchain_interface/lower_level_interface.rs index a19b879ea..ac115c533 100644 --- a/node/src/blockchain/blockchain_interface/lower_level_interface.rs +++ b/node/src/blockchain/blockchain_interface/lower_level_interface.rs @@ -17,33 +17,33 @@ pub trait LowBlockchainInt { fn get_transaction_fee_balance( &self, address: Address, - ) -> Box>; + ) -> Box>; fn get_service_fee_balance( &self, address: Address, - ) -> Box>; + ) -> Box>; - fn get_gas_price(&self) -> Box>; + fn get_gas_price(&self) -> Box>; - fn get_block_number(&self) -> Box>; + fn get_block_number(&self) -> Box>; fn get_transaction_id( &self, address: Address, - ) -> Box>; + ) -> Box>; fn get_transaction_receipt_in_batch( &self, hash_vec: Vec, - ) -> Box>, Error = BlockchainError>>; + ) -> Box>, Error=BlockchainError>>; - fn get_contract(&self) -> Contract; + fn get_contract_address(&self) -> Address; fn get_transaction_logs( &self, filter: Filter, - ) -> Box, Error = BlockchainError>>; + ) -> Box, Error=BlockchainError>>; fn get_web3_batch(&self) -> Web3>; } diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index 97e48a344..8dbc67779 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -1,7 +1,7 @@ // Copyright (c) 2024, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. // TODO: GH-744: At the end of the review rename this file to: web3_blockchain_interface_utils.rs -// TODO: GH-744: Or we should move this file into blockchain_interface_web3 +// Or we should move this file into blockchain_interface_web3 use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::accountant::db_access_objects::pending_payable_dao::PendingPayable; @@ -186,23 +186,26 @@ pub fn sign_transaction_locally( pub fn sign_and_append_payment( chain: Chain, web3_batch: &Web3>, - recipient_wallet: Wallet, + recipient: &PayableAccount, consuming_wallet: Wallet, - amount: u128, nonce: U256, gas_price_in_wei: u128, -) -> H256 { +) -> HashAndAmount { let signed_tx = sign_transaction( chain, web3_batch, - recipient_wallet, + recipient.wallet.clone(), consuming_wallet, - amount, + recipient.balance_wei, nonce, gas_price_in_wei, ); append_signed_transaction_to_batch(web3_batch, signed_tx.raw_transaction); - signed_tx.transaction_hash + + HashAndAmount { + hash: signed_tx.transaction_hash, + amount: recipient.balance_wei, + } } pub fn append_signed_transaction_to_batch(web3_batch: &Web3>, raw_transaction: Bytes) { @@ -210,29 +213,6 @@ pub fn append_signed_transaction_to_batch(web3_batch: &Web3>, raw_tr web3_batch.eth().send_raw_transaction(raw_transaction); } -pub fn handle_new_transaction( - chain: Chain, - web3_batch: &Web3>, - consuming_wallet: Wallet, - nonce: U256, - gas_price_in_wei: u128, - account: &PayableAccount, -) -> HashAndAmount { - let hash = sign_and_append_payment( - chain, - web3_batch, - account.wallet.clone(), - consuming_wallet, - account.balance_wei, - nonce, - gas_price_in_wei, - ); - HashAndAmount { - hash, - amount: account.balance_wei, - } -} - pub fn sign_and_append_multiple_payments( logger: &Logger, chain: Chain, @@ -252,13 +232,13 @@ pub fn sign_and_append_multiple_payments( pending_nonce ); - let hash_and_amount = handle_new_transaction( + let hash_and_amount = sign_and_append_payment( chain, web3_batch, + payable, consuming_wallet.clone(), pending_nonce, gas_price_in_wei, - payable, ); pending_nonce = advance_used_nonce(pending_nonce); @@ -331,17 +311,7 @@ pub fn send_payables_within_batch( ) } -// TODO: GH-744: Migrate this to blockchain/blockchain_bridge.rs and remove pub -pub fn calculate_fallback_start_block_number(start_block_number: u64, max_block_count: u64) -> u64 { - if max_block_count == u64::MAX { - start_block_number + 1u64 - } else { - start_block_number + max_block_count - } -} - -// TODO: GH-744: This function could be part of the trait BlockchainAgent (so gas_limit_const_part can go away) -pub fn create_blockchain_agent_web3( +pub fn dynamically_create_blockchain_agent_web3( gas_limit_const_part: u128, blockchain_agent_future_result: BlockchainAgentFutureResult, wallet: Wallet, @@ -399,63 +369,6 @@ mod tests { use web3::api::Namespace; use web3::Error::Rpc; - #[test] - fn calculate_fallback_start_block_number_works() { - assert_eq!( - calculate_fallback_start_block_number(10_000, u64::MAX), - 10_000 + 1 - ); - assert_eq!( - calculate_fallback_start_block_number(5_000, 10_000), - 5_000 + 10_000 - ); - } - - #[test] - fn append_signed_transaction_to_batch_works() { - let port = find_free_port(); - let _blockchain_client_server = MBCSBuilder::new(port) - .begin_batch() - .response( - "0x8290c22bd9b4d61bc57222698799edd7bbc8df5214be44e239a95f679249c59c".to_string(), - 7, - ) - .end_batch() - .start(); - let (_event_loop_handle, transport) = Http::with_max_parallel( - &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), - REQUESTS_IN_PARALLEL, - ) - .unwrap(); - let web3_batch = Web3::new(Batch::new(transport)); - let pending_nonce = 1; - let chain = TEST_DEFAULT_CHAIN; - let gas_price = DEFAULT_GAS_PRICE; - let consuming_wallet = make_paying_wallet(b"paying_wallet"); - let account = make_payable_account(1); - let signed_transaction = sign_transaction( - chain, - &web3_batch, - account.wallet, - consuming_wallet, - account.balance_wei, - pending_nonce.into(), - (gas_price * 1_000_000_000) as u128, - ); - - append_signed_transaction_to_batch(&web3_batch, signed_transaction.raw_transaction); - - let mut batch_result = web3_batch.eth().transport().submit_batch().wait().unwrap(); - let result = batch_result.pop().unwrap().unwrap(); - assert_eq!( - result, - Value::String( - "0x8290c22bd9b4d61bc57222698799edd7bbc8df5214be44e239a95f679249c59c".to_string() - ) - ); - } - - // TODO: GH-744: Review this test. with the test above, do we really need both? #[test] fn sign_and_append_payment_works() { let port = find_free_port(); @@ -482,9 +395,8 @@ mod tests { let result = sign_and_append_payment( chain, &web3_batch, - account.wallet, + &account, consuming_wallet, - account.balance_wei, pending_nonce.into(), (gas_price * 1_000_000_000) as u128, ); @@ -492,8 +404,10 @@ mod tests { let mut batch_result = web3_batch.eth().transport().submit_batch().wait().unwrap(); assert_eq!( result, - H256::from_str("94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2") - .unwrap() + HashAndAmount { + hash: H256::from_str("94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2").unwrap(), + amount: account.balance_wei + } ); assert_eq!( batch_result.pop().unwrap().unwrap(), @@ -503,42 +417,6 @@ mod tests { ); } - // TODO: GH-744: Review this test and the test below it, do we really need both? - #[test] - fn handle_new_transaction_works() { - let port = find_free_port(); - let (_event_loop_handle, transport) = Http::with_max_parallel( - &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), - REQUESTS_IN_PARALLEL, - ) - .unwrap(); - let web3_batch = Web3::new(Batch::new(transport)); - let pending_nonce = 1; - let chain = DEFAULT_CHAIN; - let gas_price = DEFAULT_GAS_PRICE; - let consuming_wallet = make_paying_wallet(b"paying_wallet"); - let account = make_payable_account(1); - let amount = account.balance_wei; - - let result = handle_new_transaction( - chain, - &web3_batch, - consuming_wallet, - pending_nonce.into(), - (gas_price * 1_000_000_000) as u128, - &account, - ); - - let expected_hash_and_amount = HashAndAmount { - hash: H256::from_str( - "94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2", - ) - .unwrap(), - amount, - }; - assert_eq!(result, expected_hash_and_amount); - } - #[test] fn send_and_append_multiple_payments_works() { let port = find_free_port(); @@ -692,7 +570,6 @@ mod tests { ) } - // TODO: GH-744 Change gas_price & nonce from 1 to something else #[test] fn send_payables_within_batch_works() { init_test_logging(); @@ -714,8 +591,8 @@ mod tests { let logger = Logger::new(test_name); let chain = DEFAULT_CHAIN; let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let gas_price = 1_000_000_000; - let pending_nonce: U256 = 1.into(); + let gas_price = 53_000_000_000; + let pending_nonce: U256 = 97.into(); let new_fingerprints_recipient = accountant.start().recipient(); let accounts_1 = make_payable_account(1); let accounts_2 = make_payable_account(2); @@ -749,14 +626,14 @@ mod tests { vec![ HashAndAmount { hash: H256::from_str( - "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" + "27106b6f1e67f68ae1265f2c6e3d1ae9f16494fb71755555dbd30a37a8f57206" ) .unwrap(), amount: accounts_1.balance_wei }, HashAndAmount { hash: H256::from_str( - "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" + "aeebcd2de0895e0eace9dcb99bbafc134591aa22408b243f5ff895b2ec993d25" ) .unwrap(), amount: accounts_2.balance_wei @@ -769,7 +646,7 @@ mod tests { ProcessedPayableFallible::Correct(PendingPayable { recipient_wallet: accounts_1.wallet, hash: H256::from_str( - "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" + "27106b6f1e67f68ae1265f2c6e3d1ae9f16494fb71755555dbd30a37a8f57206" ) .unwrap() }) @@ -779,7 +656,7 @@ mod tests { ProcessedPayableFallible::Correct(PendingPayable { recipient_wallet: accounts_2.wallet, hash: H256::from_str( - "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" + "aeebcd2de0895e0eace9dcb99bbafc134591aa22408b243f5ff895b2ec993d25" ) .unwrap() }) diff --git a/node/src/blockchain/test_utils.rs b/node/src/blockchain/test_utils.rs index d2c595a75..0434cac52 100644 --- a/node/src/blockchain/test_utils.rs +++ b/node/src/blockchain/test_utils.rs @@ -9,7 +9,6 @@ use crate::blockchain::blockchain_interface::blockchain_interface_web3::{ use crate::blockchain::blockchain_interface::data_structures::errors::{BlockchainAgentBuildError, BlockchainError, PayableTransactionError}; use crate::blockchain::blockchain_interface::data_structures::{ProcessedPayableFallible, RetrievedBlockchainTransactions}; use crate::blockchain::blockchain_interface::lower_level_interface::LowBlockchainInt; -use crate::blockchain::blockchain_interface::BlockchainInterface; use crate::set_arbitrary_id_stamp_in_mock_impl; use crate::sub_lib::wallet::Wallet; use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp; @@ -58,15 +57,13 @@ pub fn make_meaningless_seed() -> Seed { Seed::new(&mnemonic, "passphrase") } -// TODO: GH-744: Look into removing options form port. and in places were are have defined port as None, just define a port anyway. -pub fn make_blockchain_interface_web3(port_opt: Option) -> BlockchainInterfaceWeb3 { - let port = port_opt.unwrap_or_else(|| find_free_port()); +pub fn make_blockchain_interface_web3(port: u16) -> BlockchainInterfaceWeb3 { let chain = Chain::PolyMainnet; let (event_loop_handle, transport) = Http::with_max_parallel( &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); BlockchainInterfaceWeb3::new(transport, event_loop_handle, chain) } @@ -189,127 +186,6 @@ impl ReceiptResponseBuilder { } } -#[derive(Default)] -pub struct BlockchainInterfaceMock { - get_chain_results: RefCell>, - lower_interface_result: Option>, - retrieve_transactions_parameters: Arc>>, - retrieve_transactions_results: - RefCell>>, - build_blockchain_agent_params: Arc>>, - build_blockchain_agent_results: - RefCell, BlockchainAgentBuildError>>>, - arbitrary_id_stamp_opt: Option, -} - -// TODO: GH-744: There are a few tests using BlockchainInterfaceMock, if we convert them to use MBCS then we can delete BlockchainInterfaceMock -impl BlockchainInterface for BlockchainInterfaceMock { - fn contract_address(&self) -> Address { - unimplemented!("not needed so far") - } - - fn get_chain(&self) -> Chain { - unimplemented!("not needed so far") - } - - fn retrieve_transactions( - &self, - start_block: BlockNumber, - fallback_start_block_number: u64, - recipient: Address, - ) -> Box> { - self.retrieve_transactions_parameters.lock().unwrap().push(( - start_block, - fallback_start_block_number, - recipient, - )); - Box::new(result( - self.retrieve_transactions_results.borrow_mut().remove(0), - )) - } - - fn build_blockchain_agent( - &self, - _consuming_wallet: Wallet, - ) -> Box, Error = BlockchainAgentBuildError>> { - unimplemented!("not needed so far") - } - - fn lower_interface(&self) -> Box { - unimplemented!("not needed so far") - } - - fn process_transaction_receipts( - &self, - _transaction_hashes: Vec, - ) -> Box, Error = BlockchainError>> { - unimplemented!("not needed so far") - } - - fn submit_payables_in_batch( - &self, - _logger: Logger, - _chain: Chain, - _agent: Box, - _fingerprints_recipient: Recipient, - _affordable_accounts: Vec, - ) -> Box, Error = PayableTransactionError>> - { - unimplemented!("not needed so far") - } -} - -impl BlockchainInterfaceMock { - pub fn retrieve_transactions_params( - mut self, - params: &Arc>>, - ) -> Self { - self.retrieve_transactions_parameters = params.clone(); - self - } - - pub fn retrieve_transactions_result( - self, - result: Result, - ) -> Self { - self.retrieve_transactions_results.borrow_mut().push(result); - self - } - - pub fn build_blockchain_agent_params( - mut self, - params: &Arc>>, - ) -> Self { - self.build_blockchain_agent_params = params.clone(); - self - } - - pub fn build_blockchain_agent_result( - self, - result: Result, BlockchainAgentBuildError>, - ) -> Self { - self.build_blockchain_agent_results - .borrow_mut() - .push(result); - self - } - - pub fn get_chain_result(self, result: Chain) -> Self { - self.get_chain_results.borrow_mut().push(result); - self - } - - pub fn lower_interface_results( - mut self, - aggregated_results: Box, - ) -> Self { - self.lower_interface_result = Some(aggregated_results); - self - } - - set_arbitrary_id_stamp_in_mock_impl!(); -} - pub fn make_fake_event_loop_handle() -> EventLoopHandle { Http::with_max_parallel("http://86.75.30.9", REQUESTS_IN_PARALLEL) .unwrap() diff --git a/node/src/sub_lib/blockchain_bridge.rs b/node/src/sub_lib/blockchain_bridge.rs index e31760a7b..ba0ceb00c 100644 --- a/node/src/sub_lib/blockchain_bridge.rs +++ b/node/src/sub_lib/blockchain_bridge.rs @@ -85,11 +85,12 @@ impl ConsumingWalletBalances { mod tests { use crate::actor_system_factory::SubsFactory; use crate::blockchain::blockchain_bridge::{BlockchainBridge, BlockchainBridgeSubsFactoryReal}; - use crate::blockchain::test_utils::BlockchainInterfaceMock; use crate::test_utils::persistent_configuration_mock::PersistentConfigurationMock; use crate::test_utils::recorder::{make_blockchain_bridge_subs_from_recorder, Recorder}; use actix::Actor; use std::sync::{Arc, Mutex}; + use masq_lib::utils::find_free_port; + use crate::blockchain::test_utils::make_blockchain_interface_web3; #[test] fn blockchain_bridge_subs_debug() { @@ -103,7 +104,7 @@ mod tests { #[test] fn blockchain_bridge_subs_factory_produces_proper_subs() { let subject = BlockchainBridgeSubsFactoryReal {}; - let blockchain_interface = BlockchainInterfaceMock::default(); + let blockchain_interface = make_blockchain_interface_web3(find_free_port()); let persistent_config = PersistentConfigurationMock::new(); let accountant = BlockchainBridge::new( Box::new(blockchain_interface), From ef88ab4f8a9bacf45478fa8fbb645677f71051c7 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Wed, 20 Nov 2024 21:00:25 +1300 Subject: [PATCH 33/56] GH-744: Refactored all 4 test for send_payables_within_batch --- .../blockchain_interface_web3/mod.rs | 33 +- .../blockchain/blockchain_interface_utils.rs | 434 +++++------------- 2 files changed, 132 insertions(+), 335 deletions(-) diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 139539ce9..93666659e 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -775,24 +775,6 @@ mod tests { ) } - // TODO: GH-744: Migrate test to the place after the helper function below this test. - // You'll find three more tests with a simplified api and I believe that the way it is done will suite also this test. - // Please could do this for better hygiene so that our workspace is cleaner looking forward? - #[test] - fn build_of_the_blockchain_agent_fails_on_fetching_gas_price() { - let port = find_free_port(); - let _blockchain_client_server = MBCSBuilder::new(port).start(); - let wallet = make_wallet("abc"); - let subject = make_blockchain_interface_web3(port); - - let err = subject.build_blockchain_agent(wallet).wait().err().unwrap(); - - let expected_err = BlockchainAgentBuildError::GasPrice(QueryFailed( - "Transport error: Error(IncompleteMessage)".to_string(), - )); - assert_eq!(err, expected_err) - } - fn build_of_the_blockchain_agent_fails_on_blockchain_interface_error( port: u16, expected_err_factory: F, @@ -810,6 +792,21 @@ mod tests { assert_eq!(err, expected_err) } + #[test] + fn build_of_the_blockchain_agent_fails_on_fetching_gas_price() { + let port = find_free_port(); + let _blockchain_client_server = MBCSBuilder::new(port).start(); + let wallet = make_wallet("abc"); + let subject = make_blockchain_interface_web3(port); + + let err = subject.build_blockchain_agent(wallet).wait().err().unwrap(); + + let expected_err = BlockchainAgentBuildError::GasPrice(QueryFailed( + "Transport error: Error(IncompleteMessage)".to_string(), + )); + assert_eq!(err, expected_err) + } + #[test] fn build_of_the_blockchain_agent_fails_on_transaction_fee_balance() { let port = find_free_port(); diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index 8dbc67779..c54e0ccde 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -570,33 +570,25 @@ mod tests { ) } - #[test] - fn send_payables_within_batch_works() { + fn execute_send_payables_test( + test_name: &str, + accounts: Vec, + expected_result: Result, PayableTransactionError>, + port: u16, + ) { init_test_logging(); - let test_name = "send_payables_within_batch_works"; - let port = find_free_port(); let (_event_loop_handle, transport) = Http::with_max_parallel( &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, - ) - .unwrap(); - let _blockchain_client_server = MBCSBuilder::new(port) - .begin_batch() - .response("rpc_result".to_string(), 7) - .response("rpc_result_2".to_string(), 8) - .end_batch() - .start(); + ).unwrap(); + let gas_price = 1_000_000_000; + let pending_nonce: U256 = 1.into(); let web3_batch = Web3::new(Batch::new(transport)); let (accountant, _, accountant_recording) = make_recorder(); let logger = Logger::new(test_name); let chain = DEFAULT_CHAIN; let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let gas_price = 53_000_000_000; - let pending_nonce: U256 = 97.into(); let new_fingerprints_recipient = accountant.start().recipient(); - let accounts_1 = make_payable_account(1); - let accounts_2 = make_payable_account(2); - let accounts = vec![accounts_1.clone(), accounts_2.clone()]; let system = System::new(test_name); let timestamp_before = SystemTime::now(); @@ -609,58 +601,16 @@ mod tests { pending_nonce, new_fingerprints_recipient, accounts.clone(), - ) - .wait(); + ).wait(); System::current().stop(); system.run(); let timestamp_after = SystemTime::now(); let accountant_recording_result = accountant_recording.lock().unwrap(); - let ppfs_message = - accountant_recording_result.get_record::(0); + let ppfs_message = accountant_recording_result.get_record::(0); assert_eq!(accountant_recording_result.len(), 1); assert!(timestamp_before <= ppfs_message.batch_wide_timestamp); assert!(timestamp_after >= ppfs_message.batch_wide_timestamp); - assert_eq!( - ppfs_message.hashes_and_balances, - vec![ - HashAndAmount { - hash: H256::from_str( - "27106b6f1e67f68ae1265f2c6e3d1ae9f16494fb71755555dbd30a37a8f57206" - ) - .unwrap(), - amount: accounts_1.balance_wei - }, - HashAndAmount { - hash: H256::from_str( - "aeebcd2de0895e0eace9dcb99bbafc134591aa22408b243f5ff895b2ec993d25" - ) - .unwrap(), - amount: accounts_2.balance_wei - }, - ] - ); - let processed_payments = result.unwrap(); - assert_eq!( - processed_payments[0], - ProcessedPayableFallible::Correct(PendingPayable { - recipient_wallet: accounts_1.wallet, - hash: H256::from_str( - "27106b6f1e67f68ae1265f2c6e3d1ae9f16494fb71755555dbd30a37a8f57206" - ) - .unwrap() - }) - ); - assert_eq!( - processed_payments[1], - ProcessedPayableFallible::Correct(PendingPayable { - recipient_wallet: accounts_2.wallet, - hash: H256::from_str( - "aeebcd2de0895e0eace9dcb99bbafc134591aa22408b243f5ff895b2ec993d25" - ) - .unwrap() - }) - ); let tlh = TestLogHandler::new(); tlh.exists_log_containing( &format!("DEBUG: {test_name}: Common attributes of payables to be transacted: sender wallet: {}, contract: {:?}, chain_id: {}, gas_price: {}", @@ -674,100 +624,75 @@ mod tests { "INFO: {test_name}: {}", transmission_log(chain, &accounts, gas_price) )); + assert_eq!(result, expected_result); } #[test] - fn send_payables_within_batch_fails_on_submit_batch_call() { - let port = find_free_port(); - let (_event_loop_handle, transport) = Http::with_max_parallel( - &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), - REQUESTS_IN_PARALLEL, - ) - .unwrap(); - let consuming_wallet_secret_raw_bytes = b"okay-wallet"; - let recipient_wallet = make_wallet("blah123"); - let unimportant_recipient = Recorder::new().start().recipient(); - let account = make_payable_account_with_wallet_and_balance_and_timestamp_opt( - recipient_wallet.clone(), - 5000, - None, - ); - let consuming_wallet = make_paying_wallet(consuming_wallet_secret_raw_bytes); - let gas_price = 123_000_000_000; - let nonce = U256::from(1); - let os_code = transport_error_code(); - let os_msg = transport_error_message(); - - let result = send_payables_within_batch( - &Logger::new("test"), - TEST_DEFAULT_CHAIN, - &Web3::new(Batch::new(transport)), - consuming_wallet, - gas_price, - nonce, - unimportant_recipient, - vec![account], - ) - .wait(); + fn send_payables_within_batch_works() { + let accounts = vec![make_payable_account(1), make_payable_account(2)]; + let expected_result = Ok(vec![ + Correct(PendingPayable { + recipient_wallet: accounts[0].wallet.clone(), + hash: H256::from_str("35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4").unwrap(), + }), + Correct(PendingPayable { + recipient_wallet: accounts[1].wallet.clone(), + hash: H256::from_str("7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3").unwrap(), + }), + ]); - assert_eq!( - result, - Err( - Sending { - msg: format!("Transport error: Error(Connect, Os {{ code: {}, kind: ConnectionRefused, message: {:?} }})", os_code, os_msg).to_string(), - hashes: vec![H256::from_str("424c0231591a9879d82f25e0d81e09f39499b2bfd56b3aba708491995e35b4ac").unwrap()] - } - ) - ); + let port = find_free_port(); + let _blockchain_client_server = MBCSBuilder::new(port) + .begin_batch() + .response("rpc_result".to_string(), 7) + .response("rpc_result_2".to_string(), 8) + .end_batch() + .start(); + execute_send_payables_test("send_payables_within_batch_works", accounts, expected_result, port); } #[test] - fn advance_used_nonce_works() { - let initial_nonce = U256::from(55); - - let result = advance_used_nonce(initial_nonce); - - assert_eq!(result, U256::from(56)) - } + fn send_payables_within_batch_fails_on_submit_batch_call() { + let accounts = vec![make_payable_account(1), make_payable_account(2)]; + let os_code = transport_error_code(); + let os_msg = transport_error_message(); + let expected_result = Err(Sending { + msg: format!("Transport error: Error(Connect, Os {{ code: {}, kind: ConnectionRefused, message: {:?} }})", os_code, os_msg).to_string(), + hashes: vec![ + H256::from_str("35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4").unwrap(), + H256::from_str("7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3").unwrap() + ], + }); - #[test] - #[should_panic( - expected = "Consuming wallet doesn't contain a secret key: Signature(\"Cannot sign with non-keypair wallet: Address(0x000000000000000000006261645f77616c6c6574).\")" - )] - fn sign_transaction_panics_due_to_lack_of_secret_key() { let port = find_free_port(); - let (_event_loop_handle, transport) = Http::with_max_parallel( - &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), - REQUESTS_IN_PARALLEL, - ) - .unwrap(); - let recipient_wallet = make_wallet("unlucky man"); - let consuming_wallet = make_wallet("bad_wallet"); - let gas_price = 123_000_000_000; - let nonce = U256::from(1); - - sign_transaction( - Chain::PolyAmoy, - &Web3::new(Batch::new(transport)), - recipient_wallet, - consuming_wallet, - 444444, - nonce, - gas_price, - ); + execute_send_payables_test("send_payables_within_batch_fails_on_submit_batch_call", accounts, expected_result, port); } - // TODO: GH-744: Find the tests similar to this one and refactor them to remove duplicated code. #[test] fn send_payables_within_batch_all_payments_fail() { - init_test_logging(); - let test_name = "send_payables_within_batch_all_payments_fail"; + let accounts = vec![make_payable_account(1), make_payable_account(2)]; + let expected_result = Ok(vec![ + Failed(RpcPayableFailure { + rpc_error: Rpc(Error { + code: ServerError(429), + message: "The requests per second (RPS) of your requests are higher than your plan allows.".to_string(), + data: None, + }), + recipient_wallet: accounts[0].wallet.clone(), + hash: H256::from_str("35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4").unwrap(), + }), + Failed(RpcPayableFailure { + rpc_error: Rpc(Error { + code: ServerError(429), + message: "The requests per second (RPS) of your requests are higher than your plan allows.".to_string(), + data: None, + }), + recipient_wallet: accounts[1].wallet.clone(), + hash: H256::from_str("7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3").unwrap(), + }), + ]); + let port = find_free_port(); - let (_event_loop_handle, transport) = Http::with_max_parallel( - &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), - REQUESTS_IN_PARALLEL, - ) - .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .err_response( @@ -784,104 +709,29 @@ mod tests { ) .end_batch() .start(); - let web3_batch = Web3::new(Batch::new(transport)); - let (accountant, _, accountant_recording) = make_recorder(); - let logger = Logger::new(test_name); - let chain = DEFAULT_CHAIN; - let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let gas_price = 1_000_000_000; - let pending_nonce: U256 = 1.into(); - let new_fingerprints_recipient = accountant.start().recipient(); - let accounts_1 = make_payable_account(1); - let accounts_2 = make_payable_account(2); - let accounts = vec![accounts_1.clone(), accounts_2.clone()]; - let system = System::new(test_name); - let timestamp_before = SystemTime::now(); - - let result = send_payables_within_batch( - &logger, - chain, - &web3_batch, - consuming_wallet.clone(), - gas_price, - pending_nonce, - new_fingerprints_recipient, - accounts.clone(), - ) - .wait(); - - System::current().stop(); - system.run(); - let timestamp_after = SystemTime::now(); - let accountant_recording_result = accountant_recording.lock().unwrap(); - let ppfs_message = - accountant_recording_result.get_record::(0); - assert_eq!(accountant_recording_result.len(), 1); - assert!(timestamp_before <= ppfs_message.batch_wide_timestamp); - assert!(timestamp_after >= ppfs_message.batch_wide_timestamp); - assert_eq!( - ppfs_message.hashes_and_balances, - vec![ - HashAndAmount { - hash: H256::from_str( - "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" - ) - .unwrap(), - amount: accounts_1.balance_wei - }, - HashAndAmount { - hash: H256::from_str( - "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" - ) - .unwrap(), - amount: accounts_2.balance_wei - }, - ] - ); - let processed_payments = result.unwrap(); - assert_eq!(processed_payments[0], Failed(RpcPayableFailure { - rpc_error: Rpc(Error { - code: ServerError(429), - message: "The requests per second (RPS) of your requests are higher than your plan allows.".to_string(), - data: None, - }), - recipient_wallet: accounts_1.wallet, - hash: H256::from_str("35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4").unwrap(), - })); - assert_eq!(processed_payments[1], Failed(RpcPayableFailure { - rpc_error: Rpc(Error { - code: ServerError(429), - message: "The requests per second (RPS) of your requests are higher than your plan allows.".to_string(), - data: None, - }), - recipient_wallet: accounts_2.wallet, - hash: H256::from_str("7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3").unwrap(), - })); - let tlh = TestLogHandler::new(); - tlh.exists_log_containing( - &format!("DEBUG: {test_name}: Common attributes of payables to be transacted: sender wallet: {}, contract: {:?}, chain_id: {}, gas_price: {}", - consuming_wallet, - chain.rec().contract, - chain.rec().num_chain_id, - gas_price - ) - ); - tlh.exists_log_containing(&format!( - "INFO: {test_name}: {}", - transmission_log(chain, &accounts, gas_price) - )); + execute_send_payables_test("send_payables_within_batch_all_payments_fail", accounts, expected_result, port); } #[test] fn send_payables_within_batch_one_payment_works_the_other_fails() { - init_test_logging(); - let test_name = "send_payables_within_batch_one_payment_works_the_other_fails"; + let accounts = vec![make_payable_account(1), make_payable_account(2)]; + let expected_result = Ok(vec![ + Correct(PendingPayable { + recipient_wallet: accounts[0].wallet.clone(), + hash: H256::from_str("35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4").unwrap(), + }), + Failed(RpcPayableFailure { + rpc_error: Rpc(Error { + code: ServerError(429), + message: "The requests per second (RPS) of your requests are higher than your plan allows.".to_string(), + data: None, + }), + recipient_wallet: accounts[1].wallet.clone(), + hash: H256::from_str("7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3").unwrap(), + }), + ]); + let port = find_free_port(); - let (_event_loop_handle, transport) = Http::with_max_parallel( - &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), - REQUESTS_IN_PARALLEL, - ) - .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() .response("rpc_result".to_string(), 7) @@ -893,93 +743,43 @@ mod tests { ) .end_batch() .start(); - let web3_batch = Web3::new(Batch::new(transport.clone())); - let (accountant, _, accountant_recording) = make_recorder(); - let logger = Logger::new(test_name); - let chain = DEFAULT_CHAIN; - let consuming_wallet = make_paying_wallet(b"consuming_wallet"); - let gas_price = 1_000_000_000; - let pending_nonce: U256 = 1.into(); - let new_fingerprints_recipient = accountant.start().recipient(); - let accounts_1 = make_payable_account(1); - let accounts_2 = make_payable_account(2); - let accounts = vec![accounts_1.clone(), accounts_2.clone()]; - let system = System::new(test_name); - let timestamp_before = SystemTime::now(); + execute_send_payables_test("send_payables_within_batch_one_payment_works_the_other_fails", accounts, expected_result, port); + } - let result = send_payables_within_batch( - &logger, - chain, - &web3_batch, - consuming_wallet.clone(), - gas_price, - pending_nonce, - new_fingerprints_recipient, - accounts.clone(), + #[test] + fn advance_used_nonce_works() { + let initial_nonce = U256::from(55); + + let result = advance_used_nonce(initial_nonce); + + assert_eq!(result, U256::from(56)) + } + + #[test] + #[should_panic( + expected = "Consuming wallet doesn't contain a secret key: Signature(\"Cannot sign with non-keypair wallet: Address(0x000000000000000000006261645f77616c6c6574).\")" + )] + fn sign_transaction_panics_due_to_lack_of_secret_key() { + let port = find_free_port(); + let (_event_loop_handle, transport) = Http::with_max_parallel( + &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), + REQUESTS_IN_PARALLEL, ) - .wait(); + .unwrap(); + let recipient_wallet = make_wallet("unlucky man"); + let consuming_wallet = make_wallet("bad_wallet"); + let gas_price = 123_000_000_000; + let nonce = U256::from(1); - System::current().stop(); - system.run(); - let timestamp_after = SystemTime::now(); - let accountant_recording_result = accountant_recording.lock().unwrap(); - let ppfs_message = - accountant_recording_result.get_record::(0); - assert_eq!(accountant_recording_result.len(), 1); - assert!(timestamp_before <= ppfs_message.batch_wide_timestamp); - assert!(timestamp_after >= ppfs_message.batch_wide_timestamp); - assert_eq!( - ppfs_message.hashes_and_balances, - vec![ - HashAndAmount { - hash: H256::from_str( - "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" - ) - .unwrap(), - amount: accounts_1.balance_wei - }, - HashAndAmount { - hash: H256::from_str( - "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3" - ) - .unwrap(), - amount: accounts_2.balance_wei - }, - ] - ); - let processed_payments = result.unwrap(); - assert_eq!( - processed_payments[0], - ProcessedPayableFallible::Correct(PendingPayable { - recipient_wallet: accounts_1.wallet, - hash: H256::from_str( - "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4" - ) - .unwrap() - }) - ); - assert_eq!(processed_payments[1], ProcessedPayableFallible::Failed(RpcPayableFailure { - rpc_error: Rpc(Error { - code: ServerError(429), - message: "The requests per second (RPS) of your requests are higher than your plan allows.".to_string(), - data: None, - }), - recipient_wallet: accounts_2.wallet, - hash: H256::from_str("7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3").unwrap(), - })); - let tlh = TestLogHandler::new(); - tlh.exists_log_containing( - &format!("DEBUG: {test_name}: Common attributes of payables to be transacted: sender wallet: {}, contract: {:?}, chain_id: {}, gas_price: {}", - consuming_wallet, - chain.rec().contract, - chain.rec().num_chain_id, - gas_price - ) + sign_transaction( + Chain::PolyAmoy, + &Web3::new(Batch::new(transport)), + recipient_wallet, + consuming_wallet, + 444444, + nonce, + gas_price, ); - tlh.exists_log_containing(&format!( - "INFO: {test_name}: {}", - transmission_log(chain, &accounts, gas_price) - )); } #[test] From f18b8a65fc0df1b99b28f857a7aacc6c039481d8 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Wed, 20 Nov 2024 21:07:01 +1300 Subject: [PATCH 34/56] GH-744: cleanup & formatting --- node/src/accountant/mod.rs | 68 ++++++++-------- node/src/blockchain/blockchain_bridge.rs | 42 +++++----- .../lower_level_interface_web3.rs | 23 +++--- .../blockchain_interface_web3/mod.rs | 24 +++--- .../lower_level_interface.rs | 15 ++-- .../blockchain/blockchain_interface_utils.rs | 78 +++++++++++++------ node/src/blockchain/test_utils.rs | 24 +----- node/src/sub_lib/blockchain_bridge.rs | 4 +- 8 files changed, 152 insertions(+), 126 deletions(-) diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index 0ac3c69d7..a2aea8ad4 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -743,7 +743,7 @@ impl Accountant { stats_opt, query_results_opt, } - .tmb(context_id) + .tmb(context_id) } fn request_payable_accounts_by_specific_mode( @@ -1032,11 +1032,11 @@ pub fn checked_conversion>(num: T) -> S { politely_checked_conversion(num).unwrap_or_else(|msg| panic!("{}", msg)) } -pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { +pub fn gwei_to_wei + From + From, S>(gwei: S) -> T { (T::from(gwei)).mul(T::from(WEIS_IN_GWEI as u32)) } -pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { +pub fn wei_to_gwei, S: Display + Copy + Div + From>(wei: S) -> T { checked_conversion::(wei.div(S::from(WEIS_IN_GWEI as u32))) } @@ -1364,7 +1364,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Receivables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1456,7 +1456,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::Payables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1523,7 +1523,8 @@ mod tests { } #[test] - fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge() { + fn received_balances_and_qualified_payables_under_our_money_limit_thus_all_forwarded_to_blockchain_bridge( + ) { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1615,7 +1616,8 @@ mod tests { } #[test] - fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge() { + fn received_qualified_payables_exceeding_our_masq_balance_are_adjusted_before_forwarded_to_blockchain_bridge( + ) { // the numbers for balances don't do real math, they need not to match either the condition for // the payment adjustment or the actual values that come from the payable size reducing algorithm; // all that is mocked in this test @@ -1763,7 +1765,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; subject_addr.try_send(ui_message).unwrap(); @@ -1818,7 +1820,7 @@ mod tests { body: UiScanRequest { scan_type: ScanType::PendingPayables, } - .tmb(4321), + .tmb(4321), }; let second_message = first_message.clone(); let peer_actors = peer_actors_builder() @@ -2009,7 +2011,8 @@ mod tests { } #[test] - fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block() { + fn accountant_processes_msg_with_received_payments_using_receivables_dao_and_then_updates_start_block( + ) { let more_money_received_params_arc = Arc::new(Mutex::new(vec![])); let commit_params_arc = Arc::new(Mutex::new(vec![])); let set_by_guest_transaction_params_arc = Arc::new(Mutex::new(vec![])); @@ -2709,7 +2712,7 @@ mod tests { addr.try_send(ScanForPayables { response_skeleton_opt: None, }) - .unwrap(); + .unwrap(); // We ignored the second ScanForPayables message because the first message meant a scan // was already in progress; now let's make it look like that scan has ended so that we @@ -2722,7 +2725,7 @@ mod tests { .mark_as_ended(&Logger::new("irrelevant")) }), }) - .unwrap(); + .unwrap(); addr.try_send(message_after.clone()).unwrap(); system.run(); let recording = blockchain_bridge_recording.lock().unwrap(); @@ -4027,7 +4030,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4111,7 +4114,7 @@ mod tests { top_records_opt: None, custom_queries_opt: None, } - .tmb(2222), + .tmb(2222), }; subject_addr.try_send(ui_message).unwrap(); @@ -4174,7 +4177,7 @@ mod tests { }), query_results_opt: None } - .tmb(context_id) + .tmb(context_id) ) } @@ -4251,12 +4254,12 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 58, pending_payable_hash_opt: None - }, ]), + },]), receivable_opt: Some(vec![UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), age_s: extracted_receivable_ages[0], balance_gwei: 3_788_455 - }, ]) + },]) }), } ); @@ -4417,7 +4420,7 @@ mod tests { age_s: extracted_payable_ages[0], balance_gwei: 5, pending_payable_hash_opt: None - }, ]), + },]), receivable_opt: Some(vec![ UiReceivableAccount { wallet: make_wallet("efe4848").to_string(), @@ -4606,7 +4609,8 @@ mod tests { expected = "Broken code: PayableAccount with less than 1 gwei passed through db query \ constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 8686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei() { + fn compute_financials_blows_up_on_screwed_sql_query_for_payables_returning_balance_smaller_than_one_gwei( + ) { let payable_accounts_retrieved = vec![PayableAccount { wallet: make_wallet("abcd123"), balance_wei: 8_686_005, @@ -4642,7 +4646,8 @@ mod tests { expected = "Broken code: ReceivableAccount with balance between 1 and 0 gwei passed through \ db query constraints; wallet: 0x0000000000000000000000000061626364313233, balance: 7686005" )] - fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei() { + fn compute_financials_blows_up_on_screwed_sql_query_for_receivables_returning_balance_smaller_than_one_gwei( + ) { let receivable_accounts_retrieved = vec![ReceivableAccount { wallet: make_wallet("abcd123"), balance_wei: 7_686_005, @@ -4881,10 +4886,11 @@ pub mod exportable_test_parts { } } - fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao() -> ShouldWeRunTheTest { + fn verify_presence_of_user_defined_sqlite_fns_in_new_delinquencies_for_receivable_dao( + ) -> ShouldWeRunTheTest { fn skip_down_to_first_line_saying_new_delinquencies( - previous: impl Iterator, - ) -> impl Iterator { + previous: impl Iterator, + ) -> impl Iterator { previous .skip_while(|line| { let adjusted_line: String = line @@ -4895,7 +4901,7 @@ pub mod exportable_test_parts { }) .skip(1) } - fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { + fn assert_is_not_trait_definition(body_lines: impl Iterator) -> String { fn yield_if_contains_semicolon(line: &str) -> Option { line.contains(';').then(|| line.to_string()) } @@ -4934,13 +4940,13 @@ pub mod exportable_test_parts { skip_down_to_first_line_saying_new_delinquencies( lines_with_cut_fn_trait_definition, ) - .take_while(|line| { - let adjusted_line: String = line - .chars() - .skip_while(|char| char.is_whitespace()) - .collect(); - !adjusted_line.starts_with("fn") - }); + .take_while(|line| { + let adjusted_line: String = line + .chars() + .skip_while(|char| char.is_whitespace()) + .collect(); + !adjusted_line.starts_with("fn") + }); assert_is_not_trait_definition(assumed_implemented_function_body) } fn user_defined_functions_detected(line_undivided_fn_body: &str) -> bool { diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 80a35edb3..e32e5203b 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -246,7 +246,7 @@ impl BlockchainBridge { fn handle_qualified_payable_msg( &mut self, incoming_message: QualifiedPayablesMessage, - ) -> Box> { + ) -> Box> { // TODO rewrite this into a batch call as soon as GH-629 gets into master let accountant_recipient = self.payable_payments_setup_subs_opt.clone(); Box::new( @@ -271,7 +271,7 @@ impl BlockchainBridge { fn handle_outbound_payments_instructions( &mut self, msg: OutboundPaymentsInstructions, - ) -> Box> { + ) -> Box> { let skeleton_opt = msg.response_skeleton_opt; let sent_payable_subs = self .sent_payable_subs_opt @@ -306,7 +306,7 @@ impl BlockchainBridge { fn handle_retrieve_transactions( &mut self, msg: RetrieveTransactions, - ) -> Box> { + ) -> Box> { let (start_block_nbr, max_block_count) = { let persistent_config_lock = self .persistent_config_arc @@ -388,7 +388,7 @@ impl BlockchainBridge { fn handle_request_transaction_receipts( &mut self, msg: RequestTransactionReceipts, - ) -> Box> { + ) -> Box> { let logger = self.logger.clone(); let accountant_recipient = self .pending_payable_confirmation @@ -439,7 +439,7 @@ impl BlockchainBridge { fn handle_scan_future(&mut self, handler: F, scan_type: ScanType, msg: M) where - F: FnOnce(&mut BlockchainBridge, M) -> Box>, + F: FnOnce(&mut BlockchainBridge, M) -> Box>, M: SkeletonOptHolder, { let skeleton_opt = msg.skeleton_opt(); @@ -473,7 +473,7 @@ impl BlockchainBridge { &self, agent: Box, affordable_accounts: Vec, - ) -> Box, Error=PayableTransactionError>> + ) -> Box, Error = PayableTransactionError>> { let new_fingerprints_recipient = self.new_fingerprints_recipient(); let logger = self.logger.clone(); @@ -552,8 +552,7 @@ mod tests { BlockchainTransaction, RetrievedBlockchainTransactions, }; use crate::blockchain::test_utils::{ - make_blockchain_interface_web3, make_tx_hash, - ReceiptResponseBuilder, + make_blockchain_interface_web3, make_tx_hash, ReceiptResponseBuilder, }; use crate::db_config::persistent_configuration::PersistentConfigError; use crate::match_every_type_id; @@ -624,7 +623,7 @@ mod tests { addr.try_send(BindMessage { peer_actors: peer_actors_builder().build(), }) - .unwrap(); + .unwrap(); System::current().stop(); system.run(); @@ -667,7 +666,8 @@ mod tests { } #[test] - fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant() { + fn qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant( + ) { let system = System::new( "qualified_payables_msg_is_handled_and_new_msg_with_an_added_blockchain_agent_returns_to_accountant", ); @@ -826,7 +826,8 @@ mod tests { } #[test] - fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant() { + fn handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant( + ) { let system = System::new( "handle_outbound_payments_instructions_sees_payments_happen_and_sends_payment_results_back_to_accountant", ); @@ -894,7 +895,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap() + .unwrap() })]), response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, @@ -910,7 +911,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -985,7 +986,7 @@ mod tests { hash: H256::from_str( "36e9d7cdd657181317dd461192d537d9944c57a51ee950607de5a618b00e57a1" ) - .unwrap(), + .unwrap(), amount: accounts[0].balance_wei }] ); @@ -1051,7 +1052,7 @@ mod tests { hash: H256::from_str( "cc73f3d5fe9fc3dac28b510ddeb157b0f8030b201e809014967396cdf365488a" ) - .unwrap() + .unwrap() }) ); assert_eq!( @@ -1061,7 +1062,7 @@ mod tests { hash: H256::from_str( "891d9ffa838aedc0bb2f6f7e9737128ce98bb33d07b4c8aa5645871e20d6cd13" ) - .unwrap() + .unwrap() }) ); let recording = accountant_recording.lock().unwrap(); @@ -1255,7 +1256,8 @@ mod tests { } #[test] - fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort() { + fn handle_request_transaction_receipts_short_circuits_on_failure_from_remote_process_sends_back_all_good_results_and_logs_abort( + ) { init_test_logging(); let port = find_free_port(); let block_number = U64::from(4545454); @@ -1512,12 +1514,12 @@ mod tests { BlockchainTransaction { block_number: 6040059, from: make_wallet("first_wallet"), // Points to topics of 1 - wei_amount: 42, // Its points to the field data + wei_amount: 42, // Its points to the field data }, BlockchainTransaction { block_number: 6040060, from: make_wallet("second_wallet"), // Points to topics of 1 - wei_amount: 55, // Its points to the field data + wei_amount: 55, // Its points to the field data }, ], }; @@ -2111,7 +2113,7 @@ pub mod exportable_test_parts { use crate::test_utils::unshared_test_utils::SubsFactoryTestAddrLeaker; impl SubsFactory - for SubsFactoryTestAddrLeaker + for SubsFactoryTestAddrLeaker { fn make(&self, addr: &Addr) -> BlockchainBridgeSubs { self.send_leaker_msg_and_return_meaningless_subs( diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index e86148c1d..0049df8cd 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -32,7 +32,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_fee_balance( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.web3 .eth() @@ -44,7 +44,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_service_fee_balance( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.contract .query("balanceOf", address, None, Options::default(), None) @@ -52,7 +52,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } - fn get_gas_price(&self) -> Box> { + fn get_gas_price(&self) -> Box> { Box::new( self.web3 .eth() @@ -61,7 +61,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { ) } - fn get_block_number(&self) -> Box> { + fn get_block_number(&self) -> Box> { Box::new( self.web3 .eth() @@ -73,7 +73,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_id( &self, address: Address, - ) -> Box> { + ) -> Box> { Box::new( self.web3 .eth() @@ -85,7 +85,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_receipt_in_batch( &self, hash_vec: Vec, - ) -> Box>, Error=BlockchainError>> { + ) -> Box>, Error = BlockchainError>> { let _ = hash_vec.into_iter().map(|hash| { self.web3_batch.eth().transaction_receipt(hash); }); @@ -104,7 +104,7 @@ impl LowBlockchainInt for LowBlockchainIntWeb3 { fn get_transaction_logs( &self, filter: Filter, - ) -> Box, Error=BlockchainError>> { + ) -> Box, Error = BlockchainError>> { Box::new( self.web3 .eth() @@ -166,7 +166,8 @@ mod tests { } #[test] - fn get_transaction_fee_balance_returns_an_error_for_unintelligible_response_to_requesting_eth_balance() { + fn get_transaction_fee_balance_returns_an_error_for_unintelligible_response_to_requesting_eth_balance( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0xFFFQ".to_string(), 0) @@ -448,7 +449,7 @@ mod tests { topics: vec![H256::from_str( "241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80" ) - .unwrap()], + .unwrap()], data: Bytes(vec![ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 51, 16, 114, 0, 88, 197, 31, 13, 228, 86, 226, 115, 198, 38, 205, 211 @@ -457,14 +458,14 @@ mod tests { H256::from_str( "7c5a35e9cb3e8ae0e221ab470abae9d446c3a5626ce6689fc777dcffcab52c70" ) - .unwrap() + .unwrap() ), block_number: Some(U64::from(6040059)), transaction_hash: Some( H256::from_str( "3dc91b98249fa9f2c5c37486a2427a3a7825be240c1c84961dfb3063d9c04d50" ) - .unwrap() + .unwrap() ), transaction_index: Some(U64::from(29)), log_index: Some(U256::from(29)), diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 93666659e..2909cce3a 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -93,7 +93,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { start_block: BlockNumber, fallback_start_block_number: u64, recipient: Address, - ) -> Box> { + ) -> Box> { let lower_level_interface = self.lower_interface(); let logger = self.logger.clone(); let contract_address = lower_level_interface.get_contract_address(); @@ -151,7 +151,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { fn build_blockchain_agent( &self, consuming_wallet: Wallet, - ) -> Box, Error=BlockchainAgentBuildError>> { + ) -> Box, Error = BlockchainAgentBuildError>> { let wallet_address = consuming_wallet.address(); let gas_limit_const_part = self.gas_limit_const_part; // TODO: Would it be better to wrap these 3 calls into a single batch call? @@ -197,7 +197,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { fn process_transaction_receipts( &self, transaction_hashes: Vec, - ) -> Box, Error=BlockchainError>> { + ) -> Box, Error = BlockchainError>> { Box::new( self.lower_interface() .get_transaction_receipt_in_batch(transaction_hashes) @@ -241,7 +241,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { agent: Box, fingerprints_recipient: Recipient, affordable_accounts: Vec, - ) -> Box, Error=PayableTransactionError>> + ) -> Box, Error = PayableTransactionError>> { let consuming_wallet = agent.consuming_wallet().clone(); let web3_batch = self.lower_interface().get_web3_batch(); @@ -607,7 +607,8 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned() { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_too_few_topics_is_returned( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -632,7 +633,8 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned() { + fn blockchain_interface_web3_retrieve_transactions_returns_an_error_if_a_response_with_data_that_is_too_long_is_returned( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x178def", 1) @@ -654,7 +656,8 @@ mod tests { } #[test] - fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number() { + fn blockchain_interface_web3_retrieve_transactions_ignores_transaction_logs_that_have_no_block_number( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("0x400", 1) @@ -665,7 +668,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let end_block_nbr = 1024u64; let subject = @@ -695,7 +698,8 @@ mod tests { } #[test] - fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one() { + fn blockchain_interface_non_clandestine_retrieve_transactions_uses_block_number_latest_as_fallback_start_block_plus_one( + ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .response("trash", 1) @@ -767,7 +771,7 @@ mod tests { ); let expected_fee_estimation = (3 * (BlockchainInterfaceWeb3::web3_gas_limit_const_part(chain) - + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) + + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) * expected_gas_price_wei) as u128; assert_eq!( result.estimated_transaction_fee_total(3), diff --git a/node/src/blockchain/blockchain_interface/lower_level_interface.rs b/node/src/blockchain/blockchain_interface/lower_level_interface.rs index ac115c533..6e33d5c00 100644 --- a/node/src/blockchain/blockchain_interface/lower_level_interface.rs +++ b/node/src/blockchain/blockchain_interface/lower_level_interface.rs @@ -4,7 +4,6 @@ use crate::blockchain::blockchain_interface::data_structures::errors::Blockchain use ethereum_types::{H256, U64}; use futures::Future; use serde_json::Value; -use web3::contract::Contract; use web3::transports::{Batch, Http}; use web3::types::{Address, Filter, Log, U256}; use web3::{Error, Web3}; @@ -17,33 +16,33 @@ pub trait LowBlockchainInt { fn get_transaction_fee_balance( &self, address: Address, - ) -> Box>; + ) -> Box>; fn get_service_fee_balance( &self, address: Address, - ) -> Box>; + ) -> Box>; - fn get_gas_price(&self) -> Box>; + fn get_gas_price(&self) -> Box>; - fn get_block_number(&self) -> Box>; + fn get_block_number(&self) -> Box>; fn get_transaction_id( &self, address: Address, - ) -> Box>; + ) -> Box>; fn get_transaction_receipt_in_batch( &self, hash_vec: Vec, - ) -> Box>, Error=BlockchainError>>; + ) -> Box>, Error = BlockchainError>>; fn get_contract_address(&self) -> Address; fn get_transaction_logs( &self, filter: Filter, - ) -> Box, Error=BlockchainError>>; + ) -> Box, Error = BlockchainError>>; fn get_web3_batch(&self) -> Web3>; } diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index c54e0ccde..7ab1b8afd 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -132,7 +132,7 @@ pub fn gas_limit(data: [u8; 68], chain: Chain) -> U256 { ethereum_types::U256::try_from(data.iter().fold(base_gas_limit, |acc, v| { acc + if v == &0u8 { 4 } else { 68 } })) - .expect("Internal error") + .expect("Internal error") } pub fn sign_transaction( @@ -257,7 +257,7 @@ pub fn send_payables_within_batch( pending_nonce: U256, new_fingerprints_recipient: Recipient, accounts: Vec, -) -> Box, Error=PayableTransactionError> + 'static> +) -> Box, Error = PayableTransactionError> + 'static> { debug!( logger, @@ -294,7 +294,7 @@ pub fn send_payables_within_batch( logger, "{}", transmission_log(chain, &accounts, gas_price_in_wei) - ); + ); Box::new( web3_batch @@ -351,7 +351,7 @@ mod tests { use crate::sub_lib::wallet::Wallet; use crate::test_utils::make_paying_wallet; use crate::test_utils::make_wallet; - use crate::test_utils::recorder::{make_recorder, Recorder}; + use crate::test_utils::recorder::make_recorder; use crate::test_utils::unshared_test_utils::decode_hex; use actix::{Actor, System}; use ethabi::Address; @@ -384,7 +384,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let pending_nonce = 1; let chain = DEFAULT_CHAIN; let gas_price = DEFAULT_GAS_PRICE; @@ -405,7 +405,10 @@ mod tests { assert_eq!( result, HashAndAmount { - hash: H256::from_str("94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2").unwrap(), + hash: H256::from_str( + "94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2" + ) + .unwrap(), amount: account.balance_wei } ); @@ -425,7 +428,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3_batch = Web3::new(Batch::new(transport)); let chain = DEFAULT_CHAIN; let gas_price = DEFAULT_GAS_PRICE; @@ -452,14 +455,14 @@ mod tests { hash: H256::from_str( "94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2" ) - .unwrap(), + .unwrap(), amount: 1000000000 }, HashAndAmount { hash: H256::from_str( "3811874d2b73cecd51234c94af46bcce918d0cb4de7d946c01d7da606fe761b5" ) - .unwrap(), + .unwrap(), amount: 2000000000 } ] @@ -580,7 +583,8 @@ mod tests { let (_event_loop_handle, transport) = Http::with_max_parallel( &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, - ).unwrap(); + ) + .unwrap(); let gas_price = 1_000_000_000; let pending_nonce: U256 = 1.into(); let web3_batch = Web3::new(Batch::new(transport)); @@ -601,13 +605,15 @@ mod tests { pending_nonce, new_fingerprints_recipient, accounts.clone(), - ).wait(); + ) + .wait(); System::current().stop(); system.run(); let timestamp_after = SystemTime::now(); let accountant_recording_result = accountant_recording.lock().unwrap(); - let ppfs_message = accountant_recording_result.get_record::(0); + let ppfs_message = + accountant_recording_result.get_record::(0); assert_eq!(accountant_recording_result.len(), 1); assert!(timestamp_before <= ppfs_message.batch_wide_timestamp); assert!(timestamp_after >= ppfs_message.batch_wide_timestamp); @@ -633,11 +639,17 @@ mod tests { let expected_result = Ok(vec![ Correct(PendingPayable { recipient_wallet: accounts[0].wallet.clone(), - hash: H256::from_str("35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4").unwrap(), + hash: H256::from_str( + "35f42b260f090a559e8b456718d9c91a9da0f234ed0a129b9d5c4813b6615af4", + ) + .unwrap(), }), Correct(PendingPayable { recipient_wallet: accounts[1].wallet.clone(), - hash: H256::from_str("7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3").unwrap(), + hash: H256::from_str( + "7f3221109e4f1de8ba1f7cd358aab340ecca872a1456cb1b4f59ca33d3e22ee3", + ) + .unwrap(), }), ]); @@ -648,7 +660,12 @@ mod tests { .response("rpc_result_2".to_string(), 8) .end_batch() .start(); - execute_send_payables_test("send_payables_within_batch_works", accounts, expected_result, port); + execute_send_payables_test( + "send_payables_within_batch_works", + accounts, + expected_result, + port, + ); } #[test] @@ -665,7 +682,12 @@ mod tests { }); let port = find_free_port(); - execute_send_payables_test("send_payables_within_batch_fails_on_submit_batch_call", accounts, expected_result, port); + execute_send_payables_test( + "send_payables_within_batch_fails_on_submit_batch_call", + accounts, + expected_result, + port, + ); } #[test] @@ -709,7 +731,12 @@ mod tests { ) .end_batch() .start(); - execute_send_payables_test("send_payables_within_batch_all_payments_fail", accounts, expected_result, port); + execute_send_payables_test( + "send_payables_within_batch_all_payments_fail", + accounts, + expected_result, + port, + ); } #[test] @@ -743,7 +770,12 @@ mod tests { ) .end_batch() .start(); - execute_send_payables_test("send_payables_within_batch_one_payment_works_the_other_fails", accounts, expected_result, port); + execute_send_payables_test( + "send_payables_within_batch_one_payment_works_the_other_fails", + accounts, + expected_result, + port, + ); } #[test] @@ -765,7 +797,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let recipient_wallet = make_wallet("unlucky man"); let consuming_wallet = make_wallet("bad_wallet"); let gas_price = 123_000_000_000; @@ -789,7 +821,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let web3 = Web3::new(transport.clone()); let chain = DEFAULT_CHAIN; let amount = 11_222_333_444; @@ -835,7 +867,7 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let chain = DEFAULT_CHAIN; let amount = 11_222_333_444; let gas_limit = U256::from(5); @@ -963,13 +995,13 @@ mod tests { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST.to_string(), port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); let consuming_wallet = { let key_pair = Bip32EncryptionKeyProvider::from_raw_secret( &decode_hex("97923d8fd8de4a00f912bfb77ef483141dec551bd73ea59343ef5c4aac965d04") .unwrap(), ) - .unwrap(); + .unwrap(); Wallet::from(key_pair) }; let recipient_wallet = { diff --git a/node/src/blockchain/test_utils.rs b/node/src/blockchain/test_utils.rs index 0434cac52..4124e283a 100644 --- a/node/src/blockchain/test_utils.rs +++ b/node/src/blockchain/test_utils.rs @@ -2,39 +2,21 @@ #![cfg(test)] -use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; use crate::blockchain::blockchain_interface::blockchain_interface_web3::{ BlockchainInterfaceWeb3, REQUESTS_IN_PARALLEL, }; -use crate::blockchain::blockchain_interface::data_structures::errors::{BlockchainAgentBuildError, BlockchainError, PayableTransactionError}; -use crate::blockchain::blockchain_interface::data_structures::{ProcessedPayableFallible, RetrievedBlockchainTransactions}; -use crate::blockchain::blockchain_interface::lower_level_interface::LowBlockchainInt; -use crate::set_arbitrary_id_stamp_in_mock_impl; -use crate::sub_lib::wallet::Wallet; -use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp; use bip39::{Language, Mnemonic, Seed}; use ethabi::Hash; use ethereum_types::{BigEndianHash, H160, H256, U64}; -use futures::future::result; -use futures::Future; use lazy_static::lazy_static; use masq_lib::blockchains::chains::Chain; -use masq_lib::utils::{find_free_port, to_string}; +use masq_lib::utils::to_string; use serde::Serialize; use serde_derive::Deserialize; -use std::cell::RefCell; use std::fmt::Debug; use std::net::Ipv4Addr; -use std::sync::{Arc, Mutex}; -use actix::Recipient; use web3::transports::{EventLoopHandle, Http}; -use web3::types::{ - Address, BlockNumber, Index, Log, SignedTransaction, TransactionReceipt, H2048, U256, -}; -use masq_lib::logger::Logger; -use crate::accountant::db_access_objects::payable_dao::PayableAccount; -use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; -use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; +use web3::types::{Index, Log, SignedTransaction, TransactionReceipt, H2048, U256}; lazy_static! { static ref BIG_MEANINGLESS_PHRASE: Vec<&'static str> = vec![ @@ -63,7 +45,7 @@ pub fn make_blockchain_interface_web3(port: u16) -> BlockchainInterfaceWeb3 { &format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port), REQUESTS_IN_PARALLEL, ) - .unwrap(); + .unwrap(); BlockchainInterfaceWeb3::new(transport, event_loop_handle, chain) } diff --git a/node/src/sub_lib/blockchain_bridge.rs b/node/src/sub_lib/blockchain_bridge.rs index ba0ceb00c..a6fc4dd3c 100644 --- a/node/src/sub_lib/blockchain_bridge.rs +++ b/node/src/sub_lib/blockchain_bridge.rs @@ -85,12 +85,12 @@ impl ConsumingWalletBalances { mod tests { use crate::actor_system_factory::SubsFactory; use crate::blockchain::blockchain_bridge::{BlockchainBridge, BlockchainBridgeSubsFactoryReal}; + use crate::blockchain::test_utils::make_blockchain_interface_web3; use crate::test_utils::persistent_configuration_mock::PersistentConfigurationMock; use crate::test_utils::recorder::{make_blockchain_bridge_subs_from_recorder, Recorder}; use actix::Actor; - use std::sync::{Arc, Mutex}; use masq_lib::utils::find_free_port; - use crate::blockchain::test_utils::make_blockchain_interface_web3; + use std::sync::{Arc, Mutex}; #[test] fn blockchain_bridge_subs_debug() { From a5e6f68fe59535924dc7b6a4fa61facb47d616a9 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Wed, 20 Nov 2024 21:50:49 +1300 Subject: [PATCH 35/56] GH-744: small fixs --- node/src/blockchain/blockchain_interface_utils.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index 7ab1b8afd..be94f8a2c 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -27,7 +27,7 @@ use std::iter::once; use std::time::SystemTime; use thousands::Separable; use web3::transports::{Batch, Http}; -use web3::types::{Bytes, SignedTransaction, TransactionParameters, H256, U256}; +use web3::types::{Bytes, SignedTransaction, TransactionParameters, U256}; use web3::Error as Web3Error; use web3::Web3; @@ -220,10 +220,10 @@ pub fn sign_and_append_multiple_payments( consuming_wallet: Wallet, gas_price_in_wei: u128, mut pending_nonce: U256, - accounts: &Vec, + accounts: &[PayableAccount], ) -> Vec { let mut hash_and_amount_list = vec![]; - accounts.into_iter().for_each(|payable| { + accounts.iter().for_each(|payable| { debug!( logger, "Preparing payable future of {} wei to {} with nonce {}", @@ -355,6 +355,7 @@ mod tests { use crate::test_utils::unshared_test_utils::decode_hex; use actix::{Actor, System}; use ethabi::Address; + use ethereum_types::H256; use jsonrpc_core::ErrorCode::ServerError; use jsonrpc_core::{Error, ErrorCode}; use masq_lib::constants::{DEFAULT_CHAIN, DEFAULT_GAS_PRICE}; From 3d4f552a4e3a8b7b221b86b7048134fa50c52ed0 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Sat, 23 Nov 2024 00:20:32 +1300 Subject: [PATCH 36/56] GH-744: handle_normal_client_data detects wildcard IP & localhost with error --- .../tests/blockchain_interaction_test.rs | 2 +- node/src/neighborhood/mod.rs | 11 +- node/src/proxy_server/mod.rs | 109 +++++++++++++++++- 3 files changed, 109 insertions(+), 13 deletions(-) diff --git a/multinode_integration_tests/tests/blockchain_interaction_test.rs b/multinode_integration_tests/tests/blockchain_interaction_test.rs index 42381891c..02a063d87 100644 --- a/multinode_integration_tests/tests/blockchain_interaction_test.rs +++ b/multinode_integration_tests/tests/blockchain_interaction_test.rs @@ -144,7 +144,7 @@ fn debtors_are_credited_once_but_not_twice() { let config_dao = config_dao(&node_name); assert_eq!( config_dao.get("start_block").unwrap().value_opt.unwrap(), - "2001" + "2000" ); } } diff --git a/node/src/neighborhood/mod.rs b/node/src/neighborhood/mod.rs index cb98e53f3..c8b3e0da7 100644 --- a/node/src/neighborhood/mod.rs +++ b/node/src/neighborhood/mod.rs @@ -10,7 +10,7 @@ pub mod overall_connection_status; use std::collections::HashSet; use std::convert::TryFrom; -use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use std::net::{IpAddr, SocketAddr}; use std::path::PathBuf; use actix::Context; @@ -507,15 +507,6 @@ impl Neighborhood { } fn handle_route_query_message(&mut self, msg: RouteQueryMessage) -> Option { - if let Some(ref url) = msg.hostname_opt { - if let Ok(ip) = url.parse::() { - if ip == IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)) { - error!(self.logger, "Request to wildcard IP detected 0.0.0.0. Most likely because Blockchain Service URL is not set"); - return None; - } - } - } - let debug_msg_opt = self.logger.debug_enabled().then(|| format!("{:?}", msg)); let route_result = if self.mode == NeighborhoodModeLight::ZeroHop { Ok(self.zero_hop_route_response()) diff --git a/node/src/proxy_server/mod.rs b/node/src/proxy_server/mod.rs index 058c7c12f..0a333e26d 100644 --- a/node/src/proxy_server/mod.rs +++ b/node/src/proxy_server/mod.rs @@ -50,8 +50,9 @@ use masq_lib::ui_gateway::NodeFromUiMessage; use masq_lib::utils::MutabilityConflictHelper; use regex::Regex; use std::collections::HashMap; -use std::net::SocketAddr; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use std::rc::Rc; +use std::str::FromStr; use std::time::{Duration, SystemTime}; use tokio::prelude::Future; @@ -1066,7 +1067,26 @@ impl IBCDHelper for IBCDHelperReal { let stream_key = proxy.find_or_generate_stream_key(&msg); let timestamp = msg.timestamp; let payload = match proxy.make_payload(msg, &stream_key) { - Ok(payload) => payload, + Ok(payload) => { + // todo!("Hit me"); + debug!(Logger::new("test"), "*url: {:?}", payload.target_hostname); + let mut error_message_opt = None; + if let Some(host_name) = &payload.target_hostname { + error_message_opt = match IpAddr::from_str(host_name) { + Ok(ip_addr) => match ip_addr { + IpAddr::V4(ipv4addr) => validate4(ipv4addr), + IpAddr::V6(ipv6addr) => validate6(ipv6addr) + }, + Err(_) => validate_name(host_name) + }; + } + debug!(Logger::new("test"), "*Error message: {:?}", error_message_opt); + + match error_message_opt { + None => payload, + Some(e) => return Err(format!("Request to wildcard IP detected - {} (Most likely because Blockchain Service URL is not set)", e)) + } + }, Err(e) => return Err(e), }; @@ -1230,6 +1250,39 @@ impl Hostname { } } +fn validate4(addr: Ipv4Addr) -> Option { + return if addr.octets() == [0, 0, 0, 0] { + Some("0.0.0.0".to_string()) + } + else if addr.octets() == [127, 0, 0, 1] { + Some("127.0.0.1".to_string()) + } + else { + None + } +} + +fn validate6(addr: Ipv6Addr) -> Option { + return if addr.segments() == [0, 0, 0, 0, 0, 0, 0, 0] { + Some("::".to_string()) + } + else if addr.segments() == [0, 0, 0, 0, 0, 0, 0, 1] { + Some("::1".to_string()) + } + else { + None + } +} + +fn validate_name(name: &str) -> Option { + return if name == "localhost" { + Some("localhost".to_string()) + } + else { + None + } +} + #[cfg(test)] mod tests { use super::*; @@ -2535,6 +2588,58 @@ mod tests { ); } + #[test] + fn proxy_server_sends_a_message_with_error_when_quad_zeros_are_detected() { + init_test_logging(); + let test_name = "proxy_server_sends_a_message_with_error_when_quad_zeros_are_detected"; + let cryptde = main_cryptde(); + let http_request = b"GET /index.html HTTP/1.1\r\nHost: 0.0.0.0\r\n\r\n"; + let (proxy_server_mock, _, proxy_server_recording_arc) = make_recorder(); + let route_query_response = None; + let (neighborhood_mock, _, _) = make_recorder(); + let neighborhood_mock = + neighborhood_mock.route_query_response(route_query_response.clone()); + let socket_addr = SocketAddr::from_str("1.2.3.4:5678").unwrap(); + let stream_key = StreamKey::make_meaningless_stream_key(); + let expected_data = http_request.to_vec(); + let msg_from_dispatcher = InboundClientData { + timestamp: SystemTime::now(), + peer_addr: socket_addr.clone(), + reception_port: Some(HTTP_PORT), + sequence_number: Some(0), + last_data: true, + is_clandestine: false, + data: expected_data.clone(), + }; + let stream_key_factory = StreamKeyFactoryMock::new().make_result(stream_key); + let system = System::new(test_name); + let mut subject = ProxyServer::new( + cryptde, + alias_cryptde(), + true, + Some(STANDARD_CONSUMING_WALLET_BALANCE), + false, + ); + subject.stream_key_factory = Box::new(stream_key_factory); + subject.logger = Logger::new(test_name); + let subject_addr: Addr = subject.start(); + let mut peer_actors = peer_actors_builder() + .proxy_server(proxy_server_mock) + .neighborhood(neighborhood_mock) + .build(); + // Get the dns_retry_result recipient so we can partially mock it... + let dns_retry_result_recipient = peer_actors.proxy_server.route_result_sub; + peer_actors.proxy_server.route_result_sub = dns_retry_result_recipient; //Partial mocking + subject_addr.try_send(BindMessage { peer_actors }).unwrap(); + + subject_addr.try_send(msg_from_dispatcher).unwrap(); + + System::current().stop(); + system.run(); + + TestLogHandler::new().exists_log_containing(&format!("ERROR: {test_name}: Request to wildcard IP detected - 0.0.0.0 (Most likely because Blockchain Service URL is not set)")); + } + #[test] fn proxy_server_uses_existing_route() { let main_cryptde = main_cryptde(); From 4de72c8d28f622dc1f18168848ed90dee7eef085 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 25 Nov 2024 22:08:50 +1300 Subject: [PATCH 37/56] GH-744: Finished all urgent comments --- node/src/neighborhood/mod.rs | 25 -------- node/src/proxy_server/mod.rs | 118 +++++++++++++++++++++-------------- 2 files changed, 72 insertions(+), 71 deletions(-) diff --git a/node/src/neighborhood/mod.rs b/node/src/neighborhood/mod.rs index c8b3e0da7..e46e2abce 100644 --- a/node/src/neighborhood/mod.rs +++ b/node/src/neighborhood/mod.rs @@ -2627,31 +2627,6 @@ mod tests { assert_eq!(result, None); } - #[test] - fn route_query_responds_with_none_when_wildcard_ip_is_requested() { - init_test_logging(); - let test_name = "route_query_responds_with_none_when_wildcard_ip_is_requested"; - let system = System::new(test_name); - let mut subject = make_standard_subject(); - subject.logger = Logger::new(test_name); - let addr: Addr = subject.start(); - let sub: Recipient = addr.recipient::(); - - let future = sub.send(RouteQueryMessage::data_indefinite_route_request( - Some("0.0.0.0".to_string()), - 430, - )); - - System::current().stop_with_code(0); - system.run(); - let result = future.wait().unwrap(); - assert_eq!(result, None); - TestLogHandler::new().exists_log_containing(&format!( - "ERROR: {}: Request to wildcard IP detected 0.0.0.0. Most likely because Blockchain Service URL is not set", - test_name - )); - } - #[test] fn route_query_works_when_node_is_set_for_one_hop_and_no_consuming_wallet() { let cryptde = main_cryptde(); diff --git a/node/src/proxy_server/mod.rs b/node/src/proxy_server/mod.rs index 0a333e26d..4d221a8f7 100644 --- a/node/src/proxy_server/mod.rs +++ b/node/src/proxy_server/mod.rs @@ -1068,25 +1068,13 @@ impl IBCDHelper for IBCDHelperReal { let timestamp = msg.timestamp; let payload = match proxy.make_payload(msg, &stream_key) { Ok(payload) => { - // todo!("Hit me"); - debug!(Logger::new("test"), "*url: {:?}", payload.target_hostname); - let mut error_message_opt = None; - if let Some(host_name) = &payload.target_hostname { - error_message_opt = match IpAddr::from_str(host_name) { - Ok(ip_addr) => match ip_addr { - IpAddr::V4(ipv4addr) => validate4(ipv4addr), - IpAddr::V6(ipv6addr) => validate6(ipv6addr) - }, - Err(_) => validate_name(host_name) - }; - } - debug!(Logger::new("test"), "*Error message: {:?}", error_message_opt); - - match error_message_opt { - None => payload, - Some(e) => return Err(format!("Request to wildcard IP detected - {} (Most likely because Blockchain Service URL is not set)", e)) + if let Some(hostname) = &payload.target_hostname { + if let Err(e) = Hostname::new(hostname).is_valid() { + return Err(format!("Request to wildcard IP detected - {} (Most likely because Blockchain Service URL is not set)", e)); + } } - }, + payload + } Err(e) => return Err(e), }; @@ -1233,7 +1221,6 @@ struct Hostname { } impl Hostname { - #[allow(dead_code)] fn new(raw_url: &str) -> Self { let regex = Regex::new( r"^((http[s]?|ftp):/)?/?([^:/\s]+)((/\w+)*/)([\w\-.]+[^#?\s]+)(.*)?(#[\w\-]+)?$", @@ -1248,38 +1235,43 @@ impl Hostname { }; Self { hostname } } -} -fn validate4(addr: Ipv4Addr) -> Option { - return if addr.octets() == [0, 0, 0, 0] { - Some("0.0.0.0".to_string()) - } - else if addr.octets() == [127, 0, 0, 1] { - Some("127.0.0.1".to_string()) - } - else { - None + fn is_valid(&self) -> Result<(), String> { + match IpAddr::from_str(&self.hostname) { + Ok(ip_addr) => match ip_addr { + IpAddr::V4(ipv4addr) => Self::validate_ipv4(ipv4addr), + IpAddr::V6(ipv6addr) => Self::validate_ipv6(ipv6addr), + }, + Err(_) => Self::validate_raw_string(&self.hostname), + } } -} -fn validate6(addr: Ipv6Addr) -> Option { - return if addr.segments() == [0, 0, 0, 0, 0, 0, 0, 0] { - Some("::".to_string()) - } - else if addr.segments() == [0, 0, 0, 0, 0, 0, 0, 1] { - Some("::1".to_string()) - } - else { - None + fn validate_ipv4(addr: Ipv4Addr) -> Result<(), String> { + if addr.octets() == [0, 0, 0, 0] { + Err("0.0.0.0".to_string()) + } else if addr.octets() == [127, 0, 0, 1] { + Err("127.0.0.1".to_string()) + } else { + Ok(()) + } } -} -fn validate_name(name: &str) -> Option { - return if name == "localhost" { - Some("localhost".to_string()) + fn validate_ipv6(addr: Ipv6Addr) -> Result<(), String> { + if addr.segments() == [0, 0, 0, 0, 0, 0, 0, 0] { + Err("::".to_string()) + } else if addr.segments() == [0, 0, 0, 0, 0, 0, 0, 1] { + Err("::1".to_string()) + } else { + Ok(()) + } } - else { - None + + fn validate_raw_string(name: &str) -> Result<(), String> { + if name == "localhost" { + Err("localhost".to_string()) + } else { + Ok(()) + } } } @@ -2594,7 +2586,7 @@ mod tests { let test_name = "proxy_server_sends_a_message_with_error_when_quad_zeros_are_detected"; let cryptde = main_cryptde(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: 0.0.0.0\r\n\r\n"; - let (proxy_server_mock, _, proxy_server_recording_arc) = make_recorder(); + let (proxy_server_mock, _, _) = make_recorder(); let route_query_response = None; let (neighborhood_mock, _, _) = make_recorder(); let neighborhood_mock = @@ -6024,6 +6016,40 @@ mod tests { assert_eq!(expected_result, clean_hostname); } + #[test] + fn hostname_is_valid_works() { + // IPv4 + assert_eq!( + Hostname::new("0.0.0.0").is_valid(), + Err("0.0.0.0".to_string()) + ); + assert_eq!( + Hostname::new("127.0.0.1").is_valid(), + Err("127.0.0.1".to_string()) + ); + assert_eq!(Hostname::new("192.168.1.158").is_valid(), Ok(())); + // IPv6 + assert_eq!( + Hostname::new("0:0:0:0:0:0:0:0").is_valid(), + Err("::".to_string()) + ); + assert_eq!( + Hostname::new("0:0:0:0:0:0:0:1").is_valid(), + Err("::1".to_string()) + ); + assert_eq!( + Hostname::new("2001:0db8:85a3:0000:0000:8a2e:0370:7334").is_valid(), + Ok(()) + ); + // Hostname + assert_eq!( + Hostname::new("localhost").is_valid(), + Err("localhost".to_string()) + ); + assert_eq!(Hostname::new("example.com").is_valid(), Ok(())); + assert_eq!(Hostname::new("https://example.com").is_valid(), Ok(())); + } + #[test] #[should_panic( expected = "ProxyServer should never get ShutdownStreamMsg about clandestine stream" From 9a6bcb416e2c72e64222ebc4abae56b9a5745047 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Wed, 4 Dec 2024 21:08:45 +1300 Subject: [PATCH 38/56] GH-744: changed actions macos-12 to 13 --- .github/workflows/ci-matrix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-matrix.yml b/.github/workflows/ci-matrix.yml index 71a537d48..845add861 100644 --- a/.github/workflows/ci-matrix.yml +++ b/.github/workflows/ci-matrix.yml @@ -14,7 +14,7 @@ jobs: matrix: target: - { name: linux, os: ubuntu-22.04 } - - { name: macos, os: macos-12 } + - { name: macos, os: macos-13 } - { name: windows, os: windows-2022 } name: Build node on ${{ matrix.target.os }} From 749933267a2bfde7de06dd17297aaf97d046ef31 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Wed, 4 Dec 2024 21:50:27 +1300 Subject: [PATCH 39/56] GH-744: increased sleep time for test provided_and_consumed_services_are_recorded_in_databases --- multinode_integration_tests/tests/bookkeeping_test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multinode_integration_tests/tests/bookkeeping_test.rs b/multinode_integration_tests/tests/bookkeeping_test.rs index 41642a724..cbed01e84 100644 --- a/multinode_integration_tests/tests/bookkeeping_test.rs +++ b/multinode_integration_tests/tests/bookkeeping_test.rs @@ -42,7 +42,7 @@ fn provided_and_consumed_services_are_recorded_in_databases() { let payables = non_pending_payables(&originating_node); // Waiting until the serving nodes have finished accruing their receivables - thread::sleep(Duration::from_secs(7)); + thread::sleep(Duration::from_secs(10)); // get all receivables from all other nodes let receivable_balances = non_originating_nodes From e2317ae41cae33ce3d99976ed0972a3e327574ef Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 16 Dec 2024 21:59:07 +1300 Subject: [PATCH 40/56] GH-744: Fixed multinode tests --- multinode_integration_tests/docker/Dockerfile | 3 +- .../tests/communication_failure_test.rs | 78 +++++++++---------- .../tests/data_routing_test.rs | 2 +- .../tests/verify_bill_payment.rs | 2 +- 4 files changed, 43 insertions(+), 42 deletions(-) diff --git a/multinode_integration_tests/docker/Dockerfile b/multinode_integration_tests/docker/Dockerfile index 9adb3b09b..e33d2ee53 100644 --- a/multinode_integration_tests/docker/Dockerfile +++ b/multinode_integration_tests/docker/Dockerfile @@ -2,7 +2,8 @@ #FROM debian:stable-slim #FROM debian:buster-slim #FROM debian:bullseye-slim -FROM debian:bookworm-slim +#FROM debian:bookworm-slim +FROM debian:trixie-slim RUN apt-get update && \ apt-get install -y libc6 && \ diff --git a/multinode_integration_tests/tests/communication_failure_test.rs b/multinode_integration_tests/tests/communication_failure_test.rs index c71b4b4e6..b35a5d5df 100644 --- a/multinode_integration_tests/tests/communication_failure_test.rs +++ b/multinode_integration_tests/tests/communication_failure_test.rs @@ -28,7 +28,6 @@ use node_lib::sub_lib::versioned_data::VersionedData; use node_lib::test_utils::assert_string_contains; use node_lib::test_utils::neighborhood_test_utils::{db_from_node, make_node_record}; use std::convert::TryInto; -use std::net::Ipv4Addr; use std::thread; use std::time::Duration; @@ -272,44 +271,45 @@ fn dns_resolution_failure_with_real_nodes() { ); } -#[test] -fn dns_resolution_failure_for_wildcard_ip_with_real_nodes() { - let dns_server_that_fails = Ipv4Addr::new(1, 1, 1, 3).into(); - let mut cluster = MASQNodeCluster::start().unwrap(); - let exit_node = cluster.start_real_node( - NodeStartupConfigBuilder::standard() - .chain(cluster.chain) - .consuming_wallet_info(make_consuming_wallet_info("exit_node")) - .dns_servers(vec![dns_server_that_fails]) - .build(), - ); - let originating_node = cluster.start_real_node( - NodeStartupConfigBuilder::standard() - .neighbor(exit_node.node_reference()) - .consuming_wallet_info(make_consuming_wallet_info("originating_node")) - .chain(cluster.chain) - .min_hops(Hops::OneHop) - .build(), - ); - - thread::sleep(Duration::from_millis(1000)); - let mut client = originating_node.make_client(8080, STANDARD_CLIENT_TIMEOUT_MILLIS); - client.send_chunk(b"GET / HTTP/1.1\r\nHost: www.xvideos.com\r\n\r\n"); - let response = client.wait_for_chunk(); - - assert_eq!( - index_of(&response, &b"

Title: DNS Resolution Problem

"[..]).is_some(), - true, - "Actual response:\n{}", - String::from_utf8(response.clone()).unwrap() - ); - assert_eq!( - index_of(&response, &b"

DNS Failure, We have tried multiple Exit Nodes and all have failed to resolve this address www.xvideos.com

"[..]).is_some(), - true, - "Actual response:\n{}", - String::from_utf8(response).unwrap() - ); -} +// >>> TODO: GH-744: - Re-Enable this test. +// #[test] +// fn dns_resolution_failure_for_wildcard_ip_with_real_nodes() { +// let dns_server_that_fails = Ipv4Addr::new(1, 1, 1, 3).into(); +// let mut cluster = MASQNodeCluster::start().unwrap(); +// let exit_node = cluster.start_real_node( +// NodeStartupConfigBuilder::standard() +// .chain(cluster.chain) +// .consuming_wallet_info(make_consuming_wallet_info("exit_node")) +// .dns_servers(vec![dns_server_that_fails]) +// .build(), +// ); +// let originating_node = cluster.start_real_node( +// NodeStartupConfigBuilder::standard() +// .neighbor(exit_node.node_reference()) +// .consuming_wallet_info(make_consuming_wallet_info("originating_node")) +// .chain(cluster.chain) +// .min_hops(Hops::OneHop) +// .build(), +// ); +// +// thread::sleep(Duration::from_millis(1000)); +// let mut client = originating_node.make_client(8080, STANDARD_CLIENT_TIMEOUT_MILLIS); +// client.send_chunk(b"GET / HTTP/1.1\r\nHost: www.xvideos.com\r\n\r\n"); +// let response = client.wait_for_chunk(); +// +// assert_eq!( +// index_of(&response, &b"

Title: DNS Resolution Problem

"[..]).is_some(), +// true, +// "Actual response:\n{}", +// String::from_utf8(response.clone()).unwrap() +// ); +// assert_eq!( +// index_of(&response, &b"

DNS Failure, We have tried multiple Exit Nodes and all have failed to resolve this address www.xvideos.com

"[..]).is_some(), +// true, +// "Actual response:\n{}", +// String::from_utf8(response).unwrap() +// ); +// } #[test] fn dns_resolution_failure_no_longer_blacklists_exit_node_for_all_hosts() { diff --git a/multinode_integration_tests/tests/data_routing_test.rs b/multinode_integration_tests/tests/data_routing_test.rs index 0b3fa9d21..0c4cef279 100644 --- a/multinode_integration_tests/tests/data_routing_test.rs +++ b/multinode_integration_tests/tests/data_routing_test.rs @@ -316,7 +316,7 @@ fn multiple_stream_zero_hop_test() { let mut another_client = zero_hop_node.make_client(8080, STANDARD_CLIENT_TIMEOUT_MILLIS); one_client.send_chunk(b"GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"); - another_client.send_chunk(b"GET /online/ HTTP/1.1\r\nHost: whatever.neverssl.com\r\n\r\n"); + another_client.send_chunk(b"GET /online/ HTTP/1.1\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\r\nAccept-Language: cs-CZ,cs;q=0.9,en;q=0.8,sk;q=0.7\r\nCache-Control: max-age=0\r\nConnection: keep-alive\r\nHost: whatever.neverssl.com\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36\r\n\r\n"); let one_response = one_client.wait_for_chunk(); let another_response = another_client.wait_for_chunk(); diff --git a/multinode_integration_tests/tests/verify_bill_payment.rs b/multinode_integration_tests/tests/verify_bill_payment.rs index a894640d7..e649deba3 100644 --- a/multinode_integration_tests/tests/verify_bill_payment.rs +++ b/multinode_integration_tests/tests/verify_bill_payment.rs @@ -233,7 +233,7 @@ fn verify_bill_payment() { assert_balances( &contract_owner_wallet, &blockchain_interface, - "99995074522000000000", + "99995231980000000000", "471999999700000000000000000", ); From 1c4b7f07683ae43c3d442db86f79825415ff9251 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Tue, 17 Dec 2024 20:10:37 +1300 Subject: [PATCH 41/56] GH-744: Added start block +1 to handle_transaction_logs --- node/src/blockchain/blockchain_bridge.rs | 1 + .../blockchain_interface_web3/mod.rs | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index ed65c43f7..420b2925e 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -566,6 +566,7 @@ impl BlockchainBridge { start_block_number } else { start_block_number + 1u64 // TODO: GH-744 Way are we adding +1 can we just return the same value? + //start_block_number } } else { start_block_number + max_block_count diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 7c3acc877..661558365 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -372,7 +372,7 @@ impl BlockchainInterfaceWeb3 { ); Ok(RetrievedBlockchainTransactions { - new_start_block: transaction_max_block_number, + new_start_block: transaction_max_block_number + 1, transactions, }) } @@ -715,8 +715,7 @@ mod tests { let subject = make_blockchain_interface_web3(port); let start_block_nbr = 42u64; let start_block = BlockNumber::Number(start_block_nbr.into()); - // let fallback_number = BlockchainBridge::calculate_fallback_start_block_number(start_block_nbr, u64::MAX); - let fallback_number = start_block_nbr + 1; + let fallback_number = start_block_nbr; let result = subject .retrieve_transactions( @@ -728,11 +727,11 @@ mod tests { ) .wait(); - let expected_fallback_start_block = start_block_nbr + 1u64; + let expected_start_block = fallback_number + 1u64; assert_eq!( result, Ok(RetrievedBlockchainTransactions { - new_start_block: expected_fallback_start_block, + new_start_block: expected_start_block, transactions: vec![] }) ); From e80e1d037edc862c431bc8da01ef617277fdfc08 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Tue, 17 Dec 2024 20:12:32 +1300 Subject: [PATCH 42/56] GH-744: Fixed some tests --- .../payable_scanner/agent_null.rs | 7 ++ .../payable_scanner/agent_web3.rs | 13 ++- .../payable_scanner/blockchain_agent.rs | 3 + .../payable_scanner/test_utils.rs | 26 +++++- node/src/accountant/scanners/mod.rs | 4 +- node/src/actor_system_factory.rs | 86 ------------------- node/src/blockchain/blockchain_bridge.rs | 13 +-- .../lower_level_interface_web3.rs | 6 +- .../blockchain_interface_web3/mod.rs | 12 +-- .../lower_level_interface.rs | 1 - .../blockchain/blockchain_interface/mod.rs | 4 - .../blockchain/blockchain_interface_utils.rs | 2 + node/src/proxy_server/mod.rs | 12 +-- 13 files changed, 69 insertions(+), 120 deletions(-) diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs index 036d1d72f..31f0758e4 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs @@ -5,7 +5,9 @@ use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockch use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; use ethereum_types::U256; +use masq_lib::blockchains::chains::Chain; use masq_lib::logger::Logger; +use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; #[derive(Clone)] pub struct BlockchainAgentNull { @@ -37,6 +39,11 @@ impl BlockchainAgent for BlockchainAgentNull { &self.wallet } + fn get_chain(&self) -> Chain { + self.log_function_call("get_chain()"); + TEST_DEFAULT_CHAIN + } + #[cfg(test)] fn dup(&self) -> Box { intentionally_blank!() diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs index c31c7ebbb..1cb9fbc73 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs @@ -1,5 +1,6 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. +use masq_lib::blockchains::chains::Chain; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; @@ -11,6 +12,7 @@ pub struct BlockchainAgentWeb3 { maximum_added_gas_margin: u128, consuming_wallet: Wallet, consuming_wallet_balances: ConsumingWalletBalances, + chain: Chain } impl BlockchainAgent for BlockchainAgentWeb3 { @@ -31,6 +33,10 @@ impl BlockchainAgent for BlockchainAgentWeb3 { fn consuming_wallet(&self) -> &Wallet { &self.consuming_wallet } + + fn get_chain(&self) -> Chain { + self.chain + } } // 64 * (64 - 12) ... std transaction has data of 64 bytes and 12 bytes are never used with us; @@ -43,6 +49,7 @@ impl BlockchainAgentWeb3 { gas_limit_const_part: u128, consuming_wallet: Wallet, consuming_wallet_balances: ConsumingWalletBalances, + chain: Chain ) -> Self { Self { gas_price_wei, @@ -50,6 +57,7 @@ impl BlockchainAgentWeb3 { consuming_wallet, maximum_added_gas_margin: WEB3_MAXIMAL_GAS_LIMIT_MARGIN, consuming_wallet_balances, + chain } } } @@ -65,6 +73,8 @@ mod tests { use crate::test_utils::make_wallet; use web3::types::U256; + use masq_lib::constants::DEFAULT_CHAIN; + use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; #[test] fn constants_are_correct() { @@ -86,6 +96,7 @@ mod tests { gas_limit_const_part, consuming_wallet.clone(), consuming_wallet_balances, + TEST_DEFAULT_CHAIN ); assert_eq!(subject.agreed_fee_per_computation_unit(), gas_price_gwei); @@ -104,7 +115,7 @@ mod tests { masq_token_balance_in_minor_units: Default::default(), }; let agent = - BlockchainAgentWeb3::new(444, 77_777, consuming_wallet, consuming_wallet_balances); + BlockchainAgentWeb3::new(444, 77_777, consuming_wallet, consuming_wallet_balances, TEST_DEFAULT_CHAIN); let result = agent.estimated_transaction_fee_total(3); diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs index 70918ed77..f883f627b 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs @@ -1,5 +1,6 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. +use masq_lib::blockchains::chains::Chain; use crate::arbitrary_id_stamp_in_trait; use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; @@ -26,6 +27,8 @@ pub trait BlockchainAgent: Send { fn agreed_fee_per_computation_unit(&self) -> u128; fn consuming_wallet(&self) -> &Wallet; + fn get_chain(&self) -> Chain; + #[cfg(test)] fn dup(&self) -> Box { intentionally_blank!() diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs index ee1706b36..6536ccf6c 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs @@ -8,13 +8,28 @@ use crate::sub_lib::wallet::Wallet; use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp; use crate::{arbitrary_id_stamp_in_trait_impl, set_arbitrary_id_stamp_in_mock_impl}; use std::cell::RefCell; +use masq_lib::blockchains::chains::Chain; +use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; + -#[derive(Default)] pub struct BlockchainAgentMock { consuming_wallet_balances_results: RefCell>, agreed_fee_per_computation_unit_results: RefCell>, consuming_wallet_result_opt: Option, arbitrary_id_stamp_opt: Option, + get_chain_result_opt: Option +} + +impl Default for BlockchainAgentMock { + fn default() -> Self { + BlockchainAgentMock{ + consuming_wallet_balances_results: RefCell::new(vec![]), + agreed_fee_per_computation_unit_results: RefCell::new(vec![]), + consuming_wallet_result_opt: None, + arbitrary_id_stamp_opt: None, + get_chain_result_opt: Some(TEST_DEFAULT_CHAIN), + } + } } impl BlockchainAgent for BlockchainAgentMock { @@ -36,6 +51,10 @@ impl BlockchainAgent for BlockchainAgentMock { self.consuming_wallet_result_opt.as_ref().unwrap() } + fn get_chain(&self) -> Chain { + self.get_chain_result_opt.unwrap() + } + fn dup(&self) -> Box { intentionally_blank!() } @@ -63,5 +82,10 @@ impl BlockchainAgentMock { self } + pub fn get_chain_result(mut self, get_chain_result: Chain) -> Self { + self.get_chain_result_opt = Some(get_chain_result); + self + } + set_arbitrary_id_stamp_in_mock_impl!(); } diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index 83fa85e56..9fd9ac46d 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -654,8 +654,6 @@ impl PendingPayableScanner { msg: ReportTransactionReceipts, logger: &Logger, ) -> PendingPayableScanReport { - // TODO: We want to ensure that failed transactions are not marked still pending, - // and also adjust log levels accordingly. fn handle_none_receipt( mut scan_report: PendingPayableScanReport, payable: PendingPayableFingerprint, @@ -689,7 +687,7 @@ impl PendingPayableScanner { "none was given".to_string(), logger, ), - TransactionReceiptResult::Error(e) => handle_none_receipt( + TransactionReceiptResult::LocalError(e) => handle_none_receipt( scan_report_so_far, fingerprint, format!("failed due to {}", e), diff --git a/node/src/actor_system_factory.rs b/node/src/actor_system_factory.rs index 70f00c92b..536f840e7 100644 --- a/node/src/actor_system_factory.rs +++ b/node/src/actor_system_factory.rs @@ -2001,92 +2001,6 @@ mod tests { ) } - #[test] - fn blockchain_bridge_is_constructed_with_correctly_functioning_connections() { - let test_name = "blockchain_bridge_is_constructed_with_correctly_functioning_connections"; - let data_dir = ensure_node_home_directory_exists("actor_system_factory", test_name); - let port = find_free_port(); - let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0) - .response( - vec![LogObject { - removed: false, - log_index: Some("0x20".to_string()), - transaction_index: Some("0x30".to_string()), - transaction_hash: Some( - "0x2222222222222222222222222222222222222222222222222222222222222222" - .to_string(), - ), - block_hash: Some( - "0x1111111111111111111111111111111111111111111111111111111111111111" - .to_string(), - ), - block_number: Some("0x7D0".to_string()), // 2000 decimal - address: "0x3333333333333333333333333333333333333334".to_string(), - data: "0x000000000000000000000000000000000000000000000000000000003b5dc100" - .to_string(), - topics: vec![ - "0xddf252ad1be2c89b69c2b0680000000000006561726e696e675f77616c6c6574" - .to_string(), - "0xddf252ad1be2c89b69c2b0690000000000006561726e696e675f77616c6c6574" - .to_string(), - ], - }], - 1, - ) - .start(); - let server_url = format!("http://{}:{}", &Ipv4Addr::LOCALHOST, port); - let _persistent_config = { - let conn = DbInitializerReal::default() - .initialize(&data_dir, DbInitializationConfig::test_default()) - .unwrap(); - PersistentConfigurationReal::from(conn) - }; - let wallet = make_wallet("abc"); - let mut bootstrapper_config = BootstrapperConfig::new(); - bootstrapper_config - .blockchain_bridge_config - .blockchain_service_url_opt = Some(server_url); - bootstrapper_config.blockchain_bridge_config.chain = TEST_DEFAULT_CHAIN; - bootstrapper_config.data_directory = data_dir.clone(); - let system = System::new(test_name); - let (accountant, _, accountant_recording) = make_recorder(); - let accountant = accountant.system_stop_conditions(match_every_type_id!(ReceivedPayments)); - let peer_actors = peer_actors_builder().accountant(accountant).build(); - let (tx, blockchain_bridge_addr_rx) = bounded(1); - let address_leaker = SubsFactoryTestAddrLeaker { address_leaker: tx }; - - ActorFactoryReal::new() - .make_and_start_blockchain_bridge(&bootstrapper_config, &address_leaker); - - let blockchain_bridge_addr = blockchain_bridge_addr_rx.try_recv().unwrap(); - blockchain_bridge_addr - .try_send(BindMessage { - peer_actors: peer_actors, - }) - .unwrap(); - blockchain_bridge_addr - .try_send(RetrieveTransactions { - recipient: wallet.clone(), - response_skeleton_opt: None, - }) - .unwrap(); - assert_eq!(system.run(), 0); - let recording = accountant_recording.lock().unwrap(); - let received_payments_message = recording.get_record::(0); - assert_eq!( - received_payments_message.payments_and_start_block, - PaymentsAndStartBlock { - payments: vec![BlockchainTransaction { - block_number: 2000, - from: Wallet::new("0x0000000000006561726e696e675f77616c6c6574"), - wei_amount: 996000000 - }], - new_start_block: 1000000000 - } - ); - } - #[test] fn load_banned_cache_implements_panic_on_migration() { let data_dir = ensure_node_home_directory_exists( diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index ed65c43f7..8c17a085b 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -580,10 +580,8 @@ impl BlockchainBridge { { let new_fingerprints_recipient = self.new_fingerprints_recipient(); let logger = self.logger.clone(); - let chain = self.blockchain_interface.get_chain(); self.blockchain_interface.submit_payables_in_batch( logger, - chain, agent, new_fingerprints_recipient, affordable_accounts, @@ -968,7 +966,8 @@ mod tests { let agent = BlockchainAgentMock::default() .set_arbitrary_id_stamp(agent_id_stamp) .agreed_fee_per_computation_unit_result(123) - .consuming_wallet_result(consuming_wallet); + .consuming_wallet_result(consuming_wallet) + .get_chain_result(Chain::PolyMainnet); send_bind_message!(subject_subs, peer_actors); @@ -1056,7 +1055,8 @@ mod tests { let consuming_wallet = make_paying_wallet(b"consuming_wallet"); let agent = BlockchainAgentMock::default() .consuming_wallet_result(consuming_wallet) - .agreed_fee_per_computation_unit_result(123); + .agreed_fee_per_computation_unit_result(123) + .get_chain_result(Chain::PolyMainnet);; send_bind_message!(subject_subs, peer_actors); let _ = addr @@ -1128,7 +1128,8 @@ mod tests { let system = System::new(test_name); let agent = BlockchainAgentMock::default() .consuming_wallet_result(consuming_wallet) - .agreed_fee_per_computation_unit_result(1); + .agreed_fee_per_computation_unit_result(1) + .get_chain_result(Chain::PolyMainnet); let msg = OutboundPaymentsInstructions::new(accounts, Box::new(agent), None); let persistent_config = PersistentConfigurationMock::new(); let mut subject = BlockchainBridge::new( @@ -1462,7 +1463,7 @@ mod tests { (TransactionReceiptResult::NotPresent, fingerprint_1), (TransactionReceiptResult::Found(transaction_receipt), fingerprint_2), (TransactionReceiptResult::NotPresent, fingerprint_3), - (TransactionReceiptResult::Error("RPC error: Error { code: ServerError(429), message: \"The requests per second (RPS) of your requests are higher than your plan allows.\", data: None }".to_string()), fingerprint_4) + (TransactionReceiptResult::LocalError("RPC error: Error { code: ServerError(429), message: \"The requests per second (RPS) of your requests are higher than your plan allows.\", data: None }".to_string()), fingerprint_4) ], response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index 0049df8cd..b06950330 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -17,8 +17,8 @@ use web3::{Error, Web3}; pub enum TransactionReceiptResult { NotPresent, Found(TransactionReceipt), - TransactionFailed(TransactionReceipt), // RemoteFailure - Error(String), // LocalFailure + TransactionFailed(TransactionReceipt), // RemoteFail ure + LocalError(String), // LocalFailure } pub struct LowBlockchainIntWeb3 { @@ -356,6 +356,8 @@ mod tests { ) } + + #[test] fn transaction_receipt_batch_fails_on_submit_batch() { let port = find_free_port(); diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 7c3acc877..583c99a99 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -162,6 +162,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { let get_service_fee_balance = self .lower_interface() .get_service_fee_balance(wallet_address); + let chain = self.chain; Box::new( get_gas_price @@ -187,6 +188,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { gas_limit_const_part, blockchain_agent_future_result, consuming_wallet, + chain )) }) }) @@ -222,12 +224,12 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { if e.to_string().contains("invalid type: null") { TransactionReceiptResult::NotPresent } else { - TransactionReceiptResult::Error(e.to_string()) + TransactionReceiptResult::LocalError(e.to_string()) } } } } - Err(e) => TransactionReceiptResult::Error(e.to_string()), + Err(e) => TransactionReceiptResult::LocalError(e.to_string()), }) .collect::>()) }), @@ -237,7 +239,6 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { fn submit_payables_in_batch( &self, logger: Logger, - chain: Chain, agent: Box, fingerprints_recipient: Recipient, affordable_accounts: Vec, @@ -249,6 +250,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { .lower_interface() .get_transaction_id(consuming_wallet.address()); let gas_price_wei = agent.agreed_fee_per_computation_unit(); + let chain = agent.get_chain(); Box::new( get_transaction_id @@ -930,11 +932,11 @@ mod tests { .wait() .unwrap(); - assert_eq!(result[0], TransactionReceiptResult::Error("RPC error: Error { code: ServerError(429), message: \"The requests per second (RPS) of your requests are higher than your plan allows.\", data: None }".to_string())); + assert_eq!(result[0], TransactionReceiptResult::LocalError("RPC error: Error { code: ServerError(429), message: \"The requests per second (RPS) of your requests are higher than your plan allows.\", data: None }".to_string())); assert_eq!(result[1], TransactionReceiptResult::NotPresent); assert_eq!( result[2], - TransactionReceiptResult::Error( + TransactionReceiptResult::LocalError( "invalid type: string \"trash\", expected struct Receipt".to_string() ) ); diff --git a/node/src/blockchain/blockchain_interface/lower_level_interface.rs b/node/src/blockchain/blockchain_interface/lower_level_interface.rs index 6e33d5c00..c8653f985 100644 --- a/node/src/blockchain/blockchain_interface/lower_level_interface.rs +++ b/node/src/blockchain/blockchain_interface/lower_level_interface.rs @@ -12,7 +12,6 @@ pub trait LowBlockchainInt { // TODO: GH-495 The data structures in this trait are not generic, will need associated_type_defaults to implement it. // see issue #29661 for more information - // TODO: Address can be a wrapper type fn get_transaction_fee_balance( &self, address: Address, diff --git a/node/src/blockchain/blockchain_interface/mod.rs b/node/src/blockchain/blockchain_interface/mod.rs index fda6157ab..c1db462a2 100644 --- a/node/src/blockchain/blockchain_interface/mod.rs +++ b/node/src/blockchain/blockchain_interface/mod.rs @@ -24,9 +24,6 @@ pub trait BlockchainInterface { fn get_chain(&self) -> Chain; - // Initially this lower_interface wasn't wrapped with a box, but under the card GH-744 this design was used to solve lifetime issues - // with the futures. - // The downside to this method is we cant store persistent values, instead its being initialised where ever it being used. fn lower_interface(&self) -> Box; fn retrieve_transactions( @@ -49,7 +46,6 @@ pub trait BlockchainInterface { fn submit_payables_in_batch( &self, logger: Logger, - chain: Chain, agent: Box, fingerprints_recipient: Recipient, affordable_accounts: Vec, diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index be94f8a2c..8c7c155d2 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -315,6 +315,7 @@ pub fn dynamically_create_blockchain_agent_web3( gas_limit_const_part: u128, blockchain_agent_future_result: BlockchainAgentFutureResult, wallet: Wallet, + chain: Chain ) -> Box { Box::new(BlockchainAgentWeb3::new( blockchain_agent_future_result.gas_price_wei.as_u128(), @@ -325,6 +326,7 @@ pub fn dynamically_create_blockchain_agent_web3( .transaction_fee_balance, masq_token_balance_in_minor_units: blockchain_agent_future_result.masq_token_balance, }, + chain )) } diff --git a/node/src/proxy_server/mod.rs b/node/src/proxy_server/mod.rs index 4d221a8f7..ae7ca19db 100644 --- a/node/src/proxy_server/mod.rs +++ b/node/src/proxy_server/mod.rs @@ -2586,11 +2586,6 @@ mod tests { let test_name = "proxy_server_sends_a_message_with_error_when_quad_zeros_are_detected"; let cryptde = main_cryptde(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: 0.0.0.0\r\n\r\n"; - let (proxy_server_mock, _, _) = make_recorder(); - let route_query_response = None; - let (neighborhood_mock, _, _) = make_recorder(); - let neighborhood_mock = - neighborhood_mock.route_query_response(route_query_response.clone()); let socket_addr = SocketAddr::from_str("1.2.3.4:5678").unwrap(); let stream_key = StreamKey::make_meaningless_stream_key(); let expected_data = http_request.to_vec(); @@ -2615,13 +2610,8 @@ mod tests { subject.stream_key_factory = Box::new(stream_key_factory); subject.logger = Logger::new(test_name); let subject_addr: Addr = subject.start(); - let mut peer_actors = peer_actors_builder() - .proxy_server(proxy_server_mock) - .neighborhood(neighborhood_mock) + let peer_actors = peer_actors_builder() .build(); - // Get the dns_retry_result recipient so we can partially mock it... - let dns_retry_result_recipient = peer_actors.proxy_server.route_result_sub; - peer_actors.proxy_server.route_result_sub = dns_retry_result_recipient; //Partial mocking subject_addr.try_send(BindMessage { peer_actors }).unwrap(); subject_addr.try_send(msg_from_dispatcher).unwrap(); From 0c82a79f2eb8d38d77930199f15910bc4262b7dd Mon Sep 17 00:00:00 2001 From: Syther007 Date: Wed, 18 Dec 2024 20:56:51 +1300 Subject: [PATCH 43/56] GH-744: Fixes from review 2 --- node/src/accountant/mod.rs | 4 +- .../payable_scanner/agent_web3.rs | 24 +++--- .../payable_scanner/blockchain_agent.rs | 2 +- .../payable_scanner/test_utils.rs | 7 +- node/src/accountant/scanners/mod.rs | 4 +- node/src/actor_system_factory.rs | 26 ++---- node/src/blockchain/blockchain_bridge.rs | 43 ++++++---- .../lower_level_interface_web3.rs | 53 +++++------- .../blockchain_interface_web3/mod.rs | 63 +++++++++------ .../blockchain/blockchain_interface_utils.rs | 80 +++++++++---------- node/src/proxy_server/mod.rs | 28 ++++--- 11 files changed, 169 insertions(+), 165 deletions(-) diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index c986a1323..3e121af88 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -3832,11 +3832,11 @@ mod tests { let msg = ReportTransactionReceipts { fingerprints_with_receipts: vec![ ( - TransactionReceiptResult::Found(transaction_receipt_1), + TransactionReceiptResult::Found(transaction_receipt_1.into()), fingerprint_1.clone(), ), ( - TransactionReceiptResult::Found(transaction_receipt_2), + TransactionReceiptResult::Found(transaction_receipt_2.into()), fingerprint_2.clone(), ), ], diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs index 1cb9fbc73..af49f3950 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs @@ -1,9 +1,9 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -use masq_lib::blockchains::chains::Chain; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; +use masq_lib::blockchains::chains::Chain; #[derive(Debug, Clone)] pub struct BlockchainAgentWeb3 { @@ -12,7 +12,7 @@ pub struct BlockchainAgentWeb3 { maximum_added_gas_margin: u128, consuming_wallet: Wallet, consuming_wallet_balances: ConsumingWalletBalances, - chain: Chain + chain: Chain, } impl BlockchainAgent for BlockchainAgentWeb3 { @@ -49,7 +49,7 @@ impl BlockchainAgentWeb3 { gas_limit_const_part: u128, consuming_wallet: Wallet, consuming_wallet_balances: ConsumingWalletBalances, - chain: Chain + chain: Chain, ) -> Self { Self { gas_price_wei, @@ -57,7 +57,7 @@ impl BlockchainAgentWeb3 { consuming_wallet, maximum_added_gas_margin: WEB3_MAXIMAL_GAS_LIMIT_MARGIN, consuming_wallet_balances, - chain + chain, } } } @@ -68,13 +68,10 @@ mod tests { BlockchainAgentWeb3, WEB3_MAXIMAL_GAS_LIMIT_MARGIN, }; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; - use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::test_utils::make_wallet; - - use web3::types::U256; - use masq_lib::constants::DEFAULT_CHAIN; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; + use web3::types::U256; #[test] fn constants_are_correct() { @@ -96,7 +93,7 @@ mod tests { gas_limit_const_part, consuming_wallet.clone(), consuming_wallet_balances, - TEST_DEFAULT_CHAIN + TEST_DEFAULT_CHAIN, ); assert_eq!(subject.agreed_fee_per_computation_unit(), gas_price_gwei); @@ -114,8 +111,13 @@ mod tests { transaction_fee_balance_in_minor_units: Default::default(), masq_token_balance_in_minor_units: Default::default(), }; - let agent = - BlockchainAgentWeb3::new(444, 77_777, consuming_wallet, consuming_wallet_balances, TEST_DEFAULT_CHAIN); + let agent = BlockchainAgentWeb3::new( + 444, + 77_777, + consuming_wallet, + consuming_wallet_balances, + TEST_DEFAULT_CHAIN, + ); let result = agent.estimated_transaction_fee_total(3); diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs index f883f627b..2f2af4015 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/blockchain_agent.rs @@ -1,9 +1,9 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -use masq_lib::blockchains::chains::Chain; use crate::arbitrary_id_stamp_in_trait; use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; +use masq_lib::blockchains::chains::Chain; // Table of chains by // diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs index 6536ccf6c..836bb1d10 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs @@ -7,22 +7,21 @@ use crate::sub_lib::blockchain_bridge::ConsumingWalletBalances; use crate::sub_lib::wallet::Wallet; use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp; use crate::{arbitrary_id_stamp_in_trait_impl, set_arbitrary_id_stamp_in_mock_impl}; -use std::cell::RefCell; use masq_lib::blockchains::chains::Chain; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; - +use std::cell::RefCell; pub struct BlockchainAgentMock { consuming_wallet_balances_results: RefCell>, agreed_fee_per_computation_unit_results: RefCell>, consuming_wallet_result_opt: Option, arbitrary_id_stamp_opt: Option, - get_chain_result_opt: Option + get_chain_result_opt: Option, } impl Default for BlockchainAgentMock { fn default() -> Self { - BlockchainAgentMock{ + BlockchainAgentMock { consuming_wallet_balances_results: RefCell::new(vec![]), agreed_fee_per_computation_unit_results: RefCell::new(vec![]), consuming_wallet_result_opt: None, diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index 9fd9ac46d..33fe13723 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -2847,11 +2847,11 @@ mod tests { let msg = ReportTransactionReceipts { fingerprints_with_receipts: vec![ ( - TransactionReceiptResult::Found(transaction_receipt_1), + TransactionReceiptResult::Found(transaction_receipt_1.into()), fingerprint_1.clone(), ), ( - TransactionReceiptResult::Found(transaction_receipt_2), + TransactionReceiptResult::Found(transaction_receipt_2.into()), fingerprint_2.clone(), ), ], diff --git a/node/src/actor_system_factory.rs b/node/src/actor_system_factory.rs index 536f840e7..0cb035f61 100644 --- a/node/src/actor_system_factory.rs +++ b/node/src/actor_system_factory.rs @@ -635,13 +635,8 @@ where mod tests { use super::*; use crate::accountant::exportable_test_parts::test_accountant_is_constructed_with_upgraded_db_connection_recognizing_our_extra_sqlite_functions; - use crate::accountant::{ - PaymentsAndStartBlock, ReceivedPayments, DEFAULT_PENDING_TOO_LONG_SEC, - }; - use crate::blockchain::blockchain_bridge::RetrieveTransactions; - use crate::blockchain::blockchain_interface::data_structures::BlockchainTransaction; + use crate::accountant::DEFAULT_PENDING_TOO_LONG_SEC; use crate::bootstrapper::{Bootstrapper, RealUser}; - use crate::db_config::persistent_configuration::PersistentConfigurationReal; use crate::node_test_utils::{ make_stream_handler_pool_subs_from_recorder, start_recorder_refcell_opt, }; @@ -657,7 +652,6 @@ mod tests { use crate::sub_lib::peer_actors::StartMessage; use crate::sub_lib::stream_handler_pool::TransmitDataMsg; use crate::sub_lib::ui_gateway::UiGatewayConfig; - use crate::sub_lib::wallet::Wallet; use crate::test_utils::actor_system_factory::BannedCacheLoaderMock; use crate::test_utils::automap_mocks::{AutomapControlFactoryMock, AutomapControlMock}; use crate::test_utils::make_wallet; @@ -667,11 +661,9 @@ mod tests { make_accountant_subs_from_recorder, make_blockchain_bridge_subs_from_recorder, make_configurator_subs_from_recorder, make_hopper_subs_from_recorder, make_neighborhood_subs_from_recorder, make_proxy_client_subs_from_recorder, - make_proxy_server_subs_from_recorder, make_ui_gateway_subs_from_recorder, - peer_actors_builder, Recording, + make_proxy_server_subs_from_recorder, make_ui_gateway_subs_from_recorder, Recording, }; use crate::test_utils::recorder::{make_recorder, Recorder}; - use crate::test_utils::recorder_stop_conditions::{StopCondition, StopConditions}; use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp; use crate::test_utils::unshared_test_utils::system_killer_actor::SystemKillerActor; use crate::test_utils::unshared_test_utils::{ @@ -679,30 +671,24 @@ mod tests { }; use crate::test_utils::{alias_cryptde, rate_pack}; use crate::test_utils::{main_cryptde, make_cryptde_pair}; - use crate::{ - hopper, match_every_type_id, proxy_client, proxy_server, stream_handler_pool, ui_gateway, - }; + use crate::{hopper, proxy_client, proxy_server, stream_handler_pool, ui_gateway}; use actix::{Actor, Arbiter, System}; use automap_lib::control_layer::automap_control::AutomapChange; #[cfg(all(test, not(feature = "no_test_share")))] use automap_lib::mocks::{ parameterizable_automap_control, TransactorMock, PUBLIC_IP, ROUTER_IP, }; - use core::any::TypeId; - use crossbeam_channel::{bounded, unbounded}; + use crossbeam_channel::unbounded; use log::LevelFilter; use masq_lib::constants::DEFAULT_CHAIN; use masq_lib::crash_point::CrashPoint; #[cfg(feature = "log_recipient_test")] use masq_lib::logger::INITIALIZATION_COUNTER; use masq_lib::messages::{ToMessageBody, UiCrashRequest, UiDescriptorRequest}; - use masq_lib::test_utils::mock_blockchain_client_server::MBCSBuilder; - use masq_lib::test_utils::utils::{ - ensure_node_home_directory_exists, LogObject, TEST_DEFAULT_CHAIN, - }; + use masq_lib::test_utils::utils::{ensure_node_home_directory_exists, TEST_DEFAULT_CHAIN}; use masq_lib::ui_gateway::NodeFromUiMessage; + use masq_lib::utils::running_test; use masq_lib::utils::AutomapProtocol::Igdp; - use masq_lib::utils::{find_free_port, running_test}; use std::cell::RefCell; use std::collections::HashMap; use std::convert::TryFrom; diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index b66e7128c..938d6fbfb 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -566,7 +566,7 @@ impl BlockchainBridge { start_block_number } else { start_block_number + 1u64 // TODO: GH-744 Way are we adding +1 can we just return the same value? - //start_block_number + //start_block_number } } else { start_block_number + max_block_count @@ -640,11 +640,13 @@ mod tests { use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::accountant::db_access_objects::pending_payable_dao::PendingPayable; use crate::accountant::db_access_objects::utils::from_time_t; + use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::agent_web3::WEB3_MAXIMAL_GAS_LIMIT_MARGIN; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::test_utils::BlockchainAgentMock; use crate::accountant::scanners::test_utils::{ make_empty_payments_and_start_block, protect_payables_in_test, }; use crate::accountant::test_utils::{make_payable_account, make_pending_payable_fingerprint}; + use crate::blockchain::blockchain_interface::blockchain_interface_web3::BlockchainInterfaceWeb3; use crate::blockchain::blockchain_interface::data_structures::errors::PayableTransactionError::TransactionID; use crate::blockchain::blockchain_interface::data_structures::errors::{ BlockchainAgentBuildError, PayableTransactionError, @@ -775,7 +777,7 @@ mod tests { ); let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x230000000".to_string(), 1) + .response("0x230000000".to_string(), 1) // 9395240960 .response("0x23".to_string(), 1) .response( "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), @@ -848,19 +850,24 @@ mod tests { blockchain_agent_with_context_msg_actual .agent .agreed_fee_per_computation_unit(), - 9395240960 + 0x230000000 ); assert_eq!( blockchain_agent_with_context_msg_actual .agent .consuming_wallet_balances(), - ConsumingWalletBalances::new(35.into(), 65535.into()) + ConsumingWalletBalances::new( + 35.into(), + 0x000000000000000000000000000000000000000000000000000000000000FFFF.into() + ) ); + let gas_limit_const_part = + BlockchainInterfaceWeb3::web3_gas_limit_const_part(Chain::PolyMainnet); assert_eq!( blockchain_agent_with_context_msg_actual .agent .estimated_transaction_fee_total(1), - 688_934_229_114_880 + (1 * 0x230000000 * (gas_limit_const_part + WEB3_MAXIMAL_GAS_LIMIT_MARGIN)) ); assert_eq!( blockchain_agent_with_context_msg_actual.response_skeleton_opt, @@ -1057,7 +1064,7 @@ mod tests { let agent = BlockchainAgentMock::default() .consuming_wallet_result(consuming_wallet) .agreed_fee_per_computation_unit_result(123) - .get_chain_result(Chain::PolyMainnet);; + .get_chain_result(Chain::PolyMainnet); send_bind_message!(subject_subs, peer_actors); let _ = addr @@ -1293,7 +1300,7 @@ mod tests { &ReportTransactionReceipts { fingerprints_with_receipts: vec![ ( - TransactionReceiptResult::Found(expected_receipt), + TransactionReceiptResult::Found(expected_receipt.into()), pending_payable_fingerprint_1 ), ( @@ -1462,7 +1469,7 @@ mod tests { ReportTransactionReceipts { fingerprints_with_receipts: vec![ (TransactionReceiptResult::NotPresent, fingerprint_1), - (TransactionReceiptResult::Found(transaction_receipt), fingerprint_2), + (TransactionReceiptResult::Found(transaction_receipt.into()), fingerprint_2), (TransactionReceiptResult::NotPresent, fingerprint_3), (TransactionReceiptResult::LocalError("RPC error: Error { code: ServerError(429), message: \"The requests per second (RPS) of your requests are higher than your plan allows.\", data: None }".to_string()), fingerprint_4) ], @@ -1614,17 +1621,17 @@ mod tests { system.run(); let after = SystemTime::now(); let expected_transactions = RetrievedBlockchainTransactions { - new_start_block: 6040060u64, + new_start_block: 6040060u64 + 1, transactions: vec![ BlockchainTransaction { block_number: 6040059, - from: make_wallet("first_wallet"), // Points to topics of 1 - wei_amount: 42, // Its points to the field data + from: make_wallet("first_wallet"), // Relates to RPC response topics of 1 + wei_amount: 42, // Relates to RPC response field data }, BlockchainTransaction { block_number: 6040060, - from: make_wallet("second_wallet"), // Points to topics of 1 - wei_amount: 55, // Its points to the field data + from: make_wallet("second_wallet"), // Relates to RPC response topics of 1 + wei_amount: 55, // Relates to RPC response field data }, ], }; @@ -1738,7 +1745,7 @@ mod tests { }), payments_and_start_block: PaymentsAndStartBlock { payments: expected_transactions.transactions, - new_start_block: 8675309u64 + new_start_block: 8675309u64 + 1 }, } ); @@ -1785,7 +1792,7 @@ mod tests { let earning_wallet = make_wallet("earning_wallet"); let amount = 996000000; let expected_transactions = RetrievedBlockchainTransactions { - new_start_block: 1000000000, + new_start_block: (0x3B9ACA00 + 1), transactions: vec![BlockchainTransaction { block_number: 2000, from: earning_wallet.clone(), @@ -1929,12 +1936,14 @@ mod tests { let accountant = accountant.system_stop_conditions(match_every_type_id!(ScanError)); let earning_wallet = make_wallet("earning_wallet"); let blockchain_interface = make_blockchain_interface_web3(port); + let set_max_block_count_params_arc = Arc::new(Mutex::new(vec![])); let persistent_config = PersistentConfigurationMock::new() .start_block_result(Ok(Some(6))) .max_block_count_result(Err(PersistentConfigError::DatabaseError( "my tummy hurts".to_string(), ))) - .set_max_block_count_result(Ok(())); + .set_max_block_count_result(Ok(())) + .set_max_block_count_params(&set_max_block_count_params_arc); let mut subject = BlockchainBridge::new( Box::new(blockchain_interface), Arc::new(Mutex::new(persistent_config)), @@ -1970,6 +1979,8 @@ mod tests { msg: "Error while retrieving transactions: QueryFailed(\"RPC error: Error { code: ServerError(-32005), message: \\\"Blockheight too far in the past. Check params passed to eth_getLogs or eth_call requests.Range of blocks allowed for your plan: 1000\\\", data: None }\")".to_string(), } ); + let max_block_count_params = set_max_block_count_params_arc.lock().unwrap(); + assert_eq!(*max_block_count_params, vec![Some(1000)]); TestLogHandler::new().exists_log_containing(&format!( "DEBUG: {test_name}: Updated max_block_count to 1000 in database" )); diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index b06950330..bff5f68eb 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -13,12 +13,30 @@ use web3::types::{Address, BlockNumber, Filter, Log, TransactionReceipt}; use web3::{Error, Web3}; #[derive(Debug, PartialEq, Clone)] -#[allow(clippy::large_enum_variant)] pub enum TransactionReceiptResult { NotPresent, - Found(TransactionReceipt), - TransactionFailed(TransactionReceipt), // RemoteFail ure - LocalError(String), // LocalFailure + Found(TxReceipt), + TransactionFailed(TxReceipt), + LocalError(String), +} + +#[derive(Debug, PartialEq, Clone)] +pub struct TxReceipt { + pub transaction_hash: H256, + pub block_hash: Option, + pub block_number: Option, + pub status: Option, +} + +impl From for TxReceipt { + fn from(receipt: TransactionReceipt) -> Self { + TxReceipt { + transaction_hash: receipt.transaction_hash, + block_hash: receipt.block_hash, + block_number: receipt.block_number, + status: receipt.status.map(|s| s == U64::from(1)), + } + } } pub struct LowBlockchainIntWeb3 { @@ -356,33 +374,6 @@ mod tests { ) } - - - #[test] - fn transaction_receipt_batch_fails_on_submit_batch() { - let port = find_free_port(); - let _blockchain_client_server = MBCSBuilder::new(port).start(); - let subject = make_blockchain_interface_web3(port); - let tx_hash_1 = - H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0e") - .unwrap(); - let tx_hash_2 = - H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0f") - .unwrap(); - let tx_hash_vec = vec![tx_hash_1, tx_hash_2]; - - let result = subject - .lower_interface() - .get_transaction_receipt_in_batch(tx_hash_vec) - .wait() - .unwrap_err(); - - assert_eq!( - result, - BlockchainError::QueryFailed("Transport error: Error(IncompleteMessage)".to_string()) - ); - } - #[test] fn get_transaction_logs_works() { let port = find_free_port(); diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 135a71219..e8c7de1bf 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -188,7 +188,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { gas_limit_const_part, blockchain_agent_future_result, consuming_wallet, - chain + chain, )) }) }) @@ -214,9 +214,11 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { None => TransactionReceiptResult::NotPresent, Some(status) => { if status == U64::from(1) { - TransactionReceiptResult::Found(receipt) + TransactionReceiptResult::Found(receipt.into()) } else { - TransactionReceiptResult::TransactionFailed(receipt) + TransactionReceiptResult::TransactionFailed( + receipt.into(), + ) } } }, @@ -412,7 +414,8 @@ mod tests { use std::net::Ipv4Addr; use std::str::FromStr; use web3::transports::Http; - use web3::types::{BlockNumber, H2048, H256, U256}; + use web3::types::{BlockNumber, H256, U256}; + use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TxReceipt; #[test] fn constants_are_correct() { @@ -523,7 +526,7 @@ mod tests { assert_eq!( result, RetrievedBlockchainTransactions { - new_start_block: 0x4be663, + new_start_block: 0x4be663 + 1, transactions: vec![ BlockchainTransaction { block_number: 0x4be663, @@ -583,7 +586,7 @@ mod tests { assert_eq!( result, Ok(RetrievedBlockchainTransactions { - new_start_block: 1543663, + new_start_block: 1543664, transactions: vec![] }) ); @@ -679,7 +682,7 @@ mod tests { ) .unwrap(); - let end_block_nbr = 1024u64; + let end_block_nbr = 1025u64; let subject = BlockchainInterfaceWeb3::new(transport, event_loop_handle, TEST_DEFAULT_CHAIN); @@ -942,38 +945,48 @@ mod tests { assert_eq!(result[3], TransactionReceiptResult::NotPresent); assert_eq!( result[4], - TransactionReceiptResult::TransactionFailed(TransactionReceipt { + TransactionReceiptResult::TransactionFailed(TxReceipt { transaction_hash: tx_hash_5, - transaction_index: Default::default(), block_hash: None, block_number: None, - cumulative_gas_used: U256::from(0), - gas_used: None, - contract_address: None, - logs: vec![], - status: Some(status_failed), - root: None, - logs_bloom: H2048::default() + status: Some(false), }) ); assert_eq!( result[5], - TransactionReceiptResult::Found(TransactionReceipt { + TransactionReceiptResult::Found(TxReceipt { transaction_hash: tx_hash_6, - transaction_index: Default::default(), block_hash: Some(block_hash), block_number: Some(block_number), - cumulative_gas_used, - gas_used: Some(gas_used), - contract_address: None, - logs: vec![], - status: Some(status), - root: None, - logs_bloom: H2048::default() + status: Some(true), }) ); } + #[test] + fn process_transaction_receipts_fails_on_submit_batch() { + let port = find_free_port(); + let _blockchain_client_server = MBCSBuilder::new(port).start(); + let subject = make_blockchain_interface_web3(port); + let tx_hash_1 = + H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0e") + .unwrap(); + let tx_hash_2 = + H256::from_str("a128f9ca1e705cc20a936a24a7fa1df73bad6e0aaf58e8e6ffcc154a7cff6e0f") + .unwrap(); + let tx_hash_vec = vec![tx_hash_1, tx_hash_2]; + + let result = subject + .process_transaction_receipts(tx_hash_vec) + .wait() + .unwrap_err(); + + assert_eq!( + result, + BlockchainError::QueryFailed("Transport error: Error(IncompleteMessage)".to_string()) + ); + } + #[test] fn web3_gas_limit_const_part_returns_reasonable_values() { type Subject = BlockchainInterfaceWeb3; diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index 8c7c155d2..65597a246 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -315,7 +315,7 @@ pub fn dynamically_create_blockchain_agent_web3( gas_limit_const_part: u128, blockchain_agent_future_result: BlockchainAgentFutureResult, wallet: Wallet, - chain: Chain + chain: Chain, ) -> Box { Box::new(BlockchainAgentWeb3::new( blockchain_agent_future_result.gas_price_wei.as_u128(), @@ -326,7 +326,7 @@ pub fn dynamically_create_blockchain_agent_web3( .transaction_fee_balance, masq_token_balance_in_minor_units: blockchain_agent_future_result.masq_token_balance, }, - chain + chain, )) } @@ -639,6 +639,13 @@ mod tests { #[test] fn send_payables_within_batch_works() { let accounts = vec![make_payable_account(1), make_payable_account(2)]; + let port = find_free_port(); + let _blockchain_client_server = MBCSBuilder::new(port) + .begin_batch() + .response("rpc_result".to_string(), 7) + .response("rpc_result_2".to_string(), 8) + .end_batch() + .start(); let expected_result = Ok(vec![ Correct(PendingPayable { recipient_wallet: accounts[0].wallet.clone(), @@ -656,13 +663,6 @@ mod tests { }), ]); - let port = find_free_port(); - let _blockchain_client_server = MBCSBuilder::new(port) - .begin_batch() - .response("rpc_result".to_string(), 7) - .response("rpc_result_2".to_string(), 8) - .end_batch() - .start(); execute_send_payables_test( "send_payables_within_batch_works", accounts, @@ -676,6 +676,7 @@ mod tests { let accounts = vec![make_payable_account(1), make_payable_account(2)]; let os_code = transport_error_code(); let os_msg = transport_error_message(); + let port = find_free_port(); let expected_result = Err(Sending { msg: format!("Transport error: Error(Connect, Os {{ code: {}, kind: ConnectionRefused, message: {:?} }})", os_code, os_msg).to_string(), hashes: vec![ @@ -684,7 +685,6 @@ mod tests { ], }); - let port = find_free_port(); execute_send_payables_test( "send_payables_within_batch_fails_on_submit_batch_call", accounts, @@ -696,6 +696,23 @@ mod tests { #[test] fn send_payables_within_batch_all_payments_fail() { let accounts = vec![make_payable_account(1), make_payable_account(2)]; + let port = find_free_port(); + let _blockchain_client_server = MBCSBuilder::new(port) + .begin_batch() + .err_response( + 429, + "The requests per second (RPS) of your requests are higher than your plan allows." + .to_string(), + 7, + ) + .err_response( + 429, + "The requests per second (RPS) of your requests are higher than your plan allows." + .to_string(), + 8, + ) + .end_batch() + .start(); let expected_result = Ok(vec![ Failed(RpcPayableFailure { rpc_error: Rpc(Error { @@ -717,23 +734,6 @@ mod tests { }), ]); - let port = find_free_port(); - let _blockchain_client_server = MBCSBuilder::new(port) - .begin_batch() - .err_response( - 429, - "The requests per second (RPS) of your requests are higher than your plan allows." - .to_string(), - 7, - ) - .err_response( - 429, - "The requests per second (RPS) of your requests are higher than your plan allows." - .to_string(), - 8, - ) - .end_batch() - .start(); execute_send_payables_test( "send_payables_within_batch_all_payments_fail", accounts, @@ -745,6 +745,18 @@ mod tests { #[test] fn send_payables_within_batch_one_payment_works_the_other_fails() { let accounts = vec![make_payable_account(1), make_payable_account(2)]; + let port = find_free_port(); + let _blockchain_client_server = MBCSBuilder::new(port) + .begin_batch() + .response("rpc_result".to_string(), 7) + .err_response( + 429, + "The requests per second (RPS) of your requests are higher than your plan allows." + .to_string(), + 7, + ) + .end_batch() + .start(); let expected_result = Ok(vec![ Correct(PendingPayable { recipient_wallet: accounts[0].wallet.clone(), @@ -761,18 +773,6 @@ mod tests { }), ]); - let port = find_free_port(); - let _blockchain_client_server = MBCSBuilder::new(port) - .begin_batch() - .response("rpc_result".to_string(), 7) - .err_response( - 429, - "The requests per second (RPS) of your requests are higher than your plan allows." - .to_string(), - 7, - ) - .end_batch() - .start(); execute_send_payables_test( "send_payables_within_batch_one_payment_works_the_other_fails", accounts, @@ -828,7 +828,7 @@ mod tests { let web3 = Web3::new(transport.clone()); let chain = DEFAULT_CHAIN; let amount = 11_222_333_444; - let gas_price_in_wei = 123_000_000_000_000_000_000; + let gas_price_in_wei = 123 * 10_u128.pow(18); let nonce = U256::from(5); let recipient_wallet = make_wallet("recipient_wallet"); let consuming_wallet = make_paying_wallet(b"consuming_wallet"); diff --git a/node/src/proxy_server/mod.rs b/node/src/proxy_server/mod.rs index ae7ca19db..55c1c6efd 100644 --- a/node/src/proxy_server/mod.rs +++ b/node/src/proxy_server/mod.rs @@ -1069,7 +1069,7 @@ impl IBCDHelper for IBCDHelperReal { let payload = match proxy.make_payload(msg, &stream_key) { Ok(payload) => { if let Some(hostname) = &payload.target_hostname { - if let Err(e) = Hostname::new(hostname).is_valid() { + if let Err(e) = Hostname::new(hostname).validate_hostname() { return Err(format!("Request to wildcard IP detected - {} (Most likely because Blockchain Service URL is not set)", e)); } } @@ -1236,7 +1236,7 @@ impl Hostname { Self { hostname } } - fn is_valid(&self) -> Result<(), String> { + fn validate_hostname(&self) -> Result<(), String> { match IpAddr::from_str(&self.hostname) { Ok(ip_addr) => match ip_addr { IpAddr::V4(ipv4addr) => Self::validate_ipv4(ipv4addr), @@ -2610,8 +2610,7 @@ mod tests { subject.stream_key_factory = Box::new(stream_key_factory); subject.logger = Logger::new(test_name); let subject_addr: Addr = subject.start(); - let peer_actors = peer_actors_builder() - .build(); + let peer_actors = peer_actors_builder().build(); subject_addr.try_send(BindMessage { peer_actors }).unwrap(); subject_addr.try_send(msg_from_dispatcher).unwrap(); @@ -6010,34 +6009,37 @@ mod tests { fn hostname_is_valid_works() { // IPv4 assert_eq!( - Hostname::new("0.0.0.0").is_valid(), + Hostname::new("0.0.0.0").validate_hostname(), Err("0.0.0.0".to_string()) ); assert_eq!( - Hostname::new("127.0.0.1").is_valid(), + Hostname::new("127.0.0.1").validate_hostname(), Err("127.0.0.1".to_string()) ); - assert_eq!(Hostname::new("192.168.1.158").is_valid(), Ok(())); + assert_eq!(Hostname::new("192.168.1.158").validate_hostname(), Ok(())); // IPv6 assert_eq!( - Hostname::new("0:0:0:0:0:0:0:0").is_valid(), + Hostname::new("0:0:0:0:0:0:0:0").validate_hostname(), Err("::".to_string()) ); assert_eq!( - Hostname::new("0:0:0:0:0:0:0:1").is_valid(), + Hostname::new("0:0:0:0:0:0:0:1").validate_hostname(), Err("::1".to_string()) ); assert_eq!( - Hostname::new("2001:0db8:85a3:0000:0000:8a2e:0370:7334").is_valid(), + Hostname::new("2001:0db8:85a3:0000:0000:8a2e:0370:7334").validate_hostname(), Ok(()) ); // Hostname assert_eq!( - Hostname::new("localhost").is_valid(), + Hostname::new("localhost").validate_hostname(), Err("localhost".to_string()) ); - assert_eq!(Hostname::new("example.com").is_valid(), Ok(())); - assert_eq!(Hostname::new("https://example.com").is_valid(), Ok(())); + assert_eq!(Hostname::new("example.com").validate_hostname(), Ok(())); + assert_eq!( + Hostname::new("https://example.com").validate_hostname(), + Ok(()) + ); } #[test] From 69617512e53733b37082813a5d74c5aadace874d Mon Sep 17 00:00:00 2001 From: Syther007 Date: Wed, 18 Dec 2024 21:18:48 +1300 Subject: [PATCH 44/56] GH-744: Fixed test debtors_are_credited_once_but_not_twice --- .../tests/blockchain_interaction_test.rs | 2 +- node/src/accountant/mod.rs | 2 +- node/src/blockchain/blockchain_bridge.rs | 3 +-- .../blockchain_interface_web3/lower_level_interface_web3.rs | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/multinode_integration_tests/tests/blockchain_interaction_test.rs b/multinode_integration_tests/tests/blockchain_interaction_test.rs index 02a063d87..42381891c 100644 --- a/multinode_integration_tests/tests/blockchain_interaction_test.rs +++ b/multinode_integration_tests/tests/blockchain_interaction_test.rs @@ -144,7 +144,7 @@ fn debtors_are_credited_once_but_not_twice() { let config_dao = config_dao(&node_name); assert_eq!( config_dao.get("start_block").unwrap().value_opt.unwrap(), - "2000" + "2001" ); } } diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index 3e121af88..f4e2c036f 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -374,7 +374,7 @@ impl SkeletonOptHolder for RequestTransactionReceipts { } } -#[derive(Debug, PartialEq, Message, Clone)] +#[derive(Debug, PartialEq, Eq, Message, Clone)] pub struct ReportTransactionReceipts { pub fingerprints_with_receipts: Vec<(TransactionReceiptResult, PendingPayableFingerprint)>, pub response_skeleton_opt: Option, diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 938d6fbfb..8c4b6289b 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -565,8 +565,7 @@ impl BlockchainBridge { if start_block_number == u64::MAX { start_block_number } else { - start_block_number + 1u64 // TODO: GH-744 Way are we adding +1 can we just return the same value? - //start_block_number + start_block_number + 1u64 } } else { start_block_number + max_block_count diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index bff5f68eb..fada38b51 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -12,7 +12,7 @@ use web3::transports::{Batch, Http}; use web3::types::{Address, BlockNumber, Filter, Log, TransactionReceipt}; use web3::{Error, Web3}; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum TransactionReceiptResult { NotPresent, Found(TxReceipt), @@ -20,7 +20,7 @@ pub enum TransactionReceiptResult { LocalError(String), } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone)] pub struct TxReceipt { pub transaction_hash: H256, pub block_hash: Option, From ace75e7f70ecbb211fda527b66e80b6cb7224261 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Wed, 18 Dec 2024 21:58:33 +1300 Subject: [PATCH 45/56] GH-744: removed BlockNumber::Number --- node/src/blockchain/blockchain_bridge.rs | 108 +----------------- .../blockchain_interface_web3/mod.rs | 21 ++-- .../blockchain/blockchain_interface/mod.rs | 4 +- 3 files changed, 15 insertions(+), 118 deletions(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 8c4b6289b..60d2e65dc 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -44,7 +44,7 @@ use std::string::ToString; use std::sync::{Arc, Mutex}; use std::time::SystemTime; use ethabi::Hash; -use web3::types::{BlockNumber, H256}; +use web3::types::H256; use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; @@ -303,116 +303,15 @@ impl BlockchainBridge { ) } - // TODO GH-744 - From Master - // fn handle_retrieve_transactions(&mut self, msg: RetrieveTransactions) -> Result<(), String> { - // let start_block_nbr = match self.persistent_config.start_block() { - // Ok(Some(sb)) => sb, - // Ok(None) => u64::MAX, - // Err(e) => panic!("Cannot retrieve start block from database; payments to you may not be processed: {:?}", e) - // }; - // let max_block_count = match self.persistent_config.max_block_count() { - // Ok(Some(mbc)) => mbc, - // _ => u64::MAX, - // }; - // let use_unlimited_block_count_range = u64::MAX == max_block_count; - // let use_latest_block = u64::MAX == start_block_nbr; - // let end_block = match self - // .blockchain_interface - // .lower_interface() - // .get_block_number() - // { - // Ok(eb) => { - // if use_unlimited_block_count_range || use_latest_block { - // BlockNumber::Number(eb) - // } else { - // BlockNumber::Number(eb.as_u64().min(start_block_nbr + max_block_count).into()) - // } - // } - // Err(e) => { - // if use_unlimited_block_count_range || use_latest_block { - // debug!( - // self.logger, - // "Using 'latest' block number instead of a literal number. {:?}", e - // ); - // BlockNumber::Latest - // } else { - // debug!( - // self.logger, - // "Using '{}' ending block number. {:?}", - // start_block_nbr + max_block_count, - // e - // ); - // BlockNumber::Number((start_block_nbr + max_block_count).into()) - // } - // } - // }; - // let start_block = if use_latest_block { - // end_block - // } else { - // BlockNumber::Number(start_block_nbr.into()) - // }; - // let retrieved_transactions = - // self.blockchain_interface - // .retrieve_transactions(start_block, end_block, &msg.recipient); - // match retrieved_transactions { - // Ok(transactions) => { - // if let BlockNumber::Number(new_start_block_number) = transactions.new_start_block { - // if transactions.transactions.is_empty() { - // debug!(self.logger, "No new receivable detected"); - // } - // self.received_payments_subs_opt - // .as_ref() - // .expect("Accountant is unbound") - // .try_send(ReceivedPayments { - // timestamp: SystemTime::now(), - // payments: transactions.transactions, - // new_start_block: new_start_block_number.as_u64(), - // response_skeleton_opt: msg.response_skeleton_opt, - // }) - // .expect("Accountant is dead."); - // } - // Ok(()) - // } - // Err(e) => { - // if let Some(max_block_count) = self.extract_max_block_count(e.clone()) { - // debug!(self.logger, "Writing max_block_count({})", &max_block_count); - // self.persistent_config - // .set_max_block_count(Some(max_block_count)) - // .map_or_else( - // |_| { - // warning!(self.logger, "{} update max_block_count to {}. Scheduling next scan with that limit.", e, &max_block_count); - // Err(format!("{} updated max_block_count to {}. Scheduling next scan with that limit.", e, &max_block_count)) - // }, - // |e| { - // warning!(self.logger, "Writing max_block_count failed: {:?}", e); - // Err(format!("Writing max_block_count failed: {:?}", e)) - // }, - // ) - // } else { - // warning!( - // self.logger, - // "Attempted to retrieve received payments but failed: {:?}", - // e - // ); - // Err(format!( - // "Attempted to retrieve received payments but failed: {:?}", - // e - // )) - // } - // } - // } - // } - fn handle_retrieve_transactions( &mut self, msg: RetrieveTransactions, ) -> Box> { - let (start_block_nbr, max_block_count) = { + let (start_block, max_block_count) = { let persistent_config_lock = self .persistent_config_arc .lock() .expect("Unable to lock persistent config in BlockchainBridge"); - // TODO: GH-744: Look into making start_block_nbr 0 instead of u64::MAX let start_block_nbr = match persistent_config_lock.start_block() { Ok(Some(sb)) => sb, Ok(None) => u64::MAX, @@ -426,8 +325,7 @@ impl BlockchainBridge { }; let logger = self.logger.clone(); let fallback_next_start_block_number = - Self::calculate_fallback_start_block_number(start_block_nbr, max_block_count); - let start_block = BlockNumber::Number(start_block_nbr.into()); // TODO: GH-744 Look at making this a u64 or an Option of u64 + Self::calculate_fallback_start_block_number(start_block, max_block_count); let received_payments_subs = self .received_payments_subs_opt .as_ref() diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index e8c7de1bf..b4664553b 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -90,7 +90,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { fn retrieve_transactions( &self, - start_block: BlockNumber, + start_block: u64, fallback_start_block_number: u64, recipient: Address, ) -> Box> { @@ -121,7 +121,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { ); let filter = FilterBuilder::default() .address(vec![contract_address]) - .from_block(start_block) + .from_block(BlockNumber::Number(U64::from(start_block))) .to_block(BlockNumber::Number(U64::from(response_block_number))) .topics( Some(vec![TRANSACTION_LITERAL]), @@ -414,7 +414,7 @@ mod tests { use std::net::Ipv4Addr; use std::str::FromStr; use web3::transports::Http; - use web3::types::{BlockNumber, H256, U256}; + use web3::types::{H256, U256}; use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TxReceipt; #[test] @@ -516,7 +516,7 @@ mod tests { let result = subject .retrieve_transactions( - BlockNumber::Number(42u64.into()), + 42u64, end_block_nbr, Wallet::from_str(&to).unwrap().address(), ) @@ -577,7 +577,7 @@ mod tests { let result = subject .retrieve_transactions( - BlockNumber::Number(42u64.into()), + 42u64, end_block_nbr, to_wallet.address(), ) @@ -630,7 +630,7 @@ mod tests { let result = subject .retrieve_transactions( - BlockNumber::Number(42u64.into()), + 42u64, 555u64, Wallet::from_str("0x3f69f9efd4f2592fd70be8c32ecd9dce71c472fc") .unwrap() @@ -656,7 +656,7 @@ mod tests { let result = subject .retrieve_transactions( - BlockNumber::Number(42u64.into()), + 42u64, 555u64, Wallet::from_str("0x3f69f9efd4f2592fd70be8c32ecd9dce71c472fc") .unwrap() @@ -688,7 +688,7 @@ mod tests { let result = subject .retrieve_transactions( - BlockNumber::Number(42u64.into()), + 42u64, end_block_nbr, Wallet::from_str("0x3f69f9efd4f2592fd70be8c32ecd9dce71c472fc") .unwrap() @@ -718,9 +718,8 @@ mod tests { .raw_response(r#"{"jsonrpc":"2.0","id":2,"result":[{"address":"0xcd6c588e005032dd882cd43bf53a32129be81302","blockHash":"0x1a24b9169cbaec3f6effa1f600b70c7ab9e8e86db44062b49132a4415d26732a","data":"0x0000000000000000000000000000000000000000000000000010000000000000","logIndex":"0x0","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000003f69f9efd4f2592fd70be8c32ecd9dce71c472fc","0x000000000000000000000000adc1853c7859369639eb414b6342b36288fe6092"],"transactionHash":"0x955cec6ac4f832911ab894ce16aa22c3003f46deff3f7165b32700d2f5ff0681","transactionIndex":"0x0"}]}"#.to_string()) .start(); let subject = make_blockchain_interface_web3(port); - let start_block_nbr = 42u64; - let start_block = BlockNumber::Number(start_block_nbr.into()); - let fallback_number = start_block_nbr; + let start_block = 42u64; + let fallback_number = start_block; let result = subject .retrieve_transactions( diff --git a/node/src/blockchain/blockchain_interface/mod.rs b/node/src/blockchain/blockchain_interface/mod.rs index c1db462a2..569620533 100644 --- a/node/src/blockchain/blockchain_interface/mod.rs +++ b/node/src/blockchain/blockchain_interface/mod.rs @@ -13,7 +13,7 @@ use crate::blockchain::blockchain_interface::lower_level_interface::LowBlockchai use crate::sub_lib::wallet::Wallet; use futures::Future; use masq_lib::blockchains::chains::Chain; -use web3::types::{Address, BlockNumber}; +use web3::types::Address; use masq_lib::logger::Logger; use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; @@ -28,7 +28,7 @@ pub trait BlockchainInterface { fn retrieve_transactions( &self, - start_block: BlockNumber, + start_block: u64, fallback_start_block_number: u64, recipient: Address, ) -> Box>; From e132f66cb86cb6adcf5accd0046f14d20b900cc3 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Wed, 18 Dec 2024 22:28:39 +1300 Subject: [PATCH 46/56] GH-744: Resolved TODOs --- .../tests/communication_failure_test.rs | 80 ++++++++++--------- node/src/accountant/mod.rs | 23 ++---- node/src/accountant/scanners/mod.rs | 52 +++++------- node/src/accountant/scanners/test_utils.rs | 8 -- node/src/blockchain/blockchain_bridge.rs | 36 +++------ .../data_structures/mod.rs | 1 - 6 files changed, 81 insertions(+), 119 deletions(-) diff --git a/multinode_integration_tests/tests/communication_failure_test.rs b/multinode_integration_tests/tests/communication_failure_test.rs index b35a5d5df..c5c70bbaf 100644 --- a/multinode_integration_tests/tests/communication_failure_test.rs +++ b/multinode_integration_tests/tests/communication_failure_test.rs @@ -28,6 +28,7 @@ use node_lib::sub_lib::versioned_data::VersionedData; use node_lib::test_utils::assert_string_contains; use node_lib::test_utils::neighborhood_test_utils::{db_from_node, make_node_record}; use std::convert::TryInto; +use std::net::Ipv4Addr; use std::thread; use std::time::Duration; @@ -271,45 +272,46 @@ fn dns_resolution_failure_with_real_nodes() { ); } -// >>> TODO: GH-744: - Re-Enable this test. -// #[test] -// fn dns_resolution_failure_for_wildcard_ip_with_real_nodes() { -// let dns_server_that_fails = Ipv4Addr::new(1, 1, 1, 3).into(); -// let mut cluster = MASQNodeCluster::start().unwrap(); -// let exit_node = cluster.start_real_node( -// NodeStartupConfigBuilder::standard() -// .chain(cluster.chain) -// .consuming_wallet_info(make_consuming_wallet_info("exit_node")) -// .dns_servers(vec![dns_server_that_fails]) -// .build(), -// ); -// let originating_node = cluster.start_real_node( -// NodeStartupConfigBuilder::standard() -// .neighbor(exit_node.node_reference()) -// .consuming_wallet_info(make_consuming_wallet_info("originating_node")) -// .chain(cluster.chain) -// .min_hops(Hops::OneHop) -// .build(), -// ); -// -// thread::sleep(Duration::from_millis(1000)); -// let mut client = originating_node.make_client(8080, STANDARD_CLIENT_TIMEOUT_MILLIS); -// client.send_chunk(b"GET / HTTP/1.1\r\nHost: www.xvideos.com\r\n\r\n"); -// let response = client.wait_for_chunk(); -// -// assert_eq!( -// index_of(&response, &b"

Title: DNS Resolution Problem

"[..]).is_some(), -// true, -// "Actual response:\n{}", -// String::from_utf8(response.clone()).unwrap() -// ); -// assert_eq!( -// index_of(&response, &b"

DNS Failure, We have tried multiple Exit Nodes and all have failed to resolve this address www.xvideos.com

"[..]).is_some(), -// true, -// "Actual response:\n{}", -// String::from_utf8(response).unwrap() -// ); -// } +// >>> TODO: GH-744: - Fix this test. +#[test] +#[ignore] +fn dns_resolution_failure_for_wildcard_ip_with_real_nodes() { + let dns_server_that_fails = Ipv4Addr::new(1, 1, 1, 3).into(); + let mut cluster = MASQNodeCluster::start().unwrap(); + let exit_node = cluster.start_real_node( + NodeStartupConfigBuilder::standard() + .chain(cluster.chain) + .consuming_wallet_info(make_consuming_wallet_info("exit_node")) + .dns_servers(vec![dns_server_that_fails]) + .build(), + ); + let originating_node = cluster.start_real_node( + NodeStartupConfigBuilder::standard() + .neighbor(exit_node.node_reference()) + .consuming_wallet_info(make_consuming_wallet_info("originating_node")) + .chain(cluster.chain) + .min_hops(Hops::OneHop) + .build(), + ); + + thread::sleep(Duration::from_millis(1000)); + let mut client = originating_node.make_client(8080, STANDARD_CLIENT_TIMEOUT_MILLIS); + client.send_chunk(b"GET / HTTP/1.1\r\nHost: www.xvideos.com\r\n\r\n"); + let response = client.wait_for_chunk(); + + assert_eq!( + index_of(&response, &b"

Title: DNS Resolution Problem

"[..]).is_some(), + true, + "Actual response:\n{}", + String::from_utf8(response.clone()).unwrap() + ); + assert_eq!( + index_of(&response, &b"

DNS Failure, We have tried multiple Exit Nodes and all have failed to resolve this address www.xvideos.com

"[..]).is_some(), + true, + "Actual response:\n{}", + String::from_utf8(response).unwrap() + ); +} #[test] fn dns_resolution_failure_no_longer_blacklists_exit_node_for_all_hosts() { diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index f4e2c036f..84a0c1274 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -115,12 +115,6 @@ pub struct ResponseSkeleton { pub context_id: u64, } -#[derive(Debug, PartialEq, Eq)] -pub struct PaymentsAndStartBlock { - pub payments: Vec, - pub new_start_block: u64, -} - #[derive(Debug, PartialEq, Eq, Clone)] pub enum ReceivedPaymentsError { ExceededBlockScanLimit(u64), @@ -137,7 +131,8 @@ pub struct ReceivedPayments { // detects any upcoming delinquency later than the more accurate version would. Is this // a problem? Do we want to correct the timestamp? Discuss. pub timestamp: SystemTime, - pub payments_and_start_block: PaymentsAndStartBlock, + pub new_start_block: u64, + pub transactions: Vec, pub response_skeleton_opt: Option, } @@ -1053,9 +1048,7 @@ mod tests { use crate::accountant::db_access_objects::utils::{from_time_t, to_time_t, CustomQuery}; use crate::accountant::payment_adjuster::Adjustment; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::test_utils::BlockchainAgentMock; - use crate::accountant::scanners::test_utils::{ - make_empty_payments_and_start_block, protect_payables_in_test, - }; + use crate::accountant::scanners::test_utils::protect_payables_in_test; use crate::accountant::scanners::BeginScanError; use crate::accountant::test_utils::DaoWithDestination::{ ForAccountantBody, ForPayableScanner, ForPendingPayableScanner, ForReceivableScanner, @@ -1409,11 +1402,12 @@ mod tests { subject_addr.try_send(BindMessage { peer_actors }).unwrap(); let received_payments = ReceivedPayments { timestamp: SystemTime::now(), - payments_and_start_block: make_empty_payments_and_start_block(), + new_start_block: 0, response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, context_id: 4321, }), + transactions: vec![], }; subject_addr.try_send(received_payments).unwrap(); @@ -2055,15 +2049,12 @@ mod tests { .build(); let system = System::new("accountant_uses_receivables_dao_to_process_received_payments"); let subject = accountant.start(); - let mut payments_and_start_block = make_empty_payments_and_start_block(); - payments_and_start_block.payments = - vec![expected_receivable_1.clone(), expected_receivable_2.clone()]; - payments_and_start_block.new_start_block = 123456789; subject .try_send(ReceivedPayments { timestamp: now, - payments_and_start_block, + new_start_block: 123456789, response_skeleton_opt: None, + transactions: vec![expected_receivable_1.clone(), expected_receivable_2.clone()], }) .expect("unexpected actix error"); diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index 33fe13723..5c6b2c772 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -22,7 +22,7 @@ use crate::accountant::scanners::scanners_utils::pending_payable_scanner_utils:: PendingPayableScanReport, }; use crate::accountant::scanners::scanners_utils::receivable_scanner_utils::balance_and_age; -use crate::accountant::{PaymentsAndStartBlock, PendingPayableId}; +use crate::accountant::PendingPayableId; use crate::accountant::{ comma_joined_stringifiable, gwei_to_wei, Accountant, ReceivedPayments, ReportTransactionReceipts, RequestTransactionReceipts, ResponseSkeleton, ScanForPayables, @@ -831,7 +831,7 @@ impl Scanner for ReceivableScanner { } fn finish_scan(&mut self, msg: ReceivedPayments, logger: &Logger) -> Option { - self.handle_new_received_payments(&msg.payments_and_start_block, msg.timestamp, logger); + self.handle_new_received_payments(&msg, logger); self.mark_as_ended(logger); msg.response_skeleton_opt .map(|response_skeleton| NodeToUiMessage { @@ -865,16 +865,15 @@ impl ReceivableScanner { fn handle_new_received_payments( &mut self, - payments_and_start_block: &PaymentsAndStartBlock, - timestamp: SystemTime, + received_payments_msg: &ReceivedPayments, logger: &Logger, ) { - if payments_and_start_block.payments.is_empty() { + if received_payments_msg.transactions.is_empty() { info!( logger, "No newly received payments were detected during the scanning process." ); - let new_start_block = payments_and_start_block.new_start_block; + let new_start_block = received_payments_msg.new_start_block; match self .persistent_configuration .set_start_block(Some(new_start_block)) @@ -889,8 +888,8 @@ impl ReceivableScanner { let mut txn = self .receivable_dao .as_mut() - .more_money_received(timestamp, &payments_and_start_block.payments); - let new_start_block = payments_and_start_block.new_start_block; + .more_money_received(received_payments_msg.timestamp, &received_payments_msg.transactions); + let new_start_block = received_payments_msg.new_start_block; match self .persistent_configuration .set_start_block_from_txn(Some(new_start_block), &mut txn) @@ -909,8 +908,8 @@ impl ReceivableScanner { Err(e) => panic!("Commit of received transactions failed: {:?}", e), } - let total_newly_paid_receivable = payments_and_start_block - .payments + let total_newly_paid_receivable = received_payments_msg + .transactions .iter() .fold(0, |so_far, now| so_far + now.wei_amount); @@ -1087,9 +1086,7 @@ mod tests { use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::msgs::QualifiedPayablesMessage; use crate::accountant::scanners::scanners_utils::payable_scanner_utils::PendingPayableMetadata; use crate::accountant::scanners::scanners_utils::pending_payable_scanner_utils::{handle_none_status, handle_status_with_failure, PendingPayableScanReport}; - use crate::accountant::scanners::test_utils::{ - make_empty_payments_and_start_block, protect_payables_in_test, - }; + use crate::accountant::scanners::test_utils::protect_payables_in_test; use crate::accountant::scanners::{ BeginScanError, PayableScanner, PendingPayableScanner, ReceivableScanner, ScanSchedulers, Scanner, ScannerCommon, Scanners, @@ -1102,7 +1099,7 @@ mod tests { PendingPayableDaoMock, PendingPayableScannerBuilder, ReceivableDaoFactoryMock, ReceivableDaoMock, ReceivableScannerBuilder, }; - use crate::accountant::{gwei_to_wei, PendingPayableId, ReceivedPayments, ReportTransactionReceipts, RequestTransactionReceipts, SentPayables, DEFAULT_PENDING_TOO_LONG_SEC, PaymentsAndStartBlock}; + use crate::accountant::{gwei_to_wei, PendingPayableId, ReceivedPayments, ReportTransactionReceipts, RequestTransactionReceipts, SentPayables, DEFAULT_PENDING_TOO_LONG_SEC}; use crate::blockchain::blockchain_bridge::{PendingPayableFingerprint, RetrieveTransactions}; use crate::blockchain::blockchain_interface::data_structures::errors::PayableTransactionError; use crate::blockchain::blockchain_interface::data_structures::{ @@ -3049,12 +3046,11 @@ mod tests { let mut subject = ReceivableScannerBuilder::new() .persistent_configuration(persistent_config) .build(); - let mut payments_and_start_block = make_empty_payments_and_start_block(); - payments_and_start_block.new_start_block = new_start_block; let msg = ReceivedPayments { timestamp: SystemTime::now(), - payments_and_start_block, + new_start_block, response_skeleton_opt: None, + transactions: vec![], }; let message_opt = subject.finish_scan(msg, &Logger::new(test_name)); @@ -3084,12 +3080,11 @@ mod tests { let mut subject = ReceivableScannerBuilder::new() .persistent_configuration(persistent_config) .build(); - let mut payments_and_start_block = make_empty_payments_and_start_block(); - payments_and_start_block.new_start_block = 6709; let msg = ReceivedPayments { timestamp: now, - payments_and_start_block, + new_start_block: 6709, response_skeleton_opt: None, + transactions: vec![], }; // Not necessary, rather for preciseness @@ -3138,13 +3133,11 @@ mod tests { wei_amount: 3_333_345, }, ]; - let mut payments_and_start_block = make_empty_payments_and_start_block(); - payments_and_start_block.new_start_block = 7890123; - payments_and_start_block.payments = receivables.clone(); let msg = ReceivedPayments { timestamp: now, - payments_and_start_block, + new_start_block: 7890123, response_skeleton_opt: None, + transactions: receivables.clone(), }; subject.mark_as_started(SystemTime::now()); @@ -3197,11 +3190,9 @@ mod tests { }]; let msg = ReceivedPayments { timestamp: now, - payments_and_start_block: PaymentsAndStartBlock { - payments: receivables, - new_start_block: 7890123, - }, + new_start_block: 7890123, response_skeleton_opt: None, + transactions: receivables, }; // Not necessary, rather for preciseness subject.mark_as_started(SystemTime::now()); @@ -3241,12 +3232,11 @@ mod tests { from: make_wallet("abc"), wei_amount: 45_780, }]; - let mut payments_and_start_block = make_empty_payments_and_start_block(); - payments_and_start_block.payments = receivables; let msg = ReceivedPayments { timestamp: now, - payments_and_start_block, + new_start_block: 0, response_skeleton_opt: None, + transactions: receivables, }; // Not necessary, rather for preciseness subject.mark_as_started(SystemTime::now()); diff --git a/node/src/accountant/scanners/test_utils.rs b/node/src/accountant/scanners/test_utils.rs index c32c10d81..c43d6f71b 100644 --- a/node/src/accountant/scanners/test_utils.rs +++ b/node/src/accountant/scanners/test_utils.rs @@ -3,16 +3,8 @@ #![cfg(test)] use crate::accountant::db_access_objects::payable_dao::PayableAccount; -use crate::accountant::PaymentsAndStartBlock; use masq_lib::type_obfuscation::Obfuscated; pub fn protect_payables_in_test(payables: Vec) -> Obfuscated { Obfuscated::obfuscate_vector(payables) } - -pub fn make_empty_payments_and_start_block() -> PaymentsAndStartBlock { - PaymentsAndStartBlock { - payments: vec![], - new_start_block: 0, - } -} diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 60d2e65dc..91265b3b8 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -4,7 +4,7 @@ use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::msgs::{ BlockchainAgentWithContextMessage, QualifiedPayablesMessage, }; use crate::accountant::{ - PaymentsAndStartBlock, ReceivedPayments, ResponseSkeleton, ScanError, + ReceivedPayments, ResponseSkeleton, ScanError, SentPayables, SkeletonOptHolder, }; use crate::accountant::{ReportTransactionReceipts, RequestTransactionReceipts}; @@ -365,16 +365,12 @@ impl BlockchainBridge { } format!("Error while retrieving transactions: {:?}", e) }) - .and_then(move |transactions| { - let payments_and_start_block = PaymentsAndStartBlock { - payments: transactions.transactions, - new_start_block: transactions.new_start_block, - }; - received_payments_subs - .try_send(ReceivedPayments { + .and_then(move |retrieved_blockchain_transactions| { + received_payments_subs.try_send(ReceivedPayments { timestamp: SystemTime::now(), - payments_and_start_block, + new_start_block: retrieved_blockchain_transactions.new_start_block, response_skeleton_opt: msg.response_skeleton_opt, + transactions: retrieved_blockchain_transactions.transactions, }) .expect("Accountant is dead."); Ok(()) @@ -539,9 +535,7 @@ mod tests { use crate::accountant::db_access_objects::utils::from_time_t; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::agent_web3::WEB3_MAXIMAL_GAS_LIMIT_MARGIN; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::test_utils::BlockchainAgentMock; - use crate::accountant::scanners::test_utils::{ - make_empty_payments_and_start_block, protect_payables_in_test, - }; + use crate::accountant::scanners::test_utils::protect_payables_in_test; use crate::accountant::test_utils::{make_payable_account, make_pending_payable_fingerprint}; use crate::blockchain::blockchain_interface::blockchain_interface_web3::BlockchainInterfaceWeb3; use crate::blockchain::blockchain_interface::data_structures::errors::PayableTransactionError::TransactionID; @@ -1532,9 +1526,6 @@ mod tests { }, ], }; - let mut payments_and_start_block = make_empty_payments_and_start_block(); - payments_and_start_block.payments = expected_transactions.transactions; - payments_and_start_block.new_start_block = expected_transactions.new_start_block; let accountant_received_payment = accountant_recording_arc.lock().unwrap(); assert_eq!(accountant_received_payment.len(), 1); let received_payments = accountant_received_payment.get_record::(0); @@ -1543,11 +1534,12 @@ mod tests { received_payments, &ReceivedPayments { timestamp: received_payments.timestamp, - payments_and_start_block, + new_start_block: expected_transactions.new_start_block, response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, context_id: 4321 }), + transactions: expected_transactions.transactions, } ); } @@ -1636,14 +1628,12 @@ mod tests { received_payments, &ReceivedPayments { timestamp: received_payments.timestamp, + new_start_block: 8675309u64 + 1, + transactions: expected_transactions.transactions, response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, context_id: 4321 }), - payments_and_start_block: PaymentsAndStartBlock { - payments: expected_transactions.transactions, - new_start_block: 8675309u64 + 1 - }, } ); } @@ -1730,14 +1720,12 @@ mod tests { received_payments_message, &ReceivedPayments { timestamp: received_payments_message.timestamp, - payments_and_start_block: PaymentsAndStartBlock { - payments: expected_transactions.transactions, - new_start_block: expected_transactions.new_start_block, - }, + new_start_block: expected_transactions.new_start_block, response_skeleton_opt: Some(ResponseSkeleton { client_id: 1234, context_id: 4321 }), + transactions: expected_transactions.transactions, } ); } diff --git a/node/src/blockchain/blockchain_interface/data_structures/mod.rs b/node/src/blockchain/blockchain_interface/data_structures/mod.rs index aafd1f3fa..4894b3563 100644 --- a/node/src/blockchain/blockchain_interface/data_structures/mod.rs +++ b/node/src/blockchain/blockchain_interface/data_structures/mod.rs @@ -26,7 +26,6 @@ impl fmt::Display for BlockchainTransaction { } } -// TODO: GH-744: Review RetrievedBlockchainTransactions & PaymentsAndStartBlock and keep only one. check master to see whats been used. #[derive(Clone, Debug, Eq, PartialEq)] pub struct RetrievedBlockchainTransactions { pub new_start_block: u64, From 6b9d987b0c6e33aab3fbe9106eb0acbf5a164b7c Mon Sep 17 00:00:00 2001 From: Syther007 Date: Fri, 20 Dec 2024 22:15:32 +1300 Subject: [PATCH 47/56] GH-744: First commit for review-3, fixed tests --- .../mock_blockchain_client_server.rs | 2 +- .../src/mock_blockchain_client_server.rs | 18 +++--- .../tests/blockchain_interaction_test.rs | 4 +- node/src/accountant/mod.rs | 8 +-- .../payable_scanner/agent_null.rs | 15 +++++ .../payable_scanner/agent_web3.rs | 1 + node/src/blockchain/blockchain_bridge.rs | 60 ++++++++++--------- .../lower_level_interface_web3.rs | 18 +++--- .../blockchain_interface_web3/mod.rs | 34 +++++------ .../blockchain_interface_initializer.rs | 8 +-- .../blockchain/blockchain_interface_utils.rs | 9 +-- 11 files changed, 99 insertions(+), 78 deletions(-) diff --git a/masq_lib/src/test_utils/mock_blockchain_client_server.rs b/masq_lib/src/test_utils/mock_blockchain_client_server.rs index 96caf1d67..424a4433d 100644 --- a/masq_lib/src/test_utils/mock_blockchain_client_server.rs +++ b/masq_lib/src/test_utils/mock_blockchain_client_server.rs @@ -65,7 +65,7 @@ impl MBCSBuilder { self.store_response_string(raw_string) } - pub fn response(self, result: R, id: u64) -> Self + pub fn ok_response(self, result: R, id: u64) -> Self where R: Serialize, { diff --git a/multinode_integration_tests/src/mock_blockchain_client_server.rs b/multinode_integration_tests/src/mock_blockchain_client_server.rs index 2672ba196..2f0d7a9c5 100644 --- a/multinode_integration_tests/src/mock_blockchain_client_server.rs +++ b/multinode_integration_tests/src/mock_blockchain_client_server.rs @@ -29,7 +29,7 @@ mod tests { let _cluster = MASQNodeCluster::start(); let port = find_free_port(); let _subject = MockBlockchainClientServer::builder(port) - .response("Thank you and good night", 40) + .ok_response("Thank you and good night", 40) .run_in_docker() .start(); let mut client = connect(port); @@ -60,8 +60,8 @@ mod tests { let _cluster = MASQNodeCluster::start(); let port = find_free_port(); let _subject = MockBlockchainClientServer::builder(port) - .response("Welcome, and thanks for coming!", 39) - .response("Thank you and good night", 40) + .ok_response("Welcome, and thanks for coming!", 39) + .ok_response("Thank you and good night", 40) .run_in_docker() .start(); let mut client = connect(port); @@ -85,7 +85,7 @@ mod tests { let _cluster = MASQNodeCluster::start(); let port = find_free_port(); let _subject = MockBlockchainClientServer::builder(port) - .response("irrelevant".to_string(), 42) + .ok_response("irrelevant".to_string(), 42) .run_in_docker() .start(); let mut client = connect(port); @@ -102,7 +102,7 @@ mod tests { let _cluster = MASQNodeCluster::start(); let port = find_free_port(); let _subject = MockBlockchainClientServer::builder(port) - .response("irrelevant".to_string(), 42) + .ok_response("irrelevant".to_string(), 42) .run_in_docker() .start(); let mut client = connect(port); @@ -119,7 +119,7 @@ mod tests { let _cluster = MASQNodeCluster::start(); let port = find_free_port(); let _subject = MockBlockchainClientServer::builder(port) - .response("irrelevant".to_string(), 42) + .ok_response("irrelevant".to_string(), 42) .run_in_docker() .start(); let mut client = connect(port); @@ -138,10 +138,10 @@ mod tests { let subject = MockBlockchainClientServer::builder(port) .notifier(notifier) .begin_batch() - .response(1234u64, 40) + .ok_response(1234u64, 40) .error(1234, "My tummy hurts", None as Option<()>) .end_batch() - .response( + .ok_response( Person { name: "Billy".to_string(), age: 15, @@ -211,7 +211,7 @@ mod tests { let _cluster = MASQNodeCluster::start(); let port = find_free_port(); let subject = MockBlockchainClientServer::builder(port) - .response( + .ok_response( Person { name: "Billy".to_string(), age: 15, diff --git a/multinode_integration_tests/tests/blockchain_interaction_test.rs b/multinode_integration_tests/tests/blockchain_interaction_test.rs index 42381891c..05bc1f8b5 100644 --- a/multinode_integration_tests/tests/blockchain_interaction_test.rs +++ b/multinode_integration_tests/tests/blockchain_interaction_test.rs @@ -32,8 +32,8 @@ fn debtors_are_credited_once_but_not_twice() { // Create and initialize mock blockchain client: prepare a receivable at block 2000 eprintln!("Setting up mock blockchain client"); let blockchain_client_server = MBCSBuilder::new(mbcs_port) - .response("0x5DC", 1) // eth_blockNumber 1500 - .response( + .ok_response("0x5DC", 1) // eth_blockNumber 1500 + .ok_response( vec![LogObject { removed: false, log_index: Some("0x20".to_string()), diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index 84a0c1274..f2d6f50ec 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -3446,16 +3446,16 @@ mod tests { .unwrap(); let _blockchain_client_server = MBCSBuilder::new(port) // Blockchain Agent Gas Price - .response("0x3B9ACA00".to_string(), 0) // 1000000000 + .ok_response("0x3B9ACA00".to_string(), 0) // 1000000000 // Blockchain Agent transaction fee balance - .response("0xFFF0".to_string(), 0) // 65520 + .ok_response("0xFFF0".to_string(), 0) // 65520 // Blockchain Agent masq balance - .response( + .ok_response( "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), 0, ) // Submit payments to blockchain - .response("0xFFF0".to_string(), 1) + .ok_response("0xFFF0".to_string(), 1) .begin_batch() .raw_response( ReceiptResponseBuilder::default() diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs index 31f0758e4..92f53e805 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs @@ -86,6 +86,7 @@ mod tests { use masq_lib::logger::Logger; use masq_lib::test_utils::logging::{init_test_logging, TestLogHandler}; use web3::types::U256; + use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; fn blockchain_agent_null_constructor_works(constructor: C) where @@ -178,4 +179,18 @@ mod tests { assert_eq!(result, &Wallet::null()); assert_error_log(test_name, "consuming_wallet") } + + #[test] + fn null_agent_get_chain() { + init_test_logging(); + let test_name = "null_agent_get_chain"; + let mut subject = BlockchainAgentNull::new(); + subject.logger = Logger::new(test_name); + + let result = subject.get_chain(); + + assert_eq!(result, TEST_DEFAULT_CHAIN); + assert_error_log(test_name, "get_chain") + } + } diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs index af49f3950..725e14f00 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_web3.rs @@ -102,6 +102,7 @@ mod tests { subject.consuming_wallet_balances(), consuming_wallet_balances ); + assert_eq!(subject.get_chain(), TEST_DEFAULT_CHAIN); } #[test] diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 91265b3b8..f2ecc46e3 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -668,9 +668,9 @@ mod tests { ); let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x230000000".to_string(), 1) // 9395240960 - .response("0x23".to_string(), 1) - .response( + .ok_response("0x230000000".to_string(), 1) // 9395240960 + .ok_response("0x23".to_string(), 1) + .ok_response( "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), 0, ) @@ -777,8 +777,8 @@ mod tests { let port = find_free_port(); // build blockchain agent fails by not providing the third response. let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x23".to_string(), 1) - .response("0x23".to_string(), 1) + .ok_response("0x23".to_string(), 1) + .ok_response("0x23".to_string(), 1) .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant_recipient = accountant.start().recipient(); @@ -833,9 +833,9 @@ mod tests { ); let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x20".to_string(), 1) + .ok_response("0x20".to_string(), 1) .begin_batch() - .response("rpc result".to_string(), 1) + .ok_response("rpc result".to_string(), 1) .end_batch() .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); @@ -927,7 +927,7 @@ mod tests { let port = find_free_port(); // To make submit_batch failed we didn't provide any responses for batch calls let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x20".to_string(), 1) + .ok_response("0x20".to_string(), 1) .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant_addr = accountant @@ -1013,10 +1013,10 @@ mod tests { let test_name = "process_payments_works"; let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x01".to_string(), 1) + .ok_response("0x01".to_string(), 1) .begin_batch() - .response("rpc_result".to_string(), 7) - .response("rpc_result_2".to_string(), 7) + .ok_response("rpc_result".to_string(), 7) + .ok_response("rpc_result_2".to_string(), 7) .end_batch() .start(); let blockchain_interface_web3 = make_blockchain_interface_web3(port); @@ -1077,7 +1077,7 @@ mod tests { let test_name = "process_payments_fails_on_get_transaction_count"; let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("trash transaction id".to_string(), 1) + .ok_response("trash transaction id".to_string(), 1) .start(); let blockchain_interface_web3 = make_blockchain_interface_web3(port); let consuming_wallet = make_paying_wallet(b"consuming_wallet"); @@ -1213,7 +1213,7 @@ mod tests { let port = find_free_port(); // We have intentionally left out responses to cause this error let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0) + .ok_response("0x3B9ACA00".to_string(), 0) .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant_addr = accountant @@ -1447,7 +1447,7 @@ mod tests { ); let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0xC8".to_string(), 0) + .ok_response("0xC8".to_string(), 0) .raw_response(r#"{ "jsonrpc": "2.0", "id": 1, @@ -1516,13 +1516,17 @@ mod tests { transactions: vec![ BlockchainTransaction { block_number: 6040059, - from: make_wallet("first_wallet"), // Relates to RPC response topics of 1 - wei_amount: 42, // Relates to RPC response field data + // Wallet represented in the RPC response by the first 'topic' as: 0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80 + from: make_wallet("first_wallet"), + // Paid amount read out from the field 'data' in the RPC + wei_amount: 42, }, BlockchainTransaction { block_number: 6040060, - from: make_wallet("second_wallet"), // Relates to RPC response topics of 1 - wei_amount: 55, // Relates to RPC response field data + // Wallet represented in the RPC response by the first 'topic' as: 0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80 + from: make_wallet("second_wallet"), + // Paid amount read out from the field 'data' in the RPC + wei_amount: 55, }, ], }; @@ -1552,8 +1556,8 @@ mod tests { ); let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x845FED".to_string(), 0) - .response( + .ok_response("0x845FED".to_string(), 0) + .ok_response( vec![LogObject { removed: false, log_index: Some("0x20".to_string()), @@ -1644,8 +1648,8 @@ mod tests { System::new("handle_retrieve_transactions_sends_received_payments_back_to_accountant"); let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0) - .response( + .ok_response("0x3B9ACA00".to_string(), 0) + .ok_response( vec![LogObject { removed: false, log_index: Some("0x20".to_string()), @@ -1755,8 +1759,8 @@ mod tests { ], }]; let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0) - .response(expected_response_logs, 1) + .ok_response("0x3B9ACA00".to_string(), 0) + .ok_response(expected_response_logs, 1) .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); let accountant_addr = accountant.system_stop_conditions(match_every_type_id!(ScanError)); @@ -1814,7 +1818,7 @@ mod tests { let system = System::new(test_name); let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0) + .ok_response("0x3B9ACA00".to_string(), 0) .err_response(-32005, "Blockheight too far in the past. Check params passed to eth_getLogs or eth_call requests.Range of blocks allowed for your plan: 1000", 0) .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); @@ -1879,7 +1883,7 @@ mod tests { let system = System::new("test"); let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0) + .ok_response("0x3B9ACA00".to_string(), 0) .err_response(-32005, "Blockheight too far in the past. Check params passed to eth_getLogs or eth_call requests.Range of blocks allowed for your plan: 1000", 0) .start(); let (accountant, _, _) = make_recorder(); @@ -1940,7 +1944,7 @@ mod tests { fn handle_scan_future_handles_success() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0xC8".to_string(), 0) + .ok_response("0xC8".to_string(), 0) .raw_response(r#"{ "jsonrpc": "2.0", "id": 1, @@ -2032,7 +2036,7 @@ mod tests { init_test_logging(); let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0xC8".to_string(), 0) + .ok_response("0xC8".to_string(), 0) .err_response(-32005, "My tummy hurts", 0) .start(); let (accountant, _, accountant_recording_arc) = make_recorder(); diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index fada38b51..13e67c180 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -170,7 +170,7 @@ mod tests { fn get_transaction_fee_balance_works() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x23".to_string(), 1) + .ok_response("0x23".to_string(), 1) .start(); let wallet = &Wallet::from_str("0x3f69f9efd4f2592fd70be8c32ecd9dce71c472fc").unwrap(); let subject = make_blockchain_interface_web3(port); @@ -188,7 +188,7 @@ mod tests { ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0xFFFQ".to_string(), 0) + .ok_response("0xFFFQ".to_string(), 0) .start(); let subject = make_blockchain_interface_web3(port); @@ -213,7 +213,7 @@ mod tests { fn get_gas_price_works() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x01".to_string(), 1) + .ok_response("0x01".to_string(), 1) .start(); let subject = make_blockchain_interface_web3(port); @@ -244,7 +244,7 @@ mod tests { fn get_block_number_works() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x23".to_string(), 1) + .ok_response("0x23".to_string(), 1) .start(); let subject = make_blockchain_interface_web3(port); @@ -257,7 +257,7 @@ mod tests { fn get_block_number_returns_an_error() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("trash".to_string(), 1) + .ok_response("trash".to_string(), 1) .start(); let subject = make_blockchain_interface_web3(port); @@ -279,7 +279,7 @@ mod tests { fn get_transaction_id_works() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x23".to_string(), 1) + .ok_response("0x23".to_string(), 1) .start(); let subject = make_blockchain_interface_web3(port); let wallet = &Wallet::from_str("0x3f69f9efd4f2592fd70be8c32ecd9dce71c472fc").unwrap(); @@ -296,7 +296,7 @@ mod tests { fn get_transaction_id_returns_an_error_for_unintelligible_response() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0xFFFQ".to_string(), 0) + .ok_response("0xFFFQ".to_string(), 0) .start(); let subject = make_blockchain_interface_web3(port); @@ -321,7 +321,7 @@ mod tests { fn get_token_balance_can_retrieve_token_balance_of_a_wallet() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response( + .ok_response( "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), 0, ) @@ -345,7 +345,7 @@ mod tests { fn get_token_balance_returns_error_for_unintelligible_response_to_token_balance() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response( + .ok_response( "0x000000000000000000000000000000000000000000000000000000000000FFFQ".to_string(), 0, ) diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index b4664553b..87c7c937f 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -471,7 +471,7 @@ mod tests { let port = find_free_port(); #[rustfmt::skip] let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x178def", 1) + .ok_response("0x178def", 1) .raw_response( r#"{ "jsonrpc":"2.0", @@ -569,8 +569,8 @@ mod tests { let port = find_free_port(); let empty_transactions_result: Vec = vec![]; let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x178def".to_string(), 2) - .response(empty_transactions_result, 2) + .ok_response("0x178def".to_string(), 2) + .ok_response(empty_transactions_result, 2) .start(); let subject = make_blockchain_interface_web3(port); let end_block_nbr = 1024u64; @@ -623,7 +623,7 @@ mod tests { ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x178def", 1) + .ok_response("0x178def", 1) .raw_response(r#"{"jsonrpc":"2.0","id":3,"result":[{"address":"0xcd6c588e005032dd882cd43bf53a32129be81302","blockHash":"0x1a24b9169cbaec3f6effa1f600b70c7ab9e8e86db44062b49132a4415d26732a","blockNumber":"0x4be663","data":"0x0000000000000000000000000000000000000000000000056bc75e2d63100000","logIndex":"0x0","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],"transactionHash":"0x955cec6ac4f832911ab894ce16aa22c3003f46deff3f7165b32700d2f5ff0681","transactionIndex":"0x0"}]}"#.to_string()) .start(); let subject = make_blockchain_interface_web3(port); @@ -649,7 +649,7 @@ mod tests { ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x178def", 1) + .ok_response("0x178def", 1) .raw_response(r#"{"jsonrpc":"2.0","id":3,"result":[{"address":"0xcd6c588e005032dd882cd43bf53a32129be81302","blockHash":"0x1a24b9169cbaec3f6effa1f600b70c7ab9e8e86db44062b49132a4415d26732a","blockNumber":"0x4be663","data":"0x0000000000000000000000000000000000000000000000056bc75e2d6310000001","logIndex":"0x0","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000003f69f9efd4f2592fd70be8c32ecd9dce71c472fc","0x000000000000000000000000adc1853c7859369639eb414b6342b36288fe6092"],"transactionHash":"0x955cec6ac4f832911ab894ce16aa22c3003f46deff3f7165b32700d2f5ff0681","transactionIndex":"0x0"}]}"#.to_string()) .start(); let subject = make_blockchain_interface_web3(port); @@ -672,7 +672,7 @@ mod tests { ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x400", 1) + .ok_response("0x400", 1) .raw_response(r#"{"jsonrpc":"2.0","id":2,"result":[{"address":"0xcd6c588e005032dd882cd43bf53a32129be81302","blockHash":"0x1a24b9169cbaec3f6effa1f600b70c7ab9e8e86db44062b49132a4415d26732a","data":"0x0000000000000000000000000000000000000000000000000010000000000000","logIndex":"0x0","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000003f69f9efd4f2592fd70be8c32ecd9dce71c472fc","0x000000000000000000000000adc1853c7859369639eb414b6342b36288fe6092"],"transactionHash":"0x955cec6ac4f832911ab894ce16aa22c3003f46deff3f7165b32700d2f5ff0681","transactionIndex":"0x0"}]}"#.to_string()) .start(); init_test_logging(); @@ -714,7 +714,7 @@ mod tests { ) { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("trash", 1) + .ok_response("trash", 1) .raw_response(r#"{"jsonrpc":"2.0","id":2,"result":[{"address":"0xcd6c588e005032dd882cd43bf53a32129be81302","blockHash":"0x1a24b9169cbaec3f6effa1f600b70c7ab9e8e86db44062b49132a4415d26732a","data":"0x0000000000000000000000000000000000000000000000000010000000000000","logIndex":"0x0","removed":false,"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000003f69f9efd4f2592fd70be8c32ecd9dce71c472fc","0x000000000000000000000000adc1853c7859369639eb414b6342b36288fe6092"],"transactionHash":"0x955cec6ac4f832911ab894ce16aa22c3003f46deff3f7165b32700d2f5ff0681","transactionIndex":"0x0"}]}"#.to_string()) .start(); let subject = make_blockchain_interface_web3(port); @@ -746,11 +746,11 @@ mod tests { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) // gas_price - .response("0x3B9ACA00".to_string(), 0) // 1000000000 + .ok_response("0x3B9ACA00".to_string(), 0) // 1000000000 // transaction_fee_balance - .response("0xFFF0".to_string(), 0) // 65520 + .ok_response("0xFFF0".to_string(), 0) // 65520 // masq_balance - .response( + .ok_response( "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), // 65535 0, ) @@ -825,7 +825,7 @@ mod tests { fn build_of_the_blockchain_agent_fails_on_transaction_fee_balance() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0) + .ok_response("0x3B9ACA00".to_string(), 0) .start(); let expected_err_factory = |wallet: &Wallet| { BlockchainAgentBuildError::TransactionFeeBalance( @@ -846,8 +846,8 @@ mod tests { fn build_of_the_blockchain_agent_fails_on_masq_balance() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0) - .response("0xFFF0".to_string(), 0) + .ok_response("0x3B9ACA00".to_string(), 0) + .ok_response("0xFFF0".to_string(), 0) .start(); let expected_err_factory = |wallet: &Wallet| { BlockchainAgentBuildError::ServiceFeeBalance( @@ -920,7 +920,7 @@ mod tests { 7, ) .raw_response(r#"{ "jsonrpc": "2.0", "id": 1, "result": null }"#.to_string()) - .response("trash".to_string(), 0) + .ok_response("trash".to_string(), 0) .raw_response(tx_receipt_response_not_present) .raw_response(tx_receipt_response_failed) .raw_response(tx_receipt_response_success) @@ -975,14 +975,14 @@ mod tests { .unwrap(); let tx_hash_vec = vec![tx_hash_1, tx_hash_2]; - let result = subject + let error = subject .process_transaction_receipts(tx_hash_vec) .wait() .unwrap_err(); assert_eq!( - result, - BlockchainError::QueryFailed("Transport error: Error(IncompleteMessage)".to_string()) + error, + QueryFailed("Transport error: Error(IncompleteMessage)".to_string()) ); } diff --git a/node/src/blockchain/blockchain_interface_initializer.rs b/node/src/blockchain/blockchain_interface_initializer.rs index 06fbf491b..ee87519a0 100644 --- a/node/src/blockchain/blockchain_interface_initializer.rs +++ b/node/src/blockchain/blockchain_interface_initializer.rs @@ -63,13 +63,13 @@ mod tests { fn initialize_web3_interface_works() { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) - .response("0x3B9ACA00".to_string(), 0) // gas_price = 10000000000 - .response("0xFF40".to_string(), 0) - .response( + .ok_response("0x3B9ACA00".to_string(), 0) // gas_price = 10000000000 + .ok_response("0xFF40".to_string(), 0) + .ok_response( "0x000000000000000000000000000000000000000000000000000000000000FFFF".to_string(), 0, ) - .response("0x23".to_string(), 1) + .ok_response("0x23".to_string(), 1) .start(); let wallet = make_wallet("123"); let chain = Chain::PolyMainnet; diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface_utils.rs index 65597a246..ad5e21da7 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface_utils.rs @@ -377,7 +377,7 @@ mod tests { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() - .response( + .ok_response( "0x94881436a9c89f48b01651ff491c69e97089daf71ab8cfb240243d7ecf9b38b2".to_string(), 7, ) @@ -642,8 +642,9 @@ mod tests { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() - .response("rpc_result".to_string(), 7) - .response("rpc_result_2".to_string(), 8) + // TODO: GH-547: This rpc_result should be validated in production code. + .ok_response("irrelevant_ok_rpc_response".to_string(), 7) + .ok_response("irrelevant_ok_rpc_response_2".to_string(), 8) .end_batch() .start(); let expected_result = Ok(vec![ @@ -748,7 +749,7 @@ mod tests { let port = find_free_port(); let _blockchain_client_server = MBCSBuilder::new(port) .begin_batch() - .response("rpc_result".to_string(), 7) + .ok_response("rpc_result".to_string(), 7) .err_response( 429, "The requests per second (RPS) of your requests are higher than your plan allows." From d81ac193802b3efcce7dcc0af09001d53a149305 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Fri, 20 Dec 2024 22:52:48 +1300 Subject: [PATCH 48/56] GH-744: Refactored TxReceipt --- .../lower_level_interface_web3.rs | 34 +++++++++++++++---- .../blockchain_interface_web3/mod.rs | 13 ++++--- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index 13e67c180..aae3b3a42 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -20,25 +20,47 @@ pub enum TransactionReceiptResult { LocalError(String), } +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum TxStatus { + Failed, + Pending, + Succeeded(TransactionBlock), +} + #[derive(Debug, PartialEq, Eq, Clone)] pub struct TxReceipt { pub transaction_hash: H256, - pub block_hash: Option, - pub block_number: Option, - pub status: Option, + pub status: TxStatus, +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct TransactionBlock { + pub block_hash: H256, + pub block_number: U64 } impl From for TxReceipt { fn from(receipt: TransactionReceipt) -> Self { + let status = match (receipt.status, receipt.block_hash, receipt.block_number) { + (Some(status), Some(block_hash), Some(block_number)) if status == U64::from(1) => { + TxStatus::Succeeded(TransactionBlock { + block_hash, + block_number, + }) + } + (Some(status), _, _) if status == U64::from(0) => TxStatus::Failed, + _ => TxStatus::Pending, + }; + TxReceipt { transaction_hash: receipt.transaction_hash, - block_hash: receipt.block_hash, - block_number: receipt.block_number, - status: receipt.status.map(|s| s == U64::from(1)), + status, } } } + + pub struct LowBlockchainIntWeb3 { web3: Web3, web3_batch: Web3>, diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 87c7c937f..e28897945 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -415,7 +415,7 @@ mod tests { use std::str::FromStr; use web3::transports::Http; use web3::types::{H256, U256}; - use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TxReceipt; + use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{TransactionBlock, TxReceipt, TxStatus}; #[test] fn constants_are_correct() { @@ -946,18 +946,17 @@ mod tests { result[4], TransactionReceiptResult::TransactionFailed(TxReceipt { transaction_hash: tx_hash_5, - block_hash: None, - block_number: None, - status: Some(false), + status: TxStatus::Failed, }) ); assert_eq!( result[5], TransactionReceiptResult::Found(TxReceipt { transaction_hash: tx_hash_6, - block_hash: Some(block_hash), - block_number: Some(block_number), - status: Some(true), + status: TxStatus::Succeeded(TransactionBlock { + block_hash, + block_number, + }), }) ); } From 69f70c1a3c23b655919f20646c9bfd7acd2c45a6 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Sat, 21 Dec 2024 00:00:26 +1300 Subject: [PATCH 49/56] GH-744: Refactored TxResponse --- node/src/accountant/mod.rs | 10 ++++- node/src/accountant/scanners/mod.rs | 45 ++++++++++++------- node/src/blockchain/blockchain_bridge.rs | 23 ++++++---- .../lower_level_interface_web3.rs | 4 +- .../blockchain_interface_web3/mod.rs | 33 ++++++-------- 5 files changed, 66 insertions(+), 49 deletions(-) diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index f2d6f50ec..723bbfa56 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -3510,6 +3510,8 @@ mod tests { ReceiptResponseBuilder::default() .transaction_hash(pending_tx_hash_2) .status(U64::from(1)) + .block_number(U64::from(1234)) + .block_hash(Default::default()) .build(), ) .end_batch() @@ -3800,6 +3802,8 @@ mod tests { let mut transaction_receipt_1 = TransactionReceipt::default(); transaction_receipt_1.transaction_hash = transaction_hash_1; transaction_receipt_1.status = Some(U64::from(1)); //success + transaction_receipt_1.block_number = Some(U64::from(100)); + transaction_receipt_1.block_hash = Some(Default::default()); let fingerprint_1 = PendingPayableFingerprint { rowid: 5, timestamp: from_time_t(200_000_000), @@ -3812,6 +3816,8 @@ mod tests { let mut transaction_receipt_2 = TransactionReceipt::default(); transaction_receipt_2.transaction_hash = transaction_hash_2; transaction_receipt_2.status = Some(U64::from(1)); //success + transaction_receipt_2.block_number = Some(U64::from(200)); + transaction_receipt_2.block_hash = Some(Default::default()); let fingerprint_2 = PendingPayableFingerprint { rowid: 10, timestamp: from_time_t(199_780_000), @@ -3823,11 +3829,11 @@ mod tests { let msg = ReportTransactionReceipts { fingerprints_with_receipts: vec![ ( - TransactionReceiptResult::Found(transaction_receipt_1.into()), + TransactionReceiptResult::RpcResponse(transaction_receipt_1.into()), fingerprint_1.clone(), ), ( - TransactionReceiptResult::Found(transaction_receipt_2.into()), + TransactionReceiptResult::RpcResponse(transaction_receipt_2.into()), fingerprint_2.clone(), ), ], diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index 5c6b2c772..fbf640d9a 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -55,7 +55,7 @@ use web3::types::H256; use masq_lib::type_obfuscation::Obfuscated; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::{PreparedAdjustment, MultistagePayableScanner, SolvencySensitivePaymentInstructor}; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::msgs::{BlockchainAgentWithContextMessage, QualifiedPayablesMessage}; -use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; +use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{TransactionReceiptResult, TxStatus}; use crate::blockchain::blockchain_interface::data_structures::errors::PayableTransactionError; use crate::db_config::persistent_configuration::{PersistentConfiguration, PersistentConfigurationReal}; @@ -675,18 +675,24 @@ impl PendingPayableScanner { msg.fingerprints_with_receipts.into_iter().fold( scan_report, |scan_report_so_far, (receipt_result, fingerprint)| match receipt_result { - TransactionReceiptResult::Found(_receipt) => { - handle_status_with_success(scan_report_so_far, fingerprint, logger) + TransactionReceiptResult::RpcResponse(tx_receipt) => { + match tx_receipt.status { + TxStatus::Pending => { + handle_none_receipt( + scan_report_so_far, + fingerprint, + "none was given".to_string(), + logger, + ) + } + TxStatus::Failed => { + handle_status_with_failure(scan_report_so_far, fingerprint, logger) + } + TxStatus::Succeeded(_) => { + handle_status_with_success(scan_report_so_far, fingerprint, logger) + } + } } - TransactionReceiptResult::TransactionFailed(_receipt) => { - handle_status_with_failure(scan_report_so_far, fingerprint, logger) - } - TransactionReceiptResult::NotPresent => handle_none_receipt( - scan_report_so_far, - fingerprint, - "none was given".to_string(), - logger, - ), TransactionReceiptResult::LocalError(e) => handle_none_receipt( scan_report_so_far, fingerprint, @@ -1133,7 +1139,7 @@ mod tests { use std::time::{Duration, SystemTime}; use web3::types::{TransactionReceipt, H256}; use web3::Error; - use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; + use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{TransactionReceiptResult, TxReceipt, TxStatus}; #[test] fn scanners_struct_can_be_constructed_with_the_respective_scanners() { @@ -2498,7 +2504,10 @@ mod tests { }; let msg = ReportTransactionReceipts { fingerprints_with_receipts: vec![( - TransactionReceiptResult::NotPresent, + TransactionReceiptResult::RpcResponse(TxReceipt{ + transaction_hash: hash, + status: TxStatus::Pending + }), fingerprint.clone(), )], response_skeleton_opt: None, @@ -2821,6 +2830,8 @@ mod tests { let mut transaction_receipt_1 = TransactionReceipt::default(); transaction_receipt_1.transaction_hash = transaction_hash_1; transaction_receipt_1.status = Some(U64::from(1)); //success + transaction_receipt_1.block_number = Some(U64::from(1234)); + transaction_receipt_1.block_hash = Some(Default::default()); let fingerprint_1 = PendingPayableFingerprint { rowid: 5, timestamp: from_time_t(200_000_000), @@ -2833,6 +2844,8 @@ mod tests { let mut transaction_receipt_2 = TransactionReceipt::default(); transaction_receipt_2.transaction_hash = transaction_hash_2; transaction_receipt_2.status = Some(U64::from(1)); //success + transaction_receipt_2.block_number = Some(U64::from(2345)); + transaction_receipt_2.block_hash = Some(Default::default()); let fingerprint_2 = PendingPayableFingerprint { rowid: 10, timestamp: from_time_t(199_780_000), @@ -2844,11 +2857,11 @@ mod tests { let msg = ReportTransactionReceipts { fingerprints_with_receipts: vec![ ( - TransactionReceiptResult::Found(transaction_receipt_1.into()), + TransactionReceiptResult::RpcResponse(transaction_receipt_1.into()), fingerprint_1.clone(), ), ( - TransactionReceiptResult::Found(transaction_receipt_2.into()), + TransactionReceiptResult::RpcResponse(transaction_receipt_2.into()), fingerprint_2.clone(), ), ], diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index f2ecc46e3..68e690704 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -47,7 +47,7 @@ use ethabi::Hash; use web3::types::H256; use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; -use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TransactionReceiptResult; +use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{TransactionReceiptResult, TxStatus}; pub const CRASH_KEY: &str = "BLOCKCHAINBRIDGE"; pub const DEFAULT_BLOCKCHAIN_SERVICE_URL: &str = "https://0.0.0.0"; @@ -403,8 +403,10 @@ impl BlockchainBridge { let length = transaction_receipts_results.len(); let mut transactions_found = 0; for transaction_receipt in &transaction_receipts_results { - if let TransactionReceiptResult::Found(_) = transaction_receipt { - transactions_found += 1; + if let TransactionReceiptResult::RpcResponse(tx_receipt) = transaction_receipt { + if let TxStatus::Succeeded(_) = tx_receipt.status { + transactions_found += 1; + } } } let pairs = transaction_receipts_results @@ -581,6 +583,7 @@ mod tests { use std::sync::{Arc, Mutex}; use std::time::{Duration, SystemTime}; use web3::types::{TransactionReceipt, H160}; + use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TxReceipt; impl Handler> for BlockchainBridge { type Result = (); @@ -1191,11 +1194,13 @@ mod tests { &ReportTransactionReceipts { fingerprints_with_receipts: vec![ ( - TransactionReceiptResult::Found(expected_receipt.into()), + TransactionReceiptResult::RpcResponse(expected_receipt.into()), pending_payable_fingerprint_1 ), ( - TransactionReceiptResult::NotPresent, + TransactionReceiptResult::RpcResponse(TxReceipt{ + transaction_hash: hash_2, + status: TxStatus::Pending }), pending_payable_fingerprint_2 ), ], @@ -1267,6 +1272,7 @@ mod tests { let contract_address = H160::from_low_u64_be(887766); let tx_receipt_response = ReceiptResponseBuilder::default() .block_number(block_number) + .block_hash(Default::default()) .status(U64::from(1)) .contract_address(contract_address) .build(); @@ -1322,6 +1328,7 @@ mod tests { }; let mut transaction_receipt = TransactionReceipt::default(); transaction_receipt.block_number = Some(block_number); + transaction_receipt.block_hash = Some(Default::default()); transaction_receipt.contract_address = Some(contract_address); transaction_receipt.status = Some(U64::from(1)); let blockchain_interface = make_blockchain_interface_web3(port); @@ -1359,9 +1366,9 @@ mod tests { *report_receipts_msg, ReportTransactionReceipts { fingerprints_with_receipts: vec![ - (TransactionReceiptResult::NotPresent, fingerprint_1), - (TransactionReceiptResult::Found(transaction_receipt.into()), fingerprint_2), - (TransactionReceiptResult::NotPresent, fingerprint_3), + (TransactionReceiptResult::RpcResponse(TxReceipt{ transaction_hash: hash_1, status: TxStatus::Pending }), fingerprint_1), + (TransactionReceiptResult::RpcResponse(transaction_receipt.into()), fingerprint_2), + (TransactionReceiptResult::RpcResponse(TxReceipt{ transaction_hash: hash_3, status: TxStatus::Pending }), fingerprint_3), (TransactionReceiptResult::LocalError("RPC error: Error { code: ServerError(429), message: \"The requests per second (RPS) of your requests are higher than your plan allows.\", data: None }".to_string()), fingerprint_4) ], response_skeleton_opt: Some(ResponseSkeleton { diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index aae3b3a42..def0cf053 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -14,9 +14,7 @@ use web3::{Error, Web3}; #[derive(Debug, PartialEq, Eq, Clone)] pub enum TransactionReceiptResult { - NotPresent, - Found(TxReceipt), - TransactionFailed(TxReceipt), + RpcResponse(TxReceipt), LocalError(String), } diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index e28897945..ad513f3d4 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -20,7 +20,7 @@ use web3::transports::{EventLoopHandle, Http}; use web3::types::{Address, BlockNumber, Log, H256, U256, FilterBuilder, TransactionReceipt}; use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; -use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{LowBlockchainIntWeb3, TransactionReceiptResult}; +use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{LowBlockchainIntWeb3, TransactionReceiptResult, TxReceipt, TxStatus}; use crate::blockchain::blockchain_interface_utils::{dynamically_create_blockchain_agent_web3, send_payables_within_batch, BlockchainAgentFutureResult}; const CONTRACT_ABI: &str = indoc!( @@ -202,29 +202,22 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { ) -> Box, Error = BlockchainError>> { Box::new( self.lower_interface() - .get_transaction_receipt_in_batch(transaction_hashes) + .get_transaction_receipt_in_batch(transaction_hashes.clone()) .map_err(|e| e) .and_then(move |batch_response| { Ok(batch_response .into_iter() - .map(|response| match response { + .zip(transaction_hashes) + .map(|(response, hash)| match response { Ok(result) => { match serde_json::from_value::(result) { - Ok(receipt) => match receipt.status { - None => TransactionReceiptResult::NotPresent, - Some(status) => { - if status == U64::from(1) { - TransactionReceiptResult::Found(receipt.into()) - } else { - TransactionReceiptResult::TransactionFailed( - receipt.into(), - ) - } - } - }, + Ok(receipt) => TransactionReceiptResult::RpcResponse(receipt.into()), Err(e) => { if e.to_string().contains("invalid type: null") { - TransactionReceiptResult::NotPresent + TransactionReceiptResult::RpcResponse(TxReceipt{ + transaction_hash: hash, + status: TxStatus::Pending + }) } else { TransactionReceiptResult::LocalError(e.to_string()) } @@ -934,24 +927,24 @@ mod tests { .unwrap(); assert_eq!(result[0], TransactionReceiptResult::LocalError("RPC error: Error { code: ServerError(429), message: \"The requests per second (RPS) of your requests are higher than your plan allows.\", data: None }".to_string())); - assert_eq!(result[1], TransactionReceiptResult::NotPresent); + assert_eq!(result[1], TransactionReceiptResult::RpcResponse(TxReceipt{ transaction_hash: tx_hash_2, status: TxStatus::Pending })); assert_eq!( result[2], TransactionReceiptResult::LocalError( "invalid type: string \"trash\", expected struct Receipt".to_string() ) ); - assert_eq!(result[3], TransactionReceiptResult::NotPresent); + assert_eq!(result[3], TransactionReceiptResult::RpcResponse(TxReceipt{ transaction_hash: tx_hash_4, status: TxStatus::Pending })); assert_eq!( result[4], - TransactionReceiptResult::TransactionFailed(TxReceipt { + TransactionReceiptResult::RpcResponse(TxReceipt { transaction_hash: tx_hash_5, status: TxStatus::Failed, }) ); assert_eq!( result[5], - TransactionReceiptResult::Found(TxReceipt { + TransactionReceiptResult::RpcResponse(TxReceipt { transaction_hash: tx_hash_6, status: TxStatus::Succeeded(TransactionBlock { block_hash, From d30dc27f942af6920bf22b1e1cac0408db289a50 Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 23 Dec 2024 20:48:42 +1300 Subject: [PATCH 50/56] GH-744 moved & renamed blockchain_interface_utils.rs --- .../blockchain_interface/blockchain_interface_web3/mod.rs | 4 +++- .../blockchain_interface_web3/utils.rs} | 3 --- node/src/blockchain/mod.rs | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) rename node/src/blockchain/{blockchain_interface_utils.rs => blockchain_interface/blockchain_interface_web3/utils.rs} (99%) diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index ad513f3d4..3d03dc446 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -1,6 +1,8 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. pub mod lower_level_interface_web3; +mod utils; + use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::blockchain_agent::BlockchainAgent; use crate::blockchain::blockchain_interface::data_structures::errors::{BlockchainError, PayableTransactionError}; use crate::blockchain::blockchain_interface::data_structures::{BlockchainTransaction, ProcessedPayableFallible}; @@ -21,7 +23,7 @@ use web3::types::{Address, BlockNumber, Log, H256, U256, FilterBuilder, Transact use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{LowBlockchainIntWeb3, TransactionReceiptResult, TxReceipt, TxStatus}; -use crate::blockchain::blockchain_interface_utils::{dynamically_create_blockchain_agent_web3, send_payables_within_batch, BlockchainAgentFutureResult}; +use crate::blockchain::blockchain_interface::blockchain_interface_web3::utils::{dynamically_create_blockchain_agent_web3, send_payables_within_batch, BlockchainAgentFutureResult}; const CONTRACT_ABI: &str = indoc!( r#"[{ diff --git a/node/src/blockchain/blockchain_interface_utils.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/utils.rs similarity index 99% rename from node/src/blockchain/blockchain_interface_utils.rs rename to node/src/blockchain/blockchain_interface/blockchain_interface_web3/utils.rs index ad5e21da7..6db74bb91 100644 --- a/node/src/blockchain/blockchain_interface_utils.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/utils.rs @@ -1,8 +1,5 @@ // Copyright (c) 2024, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -// TODO: GH-744: At the end of the review rename this file to: web3_blockchain_interface_utils.rs -// Or we should move this file into blockchain_interface_web3 - use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::accountant::db_access_objects::pending_payable_dao::PendingPayable; use crate::accountant::scanners::mid_scan_msg_handling::payable_scanner::agent_web3::BlockchainAgentWeb3; diff --git a/node/src/blockchain/mod.rs b/node/src/blockchain/mod.rs index 20435b48b..4c51e726e 100644 --- a/node/src/blockchain/mod.rs +++ b/node/src/blockchain/mod.rs @@ -4,7 +4,6 @@ pub mod bip39; pub mod blockchain_bridge; pub mod blockchain_interface; pub mod blockchain_interface_initializer; -mod blockchain_interface_utils; pub mod payer; pub mod signature; #[cfg(test)] From 83dc7bcf1c21422572a4f57b41b4d67f97ec27ab Mon Sep 17 00:00:00 2001 From: Syther007 Date: Mon, 23 Dec 2024 20:54:07 +1300 Subject: [PATCH 51/56] GH-744: fixed test: dns_resolution_failure_for_wildcard_ip_with_real_nodes --- .../tests/communication_failure_test.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/multinode_integration_tests/tests/communication_failure_test.rs b/multinode_integration_tests/tests/communication_failure_test.rs index c5c70bbaf..5a1707a07 100644 --- a/multinode_integration_tests/tests/communication_failure_test.rs +++ b/multinode_integration_tests/tests/communication_failure_test.rs @@ -272,9 +272,7 @@ fn dns_resolution_failure_with_real_nodes() { ); } -// >>> TODO: GH-744: - Fix this test. #[test] -#[ignore] fn dns_resolution_failure_for_wildcard_ip_with_real_nodes() { let dns_server_that_fails = Ipv4Addr::new(1, 1, 1, 3).into(); let mut cluster = MASQNodeCluster::start().unwrap(); @@ -296,7 +294,7 @@ fn dns_resolution_failure_for_wildcard_ip_with_real_nodes() { thread::sleep(Duration::from_millis(1000)); let mut client = originating_node.make_client(8080, STANDARD_CLIENT_TIMEOUT_MILLIS); - client.send_chunk(b"GET / HTTP/1.1\r\nHost: www.xvideos.com\r\n\r\n"); + client.send_chunk(b"GET / HTTP/1.1\r\nHost: www.adomainthatdoesntexsit.com\r\n\r\n"); let response = client.wait_for_chunk(); assert_eq!( @@ -306,7 +304,7 @@ fn dns_resolution_failure_for_wildcard_ip_with_real_nodes() { String::from_utf8(response.clone()).unwrap() ); assert_eq!( - index_of(&response, &b"

DNS Failure, We have tried multiple Exit Nodes and all have failed to resolve this address www.xvideos.com

"[..]).is_some(), + index_of(&response, &b"

DNS Failure, We have tried multiple Exit Nodes and all have failed to resolve this address www.adomainthatdoesntexsit.com

"[..]).is_some(), true, "Actual response:\n{}", String::from_utf8(response).unwrap() From 91eefcf6b5c767ef40ecba4cbfb96cb7648e2455 Mon Sep 17 00:00:00 2001 From: utkarshg6 Date: Mon, 30 Dec 2024 19:09:43 +0530 Subject: [PATCH 52/56] GH-744: add review 4 changes --- node/src/accountant/mod.rs | 30 +++--- .../payable_scanner/agent_null.rs | 3 +- node/src/accountant/scanners/mod.rs | 96 ++++++++----------- .../src/accountant/scanners/scanners_utils.rs | 21 ++++ node/src/blockchain/blockchain_bridge.rs | 59 ++++++------ .../lower_level_interface_web3.rs | 96 ++++++++++++++++++- .../blockchain_interface_web3/mod.rs | 30 ++++-- 7 files changed, 221 insertions(+), 114 deletions(-) diff --git a/node/src/accountant/mod.rs b/node/src/accountant/mod.rs index 723bbfa56..a1510e8bd 100644 --- a/node/src/accountant/mod.rs +++ b/node/src/accountant/mod.rs @@ -1119,7 +1119,7 @@ mod tests { use std::sync::Mutex; use std::time::Duration; use std::vec; - use web3::types::TransactionReceipt; + use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{TransactionBlock, TxReceipt, TxStatus}; impl Handler> for Accountant { type Result = (); @@ -3799,11 +3799,13 @@ mod tests { .build(); let subject_addr = subject.start(); let transaction_hash_1 = make_tx_hash(4545); - let mut transaction_receipt_1 = TransactionReceipt::default(); - transaction_receipt_1.transaction_hash = transaction_hash_1; - transaction_receipt_1.status = Some(U64::from(1)); //success - transaction_receipt_1.block_number = Some(U64::from(100)); - transaction_receipt_1.block_hash = Some(Default::default()); + let transaction_receipt_1 = TxReceipt { + transaction_hash: transaction_hash_1, + status: TxStatus::Succeeded(TransactionBlock { + block_hash: Default::default(), + block_number: U64::from(100), + }), + }; let fingerprint_1 = PendingPayableFingerprint { rowid: 5, timestamp: from_time_t(200_000_000), @@ -3813,11 +3815,13 @@ mod tests { process_error: None, }; let transaction_hash_2 = make_tx_hash(3333333); - let mut transaction_receipt_2 = TransactionReceipt::default(); - transaction_receipt_2.transaction_hash = transaction_hash_2; - transaction_receipt_2.status = Some(U64::from(1)); //success - transaction_receipt_2.block_number = Some(U64::from(200)); - transaction_receipt_2.block_hash = Some(Default::default()); + let transaction_receipt_2 = TxReceipt { + transaction_hash: transaction_hash_2, + status: TxStatus::Succeeded(TransactionBlock { + block_hash: Default::default(), + block_number: U64::from(200), + }), + }; let fingerprint_2 = PendingPayableFingerprint { rowid: 10, timestamp: from_time_t(199_780_000), @@ -3829,11 +3833,11 @@ mod tests { let msg = ReportTransactionReceipts { fingerprints_with_receipts: vec![ ( - TransactionReceiptResult::RpcResponse(transaction_receipt_1.into()), + TransactionReceiptResult::RpcResponse(transaction_receipt_1), fingerprint_1.clone(), ), ( - TransactionReceiptResult::RpcResponse(transaction_receipt_2.into()), + TransactionReceiptResult::RpcResponse(transaction_receipt_2), fingerprint_2.clone(), ), ], diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs index 92f53e805..e95673002 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/agent_null.rs @@ -85,8 +85,8 @@ mod tests { use masq_lib::logger::Logger; use masq_lib::test_utils::logging::{init_test_logging, TestLogHandler}; - use web3::types::U256; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; + use web3::types::U256; fn blockchain_agent_null_constructor_works(constructor: C) where @@ -192,5 +192,4 @@ mod tests { assert_eq!(result, TEST_DEFAULT_CHAIN); assert_error_log(test_name, "get_chain") } - } diff --git a/node/src/accountant/scanners/mod.rs b/node/src/accountant/scanners/mod.rs index fbf640d9a..572d36400 100644 --- a/node/src/accountant/scanners/mod.rs +++ b/node/src/accountant/scanners/mod.rs @@ -17,10 +17,7 @@ use crate::accountant::scanners::scanners_utils::payable_scanner_utils::{ separate_errors, separate_rowids_and_hashes, PayableThresholdsGauge, PayableThresholdsGaugeReal, PayableTransactingErrorEnum, PendingPayableMetadata, }; -use crate::accountant::scanners::scanners_utils::pending_payable_scanner_utils::{ - elapsed_in_ms, handle_status_with_failure, handle_status_with_success, - PendingPayableScanReport, -}; +use crate::accountant::scanners::scanners_utils::pending_payable_scanner_utils::{handle_none_receipt, handle_status_with_failure, handle_status_with_success, PendingPayableScanReport}; use crate::accountant::scanners::scanners_utils::receivable_scanner_utils::balance_and_age; use crate::accountant::PendingPayableId; use crate::accountant::{ @@ -654,49 +651,28 @@ impl PendingPayableScanner { msg: ReportTransactionReceipts, logger: &Logger, ) -> PendingPayableScanReport { - fn handle_none_receipt( - mut scan_report: PendingPayableScanReport, - payable: PendingPayableFingerprint, - error_msg: String, - logger: &Logger, - ) -> PendingPayableScanReport { - debug!(logger, - "Interpreting a receipt for transaction {:?} but {}; attempt {}, {}ms since sending", - payable.hash, error_msg, payable.attempt,elapsed_in_ms(payable.timestamp) - ); - - scan_report - .still_pending - .push(PendingPayableId::new(payable.rowid, payable.hash)); - scan_report - } - let scan_report = PendingPayableScanReport::default(); msg.fingerprints_with_receipts.into_iter().fold( scan_report, |scan_report_so_far, (receipt_result, fingerprint)| match receipt_result { - TransactionReceiptResult::RpcResponse(tx_receipt) => { - match tx_receipt.status { - TxStatus::Pending => { - handle_none_receipt( - scan_report_so_far, - fingerprint, - "none was given".to_string(), - logger, - ) - } - TxStatus::Failed => { - handle_status_with_failure(scan_report_so_far, fingerprint, logger) - } - TxStatus::Succeeded(_) => { - handle_status_with_success(scan_report_so_far, fingerprint, logger) - } + TransactionReceiptResult::RpcResponse(tx_receipt) => match tx_receipt.status { + TxStatus::Pending => handle_none_receipt( + scan_report_so_far, + fingerprint, + "none was given", + logger, + ), + TxStatus::Failed => { + handle_status_with_failure(scan_report_so_far, fingerprint, logger) } - } + TxStatus::Succeeded(_) => { + handle_status_with_success(scan_report_so_far, fingerprint, logger) + } + }, TransactionReceiptResult::LocalError(e) => handle_none_receipt( scan_report_so_far, fingerprint, - format!("failed due to {}", e), + &format!("failed due to {}", e), logger, ), }, @@ -891,10 +867,10 @@ impl ReceivableScanner { ), } } else { - let mut txn = self - .receivable_dao - .as_mut() - .more_money_received(received_payments_msg.timestamp, &received_payments_msg.transactions); + let mut txn = self.receivable_dao.as_mut().more_money_received( + received_payments_msg.timestamp, + &received_payments_msg.transactions, + ); let new_start_block = received_payments_msg.new_start_block; match self .persistent_configuration @@ -1139,7 +1115,7 @@ mod tests { use std::time::{Duration, SystemTime}; use web3::types::{TransactionReceipt, H256}; use web3::Error; - use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{TransactionReceiptResult, TxReceipt, TxStatus}; + use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{TransactionBlock, TransactionReceiptResult, TxReceipt, TxStatus}; #[test] fn scanners_struct_can_be_constructed_with_the_respective_scanners() { @@ -2504,9 +2480,9 @@ mod tests { }; let msg = ReportTransactionReceipts { fingerprints_with_receipts: vec![( - TransactionReceiptResult::RpcResponse(TxReceipt{ + TransactionReceiptResult::RpcResponse(TxReceipt { transaction_hash: hash, - status: TxStatus::Pending + status: TxStatus::Pending, }), fingerprint.clone(), )], @@ -2827,11 +2803,13 @@ mod tests { .pending_payable_dao(pending_payable_dao) .build(); let transaction_hash_1 = make_tx_hash(4545); - let mut transaction_receipt_1 = TransactionReceipt::default(); - transaction_receipt_1.transaction_hash = transaction_hash_1; - transaction_receipt_1.status = Some(U64::from(1)); //success - transaction_receipt_1.block_number = Some(U64::from(1234)); - transaction_receipt_1.block_hash = Some(Default::default()); + let transaction_receipt_1 = TxReceipt { + transaction_hash: transaction_hash_1, + status: TxStatus::Succeeded(TransactionBlock { + block_hash: Default::default(), + block_number: U64::from(1234), + }), + }; let fingerprint_1 = PendingPayableFingerprint { rowid: 5, timestamp: from_time_t(200_000_000), @@ -2841,11 +2819,13 @@ mod tests { process_error: None, }; let transaction_hash_2 = make_tx_hash(1234); - let mut transaction_receipt_2 = TransactionReceipt::default(); - transaction_receipt_2.transaction_hash = transaction_hash_2; - transaction_receipt_2.status = Some(U64::from(1)); //success - transaction_receipt_2.block_number = Some(U64::from(2345)); - transaction_receipt_2.block_hash = Some(Default::default()); + let transaction_receipt_2 = TxReceipt { + transaction_hash: transaction_hash_2, + status: TxStatus::Succeeded(TransactionBlock { + block_hash: Default::default(), + block_number: U64::from(2345), + }), + }; let fingerprint_2 = PendingPayableFingerprint { rowid: 10, timestamp: from_time_t(199_780_000), @@ -2857,11 +2837,11 @@ mod tests { let msg = ReportTransactionReceipts { fingerprints_with_receipts: vec![ ( - TransactionReceiptResult::RpcResponse(transaction_receipt_1.into()), + TransactionReceiptResult::RpcResponse(transaction_receipt_1), fingerprint_1.clone(), ), ( - TransactionReceiptResult::RpcResponse(transaction_receipt_2.into()), + TransactionReceiptResult::RpcResponse(transaction_receipt_2), fingerprint_2.clone(), ), ], diff --git a/node/src/accountant/scanners/scanners_utils.rs b/node/src/accountant/scanners/scanners_utils.rs index 1876ca58d..30b3a3d2d 100644 --- a/node/src/accountant/scanners/scanners_utils.rs +++ b/node/src/accountant/scanners/scanners_utils.rs @@ -400,6 +400,27 @@ pub mod pending_payable_scanner_utils { scan_report.failures.push(fingerprint.into()); scan_report } + + pub fn handle_none_receipt( + mut scan_report: PendingPayableScanReport, + payable: PendingPayableFingerprint, + error_msg: &str, + logger: &Logger, + ) -> PendingPayableScanReport { + debug!( + logger, + "Interpreting a receipt for transaction {:?} but {}; attempt {}, {}ms since sending", + payable.hash, + error_msg, + payable.attempt, + elapsed_in_ms(payable.timestamp) + ); + + scan_report + .still_pending + .push(PendingPayableId::new(payable.rowid, payable.hash)); + scan_report + } } pub mod receivable_scanner_utils { diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 68e690704..35d0b3144 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -366,7 +366,8 @@ impl BlockchainBridge { format!("Error while retrieving transactions: {:?}", e) }) .and_then(move |retrieved_blockchain_transactions| { - received_payments_subs.try_send(ReceivedPayments { + received_payments_subs + .try_send(ReceivedPayments { timestamp: SystemTime::now(), new_start_block: retrieved_blockchain_transactions.new_start_block, response_skeleton_opt: msg.response_skeleton_opt, @@ -400,33 +401,32 @@ impl BlockchainBridge { .process_transaction_receipts(transaction_hashes) .map_err(move |e| e.to_string()) .and_then(move |transaction_receipts_results| { - let length = transaction_receipts_results.len(); - let mut transactions_found = 0; - for transaction_receipt in &transaction_receipts_results { - if let TransactionReceiptResult::RpcResponse(tx_receipt) = transaction_receipt { - if let TxStatus::Succeeded(_) = tx_receipt.status { - transactions_found += 1; + let (successful_count, failed_count, pending_count) = transaction_receipts_results + .iter() + .fold((0, 0, 0), |(success, fail, pending), transaction_receipt| { + match transaction_receipt { + TransactionReceiptResult::RpcResponse(tx_receipt) => match tx_receipt.status { + TxStatus::Failed => (success, fail + 1, pending), + TxStatus::Pending => (success, fail, pending + 1), + TxStatus::Succeeded(_) => (success + 1, fail, pending), + }, + TransactionReceiptResult::LocalError(_)=> (success, fail, pending + 1), } - } - } + }); + debug!(logger, "Scan results: Successful: {successful_count}, Pending: {pending_count}, Failed: {failed_count}"); + let pairs = transaction_receipts_results .into_iter() .zip(msg.pending_payable.into_iter()) .collect_vec(); + accountant_recipient .try_send(ReportTransactionReceipts { fingerprints_with_receipts: pairs, response_skeleton_opt: msg.response_skeleton_opt, }) .expect("Accountant is dead"); - if length != transactions_found { - debug!( - logger, - "Aborting scanning; {} transactions succeed and {} transactions failed", - transactions_found, - length - transactions_found - ); - }; + Ok(()) }), ) @@ -583,7 +583,7 @@ mod tests { use std::sync::{Arc, Mutex}; use std::time::{Duration, SystemTime}; use web3::types::{TransactionReceipt, H160}; - use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::TxReceipt; + use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{TransactionBlock, TxReceipt}; impl Handler> for BlockchainBridge { type Result = (); @@ -1198,9 +1198,10 @@ mod tests { pending_payable_fingerprint_1 ), ( - TransactionReceiptResult::RpcResponse(TxReceipt{ + TransactionReceiptResult::RpcResponse(TxReceipt { transaction_hash: hash_2, - status: TxStatus::Pending }), + status: TxStatus::Pending + }), pending_payable_fingerprint_2 ), ], @@ -1326,11 +1327,13 @@ mod tests { amount: 7879, process_error: None, }; - let mut transaction_receipt = TransactionReceipt::default(); - transaction_receipt.block_number = Some(block_number); - transaction_receipt.block_hash = Some(Default::default()); - transaction_receipt.contract_address = Some(contract_address); - transaction_receipt.status = Some(U64::from(1)); + let transaction_receipt = TxReceipt { + transaction_hash: Default::default(), + status: TxStatus::Succeeded(TransactionBlock { + block_hash: Default::default(), + block_number, + }), + }; let blockchain_interface = make_blockchain_interface_web3(port); let system = System::new("test_transaction_receipts"); let mut subject = BlockchainBridge::new( @@ -1367,7 +1370,7 @@ mod tests { ReportTransactionReceipts { fingerprints_with_receipts: vec![ (TransactionReceiptResult::RpcResponse(TxReceipt{ transaction_hash: hash_1, status: TxStatus::Pending }), fingerprint_1), - (TransactionReceiptResult::RpcResponse(transaction_receipt.into()), fingerprint_2), + (TransactionReceiptResult::RpcResponse(transaction_receipt), fingerprint_2), (TransactionReceiptResult::RpcResponse(TxReceipt{ transaction_hash: hash_3, status: TxStatus::Pending }), fingerprint_3), (TransactionReceiptResult::LocalError("RPC error: Error { code: ServerError(429), message: \"The requests per second (RPS) of your requests are higher than your plan allows.\", data: None }".to_string()), fingerprint_4) ], @@ -1377,7 +1380,9 @@ mod tests { }), } ); - TestLogHandler::new().exists_log_containing("DEBUG: BlockchainBridge: Aborting scanning; 1 transactions succeed and 3 transactions failed"); + TestLogHandler::new().exists_log_containing( + "DEBUG: BlockchainBridge: Scan results: Successful: 1, Pending: 3, Failed: 0", + ); } #[test] diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs index def0cf053..58a8865eb 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/lower_level_interface_web3.rs @@ -34,7 +34,7 @@ pub struct TxReceipt { #[derive(Debug, PartialEq, Eq, Clone)] pub struct TransactionBlock { pub block_hash: H256, - pub block_number: U64 + pub block_number: U64, } impl From for TxReceipt { @@ -57,8 +57,6 @@ impl From for TxReceipt { } } - - pub struct LowBlockchainIntWeb3 { web3: Web3, web3_batch: Web3>, @@ -184,7 +182,8 @@ mod tests { use masq_lib::test_utils::mock_blockchain_client_server::MBCSBuilder; use masq_lib::utils::find_free_port; use std::str::FromStr; - use web3::types::{BlockNumber, Bytes, FilterBuilder, Log, U256}; + use web3::types::{BlockNumber, Bytes, FilterBuilder, Log, TransactionReceipt, U256}; + use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{TxReceipt, TxStatus}; #[test] fn get_transaction_fee_balance_works() { @@ -544,4 +543,93 @@ mod tests { ) ); } + + #[test] + fn transaction_receipt_can_be_converted_to_successful_transaction() { + let tx_receipt: TxReceipt = create_tx_receipt( + Some(U64::from(1)), + Some(H256::from_low_u64_be(0x1234)), + Some(U64::from(10)), + H256::from_low_u64_be(0x5678), + ); + + assert_eq!(tx_receipt.transaction_hash, H256::from_low_u64_be(0x5678)); + match tx_receipt.status { + TxStatus::Succeeded(ref block) => { + assert_eq!(block.block_hash, H256::from_low_u64_be(0x1234)); + assert_eq!(block.block_number, U64::from(10)); + } + _ => panic!("Expected status to be Succeeded"), + } + } + + #[test] + fn transaction_receipt_can_be_converted_to_failed_transaction() { + let tx_receipt: TxReceipt = create_tx_receipt( + Some(U64::from(0)), + None, + None, + H256::from_low_u64_be(0x5678), + ); + + assert_eq!(tx_receipt.transaction_hash, H256::from_low_u64_be(0x5678)); + assert_eq!(tx_receipt.status, TxStatus::Failed); + } + + #[test] + fn transaction_receipt_can_be_converted_to_pending_transaction_no_status() { + let tx_receipt: TxReceipt = + create_tx_receipt(None, None, None, H256::from_low_u64_be(0x5678)); + + assert_eq!(tx_receipt.transaction_hash, H256::from_low_u64_be(0x5678)); + assert_eq!(tx_receipt.status, TxStatus::Pending); + } + + #[test] + fn transaction_receipt_can_be_converted_to_pending_transaction_no_block_info() { + let tx_receipt: TxReceipt = create_tx_receipt( + Some(U64::from(1)), + None, + None, + H256::from_low_u64_be(0x5678), + ); + + assert_eq!(tx_receipt.transaction_hash, H256::from_low_u64_be(0x5678)); + assert_eq!(tx_receipt.status, TxStatus::Pending); + } + + #[test] + fn transaction_receipt_can_be_converted_to_pending_transaction_no_status_and_block_info() { + let tx_receipt: TxReceipt = create_tx_receipt( + Some(U64::from(1)), + Some(H256::from_low_u64_be(0x1234)), + None, + H256::from_low_u64_be(0x5678), + ); + + assert_eq!(tx_receipt.transaction_hash, H256::from_low_u64_be(0x5678)); + assert_eq!(tx_receipt.status, TxStatus::Pending); + } + + fn create_tx_receipt( + status: Option, + block_hash: Option, + block_number: Option, + transaction_hash: H256, + ) -> TxReceipt { + let receipt = TransactionReceipt { + status, + root: None, + block_hash, + block_number, + cumulative_gas_used: Default::default(), + gas_used: None, + contract_address: None, + transaction_hash, + transaction_index: Default::default(), + logs: vec![], + logs_bloom: Default::default(), + }; + receipt.into() + } } diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index 3d03dc446..ae7c17128 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -213,12 +213,14 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { .map(|(response, hash)| match response { Ok(result) => { match serde_json::from_value::(result) { - Ok(receipt) => TransactionReceiptResult::RpcResponse(receipt.into()), + Ok(receipt) => { + TransactionReceiptResult::RpcResponse(receipt.into()) + } Err(e) => { if e.to_string().contains("invalid type: null") { - TransactionReceiptResult::RpcResponse(TxReceipt{ + TransactionReceiptResult::RpcResponse(TxReceipt { transaction_hash: hash, - status: TxStatus::Pending + status: TxStatus::Pending, }) } else { TransactionReceiptResult::LocalError(e.to_string()) @@ -571,11 +573,7 @@ mod tests { let end_block_nbr = 1024u64; let result = subject - .retrieve_transactions( - 42u64, - end_block_nbr, - to_wallet.address(), - ) + .retrieve_transactions(42u64, end_block_nbr, to_wallet.address()) .wait(); assert_eq!( @@ -929,14 +927,26 @@ mod tests { .unwrap(); assert_eq!(result[0], TransactionReceiptResult::LocalError("RPC error: Error { code: ServerError(429), message: \"The requests per second (RPS) of your requests are higher than your plan allows.\", data: None }".to_string())); - assert_eq!(result[1], TransactionReceiptResult::RpcResponse(TxReceipt{ transaction_hash: tx_hash_2, status: TxStatus::Pending })); + assert_eq!( + result[1], + TransactionReceiptResult::RpcResponse(TxReceipt { + transaction_hash: tx_hash_2, + status: TxStatus::Pending + }) + ); assert_eq!( result[2], TransactionReceiptResult::LocalError( "invalid type: string \"trash\", expected struct Receipt".to_string() ) ); - assert_eq!(result[3], TransactionReceiptResult::RpcResponse(TxReceipt{ transaction_hash: tx_hash_4, status: TxStatus::Pending })); + assert_eq!( + result[3], + TransactionReceiptResult::RpcResponse(TxReceipt { + transaction_hash: tx_hash_4, + status: TxStatus::Pending + }) + ); assert_eq!( result[4], TransactionReceiptResult::RpcResponse(TxReceipt { From f4b81508ce5a708b2bbc8ea49835e255f4f73859 Mon Sep 17 00:00:00 2001 From: utkarshg6 Date: Tue, 31 Dec 2024 19:50:39 +0530 Subject: [PATCH 53/56] GH-744: add review 5 changes --- node/src/blockchain/blockchain_bridge.rs | 39 ++++++++++++++++-------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index 35d0b3144..c2791eafc 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -399,21 +399,34 @@ impl BlockchainBridge { Box::new( self.blockchain_interface .process_transaction_receipts(transaction_hashes) - .map_err(move |e| e.to_string()) + .map_err(|e| e.to_string()) .and_then(move |transaction_receipts_results| { - let (successful_count, failed_count, pending_count) = transaction_receipts_results - .iter() - .fold((0, 0, 0), |(success, fail, pending), transaction_receipt| { - match transaction_receipt { - TransactionReceiptResult::RpcResponse(tx_receipt) => match tx_receipt.status { - TxStatus::Failed => (success, fail + 1, pending), - TxStatus::Pending => (success, fail, pending + 1), - TxStatus::Succeeded(_) => (success + 1, fail, pending), + logger.debug(|| { + let (successful_count, failed_count, pending_count) = + transaction_receipts_results.iter().fold( + (0, 0, 0), + |(success, fail, pending), transaction_receipt| { + match transaction_receipt { + TransactionReceiptResult::RpcResponse(tx_receipt) => { + match tx_receipt.status { + TxStatus::Failed => (success, fail + 1, pending), + TxStatus::Pending => (success, fail, pending + 1), + TxStatus::Succeeded(_) => { + (success + 1, fail, pending) + } + } + } + TransactionReceiptResult::LocalError(_) => { + (success, fail, pending + 1) + } + } }, - TransactionReceiptResult::LocalError(_)=> (success, fail, pending + 1), - } - }); - debug!(logger, "Scan results: Successful: {successful_count}, Pending: {pending_count}, Failed: {failed_count}"); + ); + format!( + "Scan results: Successful: {}, Pending: {}, Failed: {}", + successful_count, pending_count, failed_count + ) + }); let pairs = transaction_receipts_results .into_iter() From 64f2f406c0e0232bfb5318c7853148508f8c7ce1 Mon Sep 17 00:00:00 2001 From: utkarshg6 Date: Thu, 2 Jan 2025 13:52:07 +0530 Subject: [PATCH 54/56] GH-744: remove the map_err() --- node/src/blockchain/blockchain_bridge.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index c2791eafc..d80ec1f00 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -399,7 +399,6 @@ impl BlockchainBridge { Box::new( self.blockchain_interface .process_transaction_receipts(transaction_hashes) - .map_err(|e| e.to_string()) .and_then(move |transaction_receipts_results| { logger.debug(|| { let (successful_count, failed_count, pending_count) = From a047291ec45990bb5811da47b068962588e36150 Mon Sep 17 00:00:00 2001 From: utkarshg6 Date: Thu, 2 Jan 2025 21:05:12 +0530 Subject: [PATCH 55/56] GH-744: migrate the logging code to a different function --- node/src/blockchain/blockchain_bridge.rs | 54 ++++++++++--------- .../blockchain_interface_web3/mod.rs | 1 - 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index d80ec1f00..a542fcc0f 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -379,6 +379,32 @@ impl BlockchainBridge { ) } + fn log_status_of_tx_receipts( + logger: &Logger, + transaction_receipts_results: &[TransactionReceiptResult], + ) { + logger.debug(|| { + let (successful_count, failed_count, pending_count) = + transaction_receipts_results.iter().fold( + (0, 0, 0), + |(success, fail, pending), transaction_receipt| match transaction_receipt { + TransactionReceiptResult::RpcResponse(tx_receipt) => { + match tx_receipt.status { + TxStatus::Failed => (success, fail + 1, pending), + TxStatus::Pending => (success, fail, pending + 1), + TxStatus::Succeeded(_) => (success + 1, fail, pending), + } + } + TransactionReceiptResult::LocalError(_) => (success, fail, pending + 1), + }, + ); + format!( + "Scan results: Successful: {}, Pending: {}, Failed: {}", + successful_count, pending_count, failed_count + ) + }); + } + fn handle_request_transaction_receipts( &mut self, msg: RequestTransactionReceipts, @@ -399,33 +425,9 @@ impl BlockchainBridge { Box::new( self.blockchain_interface .process_transaction_receipts(transaction_hashes) + .map_err(move |e| e.to_string()) .and_then(move |transaction_receipts_results| { - logger.debug(|| { - let (successful_count, failed_count, pending_count) = - transaction_receipts_results.iter().fold( - (0, 0, 0), - |(success, fail, pending), transaction_receipt| { - match transaction_receipt { - TransactionReceiptResult::RpcResponse(tx_receipt) => { - match tx_receipt.status { - TxStatus::Failed => (success, fail + 1, pending), - TxStatus::Pending => (success, fail, pending + 1), - TxStatus::Succeeded(_) => { - (success + 1, fail, pending) - } - } - } - TransactionReceiptResult::LocalError(_) => { - (success, fail, pending + 1) - } - } - }, - ); - format!( - "Scan results: Successful: {}, Pending: {}, Failed: {}", - successful_count, pending_count, failed_count - ) - }); + Self::log_status_of_tx_receipts(&logger, &transaction_receipts_results); let pairs = transaction_receipts_results .into_iter() diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index ae7c17128..be022e46b 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -205,7 +205,6 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { Box::new( self.lower_interface() .get_transaction_receipt_in_batch(transaction_hashes.clone()) - .map_err(|e| e) .and_then(move |batch_response| { Ok(batch_response .into_iter() From d07760bfd873dfdafe7301e14db86364eb92f7a8 Mon Sep 17 00:00:00 2001 From: utkarshg6 Date: Mon, 6 Jan 2025 14:03:05 +0530 Subject: [PATCH 56/56] GH-744: add review 6 changes --- .../tests/communication_failure_test.rs | 2 +- .../payable_scanner/test_utils.rs | 3 +- node/src/blockchain/blockchain_bridge.rs | 3 +- .../blockchain_interface_web3/mod.rs | 40 +------------------ .../blockchain_interface_web3/utils.rs | 14 +++---- 5 files changed, 13 insertions(+), 49 deletions(-) diff --git a/multinode_integration_tests/tests/communication_failure_test.rs b/multinode_integration_tests/tests/communication_failure_test.rs index 5a1707a07..b123d30cc 100644 --- a/multinode_integration_tests/tests/communication_failure_test.rs +++ b/multinode_integration_tests/tests/communication_failure_test.rs @@ -294,7 +294,7 @@ fn dns_resolution_failure_for_wildcard_ip_with_real_nodes() { thread::sleep(Duration::from_millis(1000)); let mut client = originating_node.make_client(8080, STANDARD_CLIENT_TIMEOUT_MILLIS); - client.send_chunk(b"GET / HTTP/1.1\r\nHost: www.adomainthatdoesntexsit.com\r\n\r\n"); + client.send_chunk(b"GET / HTTP/1.1\r\nHost: www.adomainthatdoesntexist.com\r\n\r\n"); let response = client.wait_for_chunk(); assert_eq!( diff --git a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs index 836bb1d10..d3ab97284 100644 --- a/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs +++ b/node/src/accountant/scanners/mid_scan_msg_handling/payable_scanner/test_utils.rs @@ -8,7 +8,6 @@ use crate::sub_lib::wallet::Wallet; use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp; use crate::{arbitrary_id_stamp_in_trait_impl, set_arbitrary_id_stamp_in_mock_impl}; use masq_lib::blockchains::chains::Chain; -use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use std::cell::RefCell; pub struct BlockchainAgentMock { @@ -26,7 +25,7 @@ impl Default for BlockchainAgentMock { agreed_fee_per_computation_unit_results: RefCell::new(vec![]), consuming_wallet_result_opt: None, arbitrary_id_stamp_opt: None, - get_chain_result_opt: Some(TEST_DEFAULT_CHAIN), + get_chain_result_opt: None, } } } diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index a542fcc0f..b204d9ccf 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -346,7 +346,7 @@ impl BlockchainBridge { { match persistent_config_arc .lock() - .expect("Unable to lock persistent config in BlockchainBridge") + .expect("Mutex with persistent configuration in BlockchainBridge was poisoned") .set_max_block_count(Some(max_block_count)) { Ok(()) => { @@ -1100,6 +1100,7 @@ mod tests { let consuming_wallet = make_paying_wallet(b"consuming_wallet"); let system = System::new(test_name); let agent = BlockchainAgentMock::default() + .get_chain_result(TEST_DEFAULT_CHAIN) .consuming_wallet_result(consuming_wallet) .agreed_fee_per_computation_unit_result(123); let msg = OutboundPaymentsInstructions::new(vec![], Box::new(agent), None); diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs index be022e46b..bea78e155 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/mod.rs @@ -23,7 +23,7 @@ use web3::types::{Address, BlockNumber, Log, H256, U256, FilterBuilder, Transact use crate::accountant::db_access_objects::payable_dao::PayableAccount; use crate::blockchain::blockchain_bridge::PendingPayableFingerprintSeeds; use crate::blockchain::blockchain_interface::blockchain_interface_web3::lower_level_interface_web3::{LowBlockchainIntWeb3, TransactionReceiptResult, TxReceipt, TxStatus}; -use crate::blockchain::blockchain_interface::blockchain_interface_web3::utils::{dynamically_create_blockchain_agent_web3, send_payables_within_batch, BlockchainAgentFutureResult}; +use crate::blockchain::blockchain_interface::blockchain_interface_web3::utils::{create_blockchain_agent_web3, send_payables_within_batch, BlockchainAgentFutureResult}; const CONTRACT_ABI: &str = indoc!( r#"[{ @@ -186,7 +186,7 @@ impl BlockchainInterface for BlockchainInterfaceWeb3 { transaction_fee_balance, masq_token_balance, }; - Ok(dynamically_create_blockchain_agent_web3( + Ok(create_blockchain_agent_web3( gas_limit_const_part, blockchain_agent_future_result, consuming_wallet, @@ -539,24 +539,6 @@ mod tests { ] } ) - - // TODO: GH-543: Improve MBCS so we can confirm the calls we make are the correct ones. - // Example of older code - // let requests = test_server.requests_so_far(); - // let bodies: Vec = requests - // .into_iter() - // .map(|request| serde_json::from_slice(&request.body()).unwrap()) - // .map(|b: Value| serde_json::to_string(&b).unwrap()) - // .collect(); - // let expected_body_prefix = r#"[{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber","params":[]},{"id":1,"jsonrpc":"2.0","method":"eth_getLogs","params":[{"address":"0x384dec25e03f94931767ce4c3556168468ba24c3","fromBlock":"0x2a","toBlock":"0x400","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",null,"0x000000000000000000000000"#; - // let expected_body_suffix = r#""]}]}]"#; - // let expected_body = format!( - // "{}{}{}", - // expected_body_prefix, - // &to[2..], - // expected_body_suffix - // ); - // assert_eq!(bodies, vec!(expected_body)); } #[test] @@ -582,24 +564,6 @@ mod tests { transactions: vec![] }) ); - - // TODO: GH-543: Improve MBCS so we can confirm the calls we make are the correct ones. - // Example of older code - // let requests = test_server.requests_so_far(); - // let bodies: Vec = requests - // .into_iter() - // .map(|request| serde_json::from_slice(&request.body()).unwrap()) - // .map(|b: Value| serde_json::to_string(&b).unwrap()) - // .collect(); - // let expected_body_prefix = r#"[{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber","params":[]},{"id":1,"jsonrpc":"2.0","method":"eth_getLogs","params":[{"address":"0x384dec25e03f94931767ce4c3556168468ba24c3","fromBlock":"0x2a","toBlock":"0x400","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",null,"0x000000000000000000000000"#; - // let expected_body_suffix = r#""]}]}]"#; - // let expected_body = format!( - // "{}{}{}", - // expected_body_prefix, - // &to[2..], - // expected_body_suffix - // ); - // assert_eq!(bodies, vec!(expected_body)); } #[test] diff --git a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/utils.rs b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/utils.rs index 6db74bb91..2be7d5977 100644 --- a/node/src/blockchain/blockchain_interface/blockchain_interface_web3/utils.rs +++ b/node/src/blockchain/blockchain_interface/blockchain_interface_web3/utils.rs @@ -308,7 +308,7 @@ pub fn send_payables_within_batch( ) } -pub fn dynamically_create_blockchain_agent_web3( +pub fn create_blockchain_agent_web3( gas_limit_const_part: u128, blockchain_agent_future_result: BlockchainAgentFutureResult, wallet: Wallet, @@ -387,7 +387,7 @@ mod tests { .unwrap(); let pending_nonce = 1; let chain = DEFAULT_CHAIN; - let gas_price = DEFAULT_GAS_PRICE; + let gas_price_in_gwei = DEFAULT_GAS_PRICE; let consuming_wallet = make_paying_wallet(b"paying_wallet"); let account = make_payable_account(1); let web3_batch = Web3::new(Batch::new(transport)); @@ -398,7 +398,7 @@ mod tests { &account, consuming_wallet, pending_nonce.into(), - (gas_price * 1_000_000_000) as u128, + gwei_to_wei(gas_price_in_gwei), ); let mut batch_result = web3_batch.eth().transport().submit_batch().wait().unwrap(); @@ -431,7 +431,7 @@ mod tests { .unwrap(); let web3_batch = Web3::new(Batch::new(transport)); let chain = DEFAULT_CHAIN; - let gas_price = DEFAULT_GAS_PRICE; + let gas_price_in_gwei = DEFAULT_GAS_PRICE; let pending_nonce = 1; let consuming_wallet = make_paying_wallet(b"paying_wallet"); let account_1 = make_payable_account(1); @@ -443,7 +443,7 @@ mod tests { chain, &web3_batch, consuming_wallet, - (gas_price * 1_000_000_000) as u128, + gwei_to_wei(gas_price_in_gwei), pending_nonce.into(), &accounts, ); @@ -1012,7 +1012,7 @@ mod tests { Wallet::from(address) }; let nonce_correct_type = U256::from(nonce); - let gas_price = match chain { + let gas_price_in_gwei = match chain { Chain::EthMainnet => TEST_GAS_PRICE_ETH, Chain::EthRopsten => TEST_GAS_PRICE_ETH, Chain::PolyMainnet => TEST_GAS_PRICE_POLYGON, @@ -1032,7 +1032,7 @@ mod tests { consuming_wallet, payable_account.balance_wei, nonce_correct_type, - (gas_price * 1_000_000_000) as u128, + gwei_to_wei(gas_price_in_gwei), ); let byte_set_to_compare = signed_transaction.raw_transaction.0;