Skip to content

Commit 73cf939

Browse files
Merge pull request casper-network#5116 from darthsiroftardis/pricing-mode-fix
Fix gas cost calculation in payment limited
2 parents 0dfa3a8 + 1a6baf6 commit 73cf939

4 files changed

Lines changed: 133 additions & 4 deletions

File tree

node/src/reactor/main_reactor/tests/transactions.rs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,52 @@ async fn transfer_to_account<A: Into<U512>>(
8282
)
8383
}
8484

85+
async fn send_add_bid<A: Into<U512>>(
86+
fixture: &mut TestFixture,
87+
amount: A,
88+
signing_key: &SecretKey,
89+
pricing: PricingMode,
90+
) -> (TransactionHash, u64, ExecutionResult) {
91+
let chain_name = fixture.chainspec.network_config.name.clone();
92+
let public_key = PublicKey::from(signing_key);
93+
94+
let mut txn = Transaction::from(
95+
TransactionV1Builder::new_add_bid(public_key.clone(), 10, amount, None, None, None)
96+
.unwrap()
97+
.with_initiator_addr(public_key)
98+
.with_pricing_mode(pricing)
99+
.with_chain_name(chain_name)
100+
.build()
101+
.unwrap(),
102+
);
103+
104+
txn.sign(signing_key);
105+
let txn_hash = txn.hash();
106+
107+
fixture.inject_transaction(txn).await;
108+
109+
info!("transfer_to_account starting run_until_executed_transaction");
110+
fixture
111+
.run_until_executed_transaction(&txn_hash, TEN_SECS)
112+
.await;
113+
114+
info!("transfer_to_account finished run_until_executed_transaction");
115+
let (_node_id, runner) = fixture.network.nodes().iter().next().unwrap();
116+
let exec_info = runner
117+
.main_reactor()
118+
.storage()
119+
.read_execution_info(txn_hash)
120+
.expect("Expected transaction to be included in a block.");
121+
122+
(
123+
txn_hash,
124+
exec_info.block_height,
125+
exec_info
126+
.execution_result
127+
.expect("Exec result should have been stored."),
128+
)
129+
}
130+
85131
async fn send_wasm_transaction(
86132
fixture: &mut TestFixture,
87133
from: &SecretKey,
@@ -763,6 +809,80 @@ async fn transfer_cost_payment_limited_price_no_fee_no_refund() {
763809
);
764810
}
765811

812+
#[tokio::test]
813+
async fn add_bid_with_classic_pricing_no_fee_no_refund() {
814+
let initial_stakes = InitialStakes::FromVec(vec![u128::MAX, 1]);
815+
816+
let config = SingleTransactionTestCase::default_test_config()
817+
.with_pricing_handling(PricingHandling::Classic)
818+
.with_refund_handling(RefundHandling::NoRefund)
819+
.with_fee_handling(FeeHandling::NoFee);
820+
821+
let mut fixture = TestFixture::new(initial_stakes, Some(config)).await;
822+
823+
let alice_secret_key = Arc::clone(&fixture.node_contexts[0].secret_key);
824+
let alice_public_key = PublicKey::from(&*alice_secret_key);
825+
826+
fixture.run_until_consensus_in_era(ERA_ONE, ONE_MIN).await;
827+
828+
let alice_initial_balance = *get_balance(&mut fixture, &alice_public_key, None, true)
829+
.available_balance()
830+
.expect("Expected Alice to have a balance.");
831+
832+
const BID_PAYMENT_AMOUNT: u64 = 1_000_000_000;
833+
834+
let bid_amount = fixture.chainspec.core_config.minimum_bid_amount + 1;
835+
// This transaction should be included since the tolerance is above the min gas price.
836+
let (_txn_hash, block_height, exec_result) = send_add_bid(
837+
&mut fixture,
838+
bid_amount,
839+
&alice_secret_key,
840+
PricingMode::PaymentLimited {
841+
payment_amount: BID_PAYMENT_AMOUNT,
842+
gas_price_tolerance: MIN_GAS_PRICE + 1,
843+
standard_payment: true,
844+
},
845+
)
846+
.await;
847+
848+
let expected_add_bid_cost = BID_PAYMENT_AMOUNT * MIN_GAS_PRICE as u64;
849+
850+
assert!(exec_result_is_success(&exec_result)); // transaction should have succeeded.
851+
assert_exec_result_cost(
852+
exec_result,
853+
expected_add_bid_cost.into(),
854+
Gas::new(BID_PAYMENT_AMOUNT),
855+
);
856+
857+
let alice_available_balance =
858+
get_balance(&mut fixture, &alice_public_key, Some(block_height), false);
859+
let alice_total_balance =
860+
get_balance(&mut fixture, &alice_public_key, Some(block_height), true);
861+
862+
// since FeeHandling is set to NoFee, we expect that there's a hold on Alice's balance for the
863+
// cost of the transfer. The total balance of Alice now should be the initial balance - the
864+
// amount transferred to Charlie.
865+
let alice_expected_total_balance = alice_initial_balance - bid_amount;
866+
// The available balance is the initial balance - the amount transferred to Charlie - the hold
867+
// for the transfer cost.
868+
let alice_expected_available_balance = alice_expected_total_balance - expected_add_bid_cost;
869+
870+
assert_eq!(
871+
alice_total_balance
872+
.available_balance()
873+
.expect("Expected Alice to have a balance")
874+
.clone(),
875+
alice_expected_total_balance
876+
);
877+
assert_eq!(
878+
alice_available_balance
879+
.available_balance()
880+
.expect("Expected Alice to have a balance")
881+
.clone(),
882+
alice_expected_available_balance
883+
);
884+
}
885+
766886
#[tokio::test]
767887
#[should_panic = "within 10 seconds"]
768888
async fn transaction_with_low_threshold_should_not_get_included() {

types/src/chainspec.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,13 @@ impl Chainspec {
257257
.transaction_v1_config
258258
.get_max_transaction_count(lane)
259259
}
260+
261+
/// Returns the max payment defined by the wasm lanes.
262+
pub fn get_max_payment_limit_for_wasm(&self) -> u64 {
263+
self.transaction_config
264+
.transaction_v1_config
265+
.get_max_payment_limit_for_wasm()
266+
}
260267
}
261268

262269
#[cfg(any(feature = "testing", test))]

types/src/transaction/deploy.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use crate::{
6060
};
6161

6262
#[cfg(any(feature = "std", test))]
63-
use crate::{chainspec::PricingHandling, Chainspec, LARGE_WASM_LANE_ID};
63+
use crate::{chainspec::PricingHandling, Chainspec};
6464
#[cfg(any(feature = "std", test))]
6565
use crate::{system::auction::ARG_AMOUNT, transaction::GasLimited, Gas, Motes, U512};
6666
pub use deploy_hash::DeployHash;
@@ -1391,7 +1391,7 @@ impl GasLimited for Deploy {
13911391
let computation_limit = if self.is_transfer() {
13921392
costs.mint_costs().transfer as u64
13931393
} else {
1394-
chainspec.get_max_gas_limit_by_category(LARGE_WASM_LANE_ID)
1394+
chainspec.get_max_payment_limit_for_wasm()
13951395
};
13961396
Gas::new(computation_limit)
13971397
} // legacy deploys do not support prepaid

types/src/transaction/pricing_mode.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,12 @@ impl PricingMode {
214214
) -> Result<Motes, PricingModeError> {
215215
let gas_limit = self.gas_limit(chainspec, entry_point, lane_id)?;
216216
let motes = match self {
217-
PricingMode::PaymentLimited { .. } | PricingMode::Fixed { .. } => {
218-
Motes::from_gas(gas_limit, gas_price)
217+
PricingMode::PaymentLimited { payment_amount, .. } => {
218+
Motes::from_gas(Gas::from(*payment_amount), gas_price)
219219
.ok_or(PricingModeError::UnableToCalculateGasCost)?
220220
}
221+
PricingMode::Fixed { .. } => Motes::from_gas(gas_limit, gas_price)
222+
.ok_or(PricingModeError::UnableToCalculateGasCost)?,
221223
PricingMode::Prepaid { .. } => {
222224
Motes::zero() // prepaid
223225
}

0 commit comments

Comments
 (0)