|
|
@@ -160,20 +160,25 @@ impl CostTracker {
|
|
|
&mut self,
|
|
|
estimated_tx_cost: &TransactionCost,
|
|
|
actual_execution_units: u64,
|
|
|
+ actual_loaded_accounts_data_size_cost: u64,
|
|
|
) {
|
|
|
- let estimated_execution_units = estimated_tx_cost.programs_execution_cost();
|
|
|
- match actual_execution_units.cmp(&estimated_execution_units) {
|
|
|
+ let actual_load_and_execution_units =
|
|
|
+ actual_execution_units.saturating_add(actual_loaded_accounts_data_size_cost);
|
|
|
+ let estimated_load_and_execution_units = estimated_tx_cost
|
|
|
+ .programs_execution_cost()
|
|
|
+ .saturating_add(estimated_tx_cost.loaded_accounts_data_size_cost());
|
|
|
+ match actual_load_and_execution_units.cmp(&estimated_load_and_execution_units) {
|
|
|
Ordering::Equal => (),
|
|
|
Ordering::Greater => {
|
|
|
self.add_transaction_execution_cost(
|
|
|
estimated_tx_cost,
|
|
|
- actual_execution_units - estimated_execution_units,
|
|
|
+ actual_load_and_execution_units - estimated_load_and_execution_units,
|
|
|
);
|
|
|
}
|
|
|
Ordering::Less => {
|
|
|
self.sub_transaction_execution_cost(
|
|
|
estimated_tx_cost,
|
|
|
- estimated_execution_units - actual_execution_units,
|
|
|
+ estimated_load_and_execution_units - actual_load_and_execution_units,
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
@@ -857,51 +862,69 @@ mod tests {
|
|
|
|
|
|
#[test]
|
|
|
fn test_update_execution_cost() {
|
|
|
- let acct1 = Pubkey::new_unique();
|
|
|
- let acct2 = Pubkey::new_unique();
|
|
|
- let acct3 = Pubkey::new_unique();
|
|
|
- let cost = 100;
|
|
|
+ let estimated_programs_execution_cost = 100;
|
|
|
+ let estimated_loaded_accounts_data_size_cost = 200;
|
|
|
+ let number_writeble_accounts = 3;
|
|
|
+ let writable_accounts = std::iter::repeat_with(Pubkey::new_unique)
|
|
|
+ .take(number_writeble_accounts)
|
|
|
+ .collect();
|
|
|
|
|
|
let tx_cost = TransactionCost::Transaction(UsageCostDetails {
|
|
|
- writable_accounts: vec![acct1, acct2, acct3],
|
|
|
- programs_execution_cost: cost,
|
|
|
+ writable_accounts,
|
|
|
+ programs_execution_cost: estimated_programs_execution_cost,
|
|
|
+ loaded_accounts_data_size_cost: estimated_loaded_accounts_data_size_cost,
|
|
|
..UsageCostDetails::default()
|
|
|
});
|
|
|
+ // confirm tx_cost is only made up by programs_execution_cost and
|
|
|
+ // loaded_accounts_data_size_cost
|
|
|
+ let estimated_tx_cost = tx_cost.sum();
|
|
|
+ assert_eq!(
|
|
|
+ estimated_tx_cost,
|
|
|
+ estimated_programs_execution_cost + estimated_loaded_accounts_data_size_cost
|
|
|
+ );
|
|
|
|
|
|
- let mut cost_tracker = CostTracker::default();
|
|
|
-
|
|
|
- // Assert OK to add tx_cost
|
|
|
- assert!(cost_tracker.try_add(&tx_cost).is_ok());
|
|
|
- let (_costliest_account, costliest_account_cost) = cost_tracker.find_costliest_account();
|
|
|
- assert_eq!(cost, cost_tracker.block_cost);
|
|
|
- assert_eq!(cost, costliest_account_cost);
|
|
|
- assert_eq!(1, cost_tracker.transaction_count);
|
|
|
-
|
|
|
- // assert no-change if actual units is same as estimated units
|
|
|
- let mut expected_cost = cost;
|
|
|
- cost_tracker.update_execution_cost(&tx_cost, cost);
|
|
|
- let (_costliest_account, costliest_account_cost) = cost_tracker.find_costliest_account();
|
|
|
- assert_eq!(expected_cost, cost_tracker.block_cost);
|
|
|
- assert_eq!(expected_cost, costliest_account_cost);
|
|
|
- assert_eq!(1, cost_tracker.transaction_count);
|
|
|
-
|
|
|
- // assert cost are adjusted down
|
|
|
- let reduced_units = 3;
|
|
|
- expected_cost -= reduced_units;
|
|
|
- cost_tracker.update_execution_cost(&tx_cost, cost - reduced_units);
|
|
|
- let (_costliest_account, costliest_account_cost) = cost_tracker.find_costliest_account();
|
|
|
- assert_eq!(expected_cost, cost_tracker.block_cost);
|
|
|
- assert_eq!(expected_cost, costliest_account_cost);
|
|
|
- assert_eq!(1, cost_tracker.transaction_count);
|
|
|
+ let test_update_cost_tracker =
|
|
|
+ |execution_cost_adjust: i64, loaded_acounts_data_size_cost_adjust: i64| {
|
|
|
+ let mut cost_tracker = CostTracker::default();
|
|
|
+ assert!(cost_tracker.try_add(&tx_cost).is_ok());
|
|
|
+
|
|
|
+ let actual_programs_execution_cost =
|
|
|
+ (estimated_programs_execution_cost as i64 + execution_cost_adjust) as u64;
|
|
|
+ let actual_loaded_accounts_data_size_cost =
|
|
|
+ (estimated_loaded_accounts_data_size_cost as i64
|
|
|
+ + loaded_acounts_data_size_cost_adjust) as u64;
|
|
|
+ let expected_cost = (estimated_tx_cost as i64
|
|
|
+ + execution_cost_adjust
|
|
|
+ + loaded_acounts_data_size_cost_adjust)
|
|
|
+ as u64;
|
|
|
+
|
|
|
+ cost_tracker.update_execution_cost(
|
|
|
+ &tx_cost,
|
|
|
+ actual_programs_execution_cost,
|
|
|
+ actual_loaded_accounts_data_size_cost,
|
|
|
+ );
|
|
|
|
|
|
- // assert cost are adjusted up
|
|
|
- let increased_units = 1;
|
|
|
- expected_cost += increased_units;
|
|
|
- cost_tracker.update_execution_cost(&tx_cost, cost + increased_units);
|
|
|
- let (_costliest_account, costliest_account_cost) = cost_tracker.find_costliest_account();
|
|
|
- assert_eq!(expected_cost, cost_tracker.block_cost);
|
|
|
- assert_eq!(expected_cost, costliest_account_cost);
|
|
|
- assert_eq!(1, cost_tracker.transaction_count);
|
|
|
+ assert_eq!(expected_cost, cost_tracker.block_cost);
|
|
|
+ assert_eq!(0, cost_tracker.vote_cost);
|
|
|
+ assert_eq!(
|
|
|
+ number_writeble_accounts,
|
|
|
+ cost_tracker.cost_by_writable_accounts.len()
|
|
|
+ );
|
|
|
+ for writable_account_cost in cost_tracker.cost_by_writable_accounts.values() {
|
|
|
+ assert_eq!(expected_cost, *writable_account_cost);
|
|
|
+ }
|
|
|
+ assert_eq!(1, cost_tracker.transaction_count);
|
|
|
+ };
|
|
|
+
|
|
|
+ test_update_cost_tracker(0, 0);
|
|
|
+ test_update_cost_tracker(0, 9);
|
|
|
+ test_update_cost_tracker(0, -9);
|
|
|
+ test_update_cost_tracker(9, 0);
|
|
|
+ test_update_cost_tracker(9, 9);
|
|
|
+ test_update_cost_tracker(9, -9);
|
|
|
+ test_update_cost_tracker(-9, 0);
|
|
|
+ test_update_cost_tracker(-9, 9);
|
|
|
+ test_update_cost_tracker(-9, -9);
|
|
|
}
|
|
|
|
|
|
#[test]
|