diff --git a/node/src/components/transaction_acceptor/tests.rs b/node/src/components/transaction_acceptor/tests.rs index 9c92db6f52..dc795bedd0 100644 --- a/node/src/components/transaction_acceptor/tests.rs +++ b/node/src/components/transaction_acceptor/tests.rs @@ -36,9 +36,9 @@ use casper_types::{ global_state::TrieMerkleProof, testing::TestRng, Block, BlockV2, CLValue, Chainspec, ChainspecRawBytes, Contract, Deploy, EraId, HashAddr, - InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, PricingMode, ProtocolVersion, - PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, Transaction, - TransactionConfig, TransactionRuntime, TransactionV1, URef, U512, + InvalidDeploy, InvalidTransaction, InvalidTransactionV1, Package, PricingHandling, PricingMode, + ProtocolVersion, PublicKey, SecretKey, StoredValue, TestBlockBuilder, TimeDiff, Timestamp, + Transaction, TransactionConfig, TransactionRuntime, TransactionV1, URef, U512, }; use super::*; @@ -595,10 +595,9 @@ impl TestScenario { } TestScenario::InvalidPricingModeForTransactionV1 => { let classic_mode_transaction = TransactionV1Builder::new_random(rng) - .with_pricing_mode(PricingMode::PaymentLimited { - payment_amount: 10000u64, - gas_price_tolerance: 1u8, - standard_payment: true, + .with_pricing_mode(PricingMode::Fixed { + gas_price_tolerance: 5, + additional_computation_factor: 0, }) .with_chain_name("casper-example") .build() @@ -1152,6 +1151,14 @@ async fn run_transaction_acceptor_without_timeout( let admin = SecretKey::random(rng); let (mut chainspec, chainspec_raw_bytes) = <(Chainspec, ChainspecRawBytes)>::from_resources("local"); + let mut chainspec = if let TestScenario::TooLowGasPriceToleranceForTransactionV1 = test_scenario + { + chainspec.with_pricing_handling(PricingHandling::Fixed); + chainspec + } else { + chainspec + }; + chainspec.core_config.administrators = iter::once(PublicKey::from(&admin)).collect(); let chainspec = Arc::new(chainspec); diff --git a/node/src/reactor/main_reactor/tests/transactions.rs b/node/src/reactor/main_reactor/tests/transactions.rs index b3f28589c2..b60d7ac3db 100644 --- a/node/src/reactor/main_reactor/tests/transactions.rs +++ b/node/src/reactor/main_reactor/tests/transactions.rs @@ -32,7 +32,7 @@ static CHARLIE_SECRET_KEY: Lazy> = Lazy::new(|| { static CHARLIE_PUBLIC_KEY: Lazy = Lazy::new(|| PublicKey::from(&*CHARLIE_SECRET_KEY.clone())); -const MIN_GAS_PRICE: u8 = 5; +const MIN_GAS_PRICE: u8 = 1; const CHAIN_NAME: &str = "single-transaction-test-net"; async fn transfer_to_account>( @@ -1023,8 +1023,6 @@ impl SingleTransactionTestCase { ConfigsOverride::default() .with_minimum_era_height(5) // make the era longer so that the transaction doesn't land in the switch block. .with_balance_hold_interval(TimeDiff::from_seconds(5)) - .with_min_gas_price(MIN_GAS_PRICE) - .with_max_gas_price(MIN_GAS_PRICE) .with_chain_name("single-transaction-test-net".to_string()) } @@ -3045,25 +3043,27 @@ async fn insufficient_funds_transfer_from_account() { let transfer_amount = U512::max_value(); - let mut txn = Transaction::from( + let txn_v1 = TransactionV1Builder::new_transfer(transfer_amount, None, ALICE_PUBLIC_KEY.clone(), None) .unwrap() .with_chain_name(CHAIN_NAME) .with_initiator_addr(PublicKey::from(&**BOB_SECRET_KEY)) .build() - .unwrap(), - ); + .unwrap(); + let price = txn_v1 + .payment_amount() + .expect("must have payment amount as txns are using classic"); + let mut txn = Transaction::from(txn_v1); txn.sign(&BOB_SECRET_KEY); let (_txn_hash, _block_height, exec_result) = test.send_transaction(txn).await; let ExecutionResult::V2(result) = exec_result else { panic!("Expected ExecutionResult::V2 but got {:?}", exec_result); }; - let transfer_cost: U512 = - U512::from(test.chainspec().system_costs_config.mint_costs().transfer) * MIN_GAS_PRICE; + let expected_cost: U512 = U512::from(price) * MIN_GAS_PRICE; assert_eq!(result.error_message.as_deref(), Some("Insufficient funds")); - assert_eq!(result.cost, transfer_cost); + assert_eq!(result.cost, expected_cost); } #[tokio::test] @@ -3089,22 +3089,22 @@ async fn insufficient_funds_add_bid() { let (_, bob_initial_balance, _) = test.get_balances(None); let bid_amount = bob_initial_balance.total; - let mut txn = Transaction::from( + let txn = TransactionV1Builder::new_add_bid(BOB_PUBLIC_KEY.clone(), 0, bid_amount, None, None, None) .unwrap() .with_chain_name(CHAIN_NAME) .with_initiator_addr(PublicKey::from(&**BOB_SECRET_KEY)) .build() - .unwrap(), - ); + .unwrap(); + let price = txn.payment_amount().expect("must get payment amount"); + let mut txn = Transaction::from(txn); txn.sign(&BOB_SECRET_KEY); let (_txn_hash, _block_height, exec_result) = test.send_transaction(txn).await; let ExecutionResult::V2(result) = exec_result else { panic!("Expected ExecutionResult::V2 but got {:?}", exec_result); }; - let bid_cost: U512 = - U512::from(test.chainspec().system_costs_config.auction_costs().add_bid) * MIN_GAS_PRICE; + let bid_cost: U512 = U512::from(price) * MIN_GAS_PRICE; assert_eq!( result.error_message.as_deref(), @@ -3175,27 +3175,26 @@ async fn insufficient_funds_transfer_from_purse() { // now we try to transfer from the purse we just created let transfer_amount = U512::max_value(); - let mut txn = Transaction::from( - TransactionV1Builder::new_transfer( - transfer_amount, - Some(uref), - ALICE_PUBLIC_KEY.clone(), - None, - ) - .unwrap() - .with_chain_name(CHAIN_NAME) - .with_initiator_addr(PublicKey::from(&**BOB_SECRET_KEY)) - .build() - .unwrap(), - ); + let txn = TransactionV1Builder::new_transfer( + transfer_amount, + Some(uref), + ALICE_PUBLIC_KEY.clone(), + None, + ) + .unwrap() + .with_chain_name(CHAIN_NAME) + .with_initiator_addr(PublicKey::from(&**BOB_SECRET_KEY)) + .build() + .unwrap(); + let price = txn.payment_amount().expect("must get payment amount"); + let mut txn = Transaction::from(txn); txn.sign(&BOB_SECRET_KEY); let (_txn_hash, _block_height, exec_result) = test.send_transaction(txn).await; let ExecutionResult::V2(result) = exec_result else { panic!("Expected ExecutionResult::V2 but got {:?}", exec_result); }; - let transfer_cost: U512 = - U512::from(test.chainspec().system_costs_config.mint_costs().transfer) * MIN_GAS_PRICE; + let transfer_cost: U512 = U512::from(price) * MIN_GAS_PRICE; assert_eq!(result.error_message.as_deref(), Some("Insufficient funds")); assert_eq!(result.cost, transfer_cost); @@ -3223,22 +3222,22 @@ async fn insufficient_funds_when_caller_lacks_minimum_balance() { let (_, bob_initial_balance, _) = test.get_balances(None); let transfer_amount = bob_initial_balance.total - U512::one(); - let mut txn = Transaction::from( + let txn = TransactionV1Builder::new_transfer(transfer_amount, None, ALICE_PUBLIC_KEY.clone(), None) .unwrap() .with_chain_name(CHAIN_NAME) .with_initiator_addr(PublicKey::from(&**BOB_SECRET_KEY)) .build() - .unwrap(), - ); + .unwrap(); + let price = txn.payment_amount().expect("must get payment amount"); + let mut txn = Transaction::from(txn); txn.sign(&BOB_SECRET_KEY); let (_txn_hash, _block_height, exec_result) = test.send_transaction(txn).await; let ExecutionResult::V2(result) = exec_result else { panic!("Expected ExecutionResult::V2 but got {:?}", exec_result); }; - let transfer_cost: U512 = - U512::from(test.chainspec().system_costs_config.mint_costs().transfer) * MIN_GAS_PRICE; + let transfer_cost: U512 = U512::from(price) * MIN_GAS_PRICE; assert_eq!(result.error_message.as_deref(), Some("Insufficient funds")); assert_eq!(result.cost, transfer_cost); diff --git a/node/src/types/transaction/transaction_v1_builder.rs b/node/src/types/transaction/transaction_v1_builder.rs index 8be1ef73e6..e793319d3f 100644 --- a/node/src/types/transaction/transaction_v1_builder.rs +++ b/node/src/types/transaction/transaction_v1_builder.rs @@ -107,9 +107,10 @@ impl<'a> TransactionV1Builder<'a> { /// The default time-to-live for transactions, i.e. 30 minutes. pub const DEFAULT_TTL: TimeDiff = TimeDiff::from_millis(30 * 60 * 1_000); /// The default pricing mode for v1 transactions, ie FIXED cost. - pub const DEFAULT_PRICING_MODE: PricingMode = PricingMode::Fixed { - gas_price_tolerance: 5, - additional_computation_factor: 0, + pub const DEFAULT_PRICING_MODE: PricingMode = PricingMode::PaymentLimited { + payment_amount: 10_000_000_000, + gas_price_tolerance: 3, + standard_payment: true, }; /// The default scheduling for transactions, i.e. `Standard`. pub const DEFAULT_SCHEDULING: TransactionScheduling = TransactionScheduling::Standard; @@ -384,9 +385,10 @@ impl<'a> TransactionV1Builder<'a> { target: fields.target, entry_point: fields.entry_point, scheduling: fields.scheduling, - pricing_mode: PricingMode::Fixed { - gas_price_tolerance: 5, - additional_computation_factor: 0, + pricing_mode: PricingMode::PaymentLimited { + payment_amount: 2_500_000_000, + gas_price_tolerance: 3, + standard_payment: true, }, initiator_addr: Some(InitiatorAddr::PublicKey(PublicKey::from(&secret_key))), secret_key: Some(secret_key), @@ -423,9 +425,10 @@ impl<'a> TransactionV1Builder<'a> { target, entry_point, scheduling, - pricing_mode: PricingMode::Fixed { - gas_price_tolerance: 5, - additional_computation_factor: 0, + pricing_mode: PricingMode::PaymentLimited { + payment_amount: 2_500_000_000, + gas_price_tolerance: 3, + standard_payment: true, }, initiator_addr: Some(InitiatorAddr::PublicKey(PublicKey::from(&secret_key))), secret_key: Some(secret_key), diff --git a/resources/local/chainspec.toml.in b/resources/local/chainspec.toml.in index 5b199d6313..ebc014559b 100644 --- a/resources/local/chainspec.toml.in +++ b/resources/local/chainspec.toml.in @@ -134,7 +134,7 @@ validator_credit_cap = [1, 5] # 'classic': senders of transaction self-specify how much they pay. # 'fixed': costs are fixed, per the cost table # 'prepaid': prepaid transaction (currently not supported) -pricing_handling = { type = 'fixed' } +pricing_handling = { type = 'classic' } # Does the network allow pre-payment for future # execution? Currently not supported. # @@ -199,14 +199,14 @@ vm_casper_v2 = false # Note: For the given mainnet implementation we specially reserve the label 2 for install and upgrades and # the lane must be present and defined. # Different casper networks may not impose such a restriction. -# [1] -> Max transaction size in bytes for a given transaction in a certain lane +# [1] -> Max serialized length of the entire transaction in bytes for a given transaction in a certain lane # [2] -> Max args length size in bytes for a given transaction in a certain lane # [3] -> Transaction gas limit size in bytes for a given transaction in a certain lane # [4] -> The maximum number of transactions the lane can contain -native_mint_lane = [0, 1024, 1024, 65_000_000_000, 650] -native_auction_lane = [1, 2048, 2048, 2_500_000_000, 145] +native_mint_lane = [0, 2048, 1024, 2_500_000_000, 650] +native_auction_lane = [1, 3096, 2048, 2_500_000_000, 145] install_upgrade_lane = [2, 1_048_576, 2048, 100_000_000_000, 1] -wasm_lanes = [[3, 344_064, 1024, 100_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]] +wasm_lanes = [[3, 344_064, 1024, 100_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 2_500_000_000, 25]] [transactions.deploy] # The maximum number of Motes allowed to be spent during payment. 0 means unlimited. diff --git a/resources/production/chainspec.toml b/resources/production/chainspec.toml index 43a55ac1c6..91aa8483e9 100644 --- a/resources/production/chainspec.toml +++ b/resources/production/chainspec.toml @@ -141,7 +141,7 @@ validator_credit_cap = [1, 5] # 'classic': senders of transaction self-specify how much they pay. # 'fixed': costs are fixed, per the cost table # 'prepaid': prepaid transaction (currently not supported) -pricing_handling = { type = 'fixed' } +pricing_handling = { type = 'classic' } # Does the network allow pre-payment for future # execution? Currently not supported. # @@ -207,14 +207,14 @@ vm_casper_v2 = false # Note: For the given mainnet implementation we specially reserve the label 2 for install and upgrades and # the lane must be present and defined. # Different casper networks may not impose such a restriction. -# [1] -> Max transaction size in bytes for a given transaction in a certain lane +# [1] -> Max serialized length of the entire transaction in bytes for a given transaction in a certain lane # [2] -> Max args length size in bytes for a given transaction in a certain lane # [3] -> Transaction gas limit size in bytes for a given transaction in a certain lane # [4] -> The maximum number of transactions the lane can contain -native_mint_lane = [0, 1024, 1024, 65_000_000_000, 650] -native_auction_lane = [1, 2048, 2048, 2_500_000_000, 145] +native_mint_lane = [0, 2048, 1024, 2_500_000_000, 650] +native_auction_lane = [1, 3096, 2048, 2_500_000_000, 145] install_upgrade_lane = [2, 1_048_576, 2048, 100_000_000_000, 1] -wasm_lanes = [[3, 344_064, 1024, 100_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]] +wasm_lanes = [[3, 344_064, 1024, 100_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 2_500_000_000, 25]] [transactions.deploy] # The maximum number of Motes allowed to be spent during payment. 0 means unlimited. diff --git a/types/src/transaction/transaction_v1.rs b/types/src/transaction/transaction_v1.rs index 47c28fa4d7..9508fb9eb0 100644 --- a/types/src/transaction/transaction_v1.rs +++ b/types/src/transaction/transaction_v1.rs @@ -281,6 +281,16 @@ impl TransactionV1 { self.approvals.extend(approvals); } + /// Returns the payment amount if the txn is using classic mode. + #[cfg(any(all(feature = "std", feature = "testing"), test))] + pub fn payment_amount(&self) -> Option { + if let PricingMode::PaymentLimited { payment_amount, .. } = self.pricing_mode() { + Some(*payment_amount) + } else { + None + } + } + /// Returns a random, valid but possibly expired transaction. #[cfg(any(all(feature = "std", feature = "testing"), test))] pub fn random(rng: &mut TestRng) -> Self {