From 27636df426c86bf6d1061321f6ba73ebeb826d29 Mon Sep 17 00:00:00 2001 From: austinabell Date: Wed, 6 Apr 2022 12:27:06 -0400 Subject: [PATCH 1/3] fix!: adjust gas distribution formula for NEP264 --- runtime/near-vm-logic/src/receipt_manager.rs | 16 ++++++---------- runtime/near-vm-logic/src/tests/gas_counter.rs | 5 ++++- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/runtime/near-vm-logic/src/receipt_manager.rs b/runtime/near-vm-logic/src/receipt_manager.rs index d9a3f4bcb9d..771b90f5728 100644 --- a/runtime/near-vm-logic/src/receipt_manager.rs +++ b/runtime/near-vm-logic/src/receipt_manager.rs @@ -447,26 +447,22 @@ impl ReceiptManager { return GasDistribution::NoRatios; } - // Floor division that will ensure gas allocated is <= gas to distribute - let gas_per_weight = (unused_gas as u128 / gas_weight_sum) as Gas; - let mut distribute_gas = |index: &FunctionCallActionIndex, assigned_gas: Gas| { let FunctionCallAction { gas, .. } = get_fuction_call_action_mut(&mut self.action_receipts, *index); - // This operation cannot overflow because the gas_per_weight calculation is a floor - // division of the total amount of gas by the weight sum and the remainder is - // distributed exactly. + // Operation cannot overflow because the amount of assigned gas is a fraction of + // the unused gas and is using floor division. *gas += assigned_gas; }; let mut distributed = 0; for (action_index, GasWeight(weight)) in &self.gas_weights { - // This can't overflow because the gas_per_weight is floor division - // of the weight sum. - let assigned_gas = gas_per_weight * weight; + // Multiplication is done in u128 with max values of u64::MAX so this cannot overflow. + // Division result can be truncated to 64 bits because gas_weight_sum >= weight. + let assigned_gas = (unused_gas as u128 * *weight as u128 / gas_weight_sum) as u64; - distribute_gas(action_index, assigned_gas); + distribute_gas(action_index, assigned_gas as u64); distributed += assigned_gas } diff --git a/runtime/near-vm-logic/src/tests/gas_counter.rs b/runtime/near-vm-logic/src/tests/gas_counter.rs index 1d0599429bf..402aea3eeff 100644 --- a/runtime/near-vm-logic/src/tests/gas_counter.rs +++ b/runtime/near-vm-logic/src/tests/gas_counter.rs @@ -195,7 +195,10 @@ fn function_call_weight_basic_cases_test() { ]); // Weight over u64 bounds - function_call_weight_check(&[(0, u64::MAX, 0), (0, 1000, 10_000_000_000)]); + function_call_weight_check(&[(0, u64::MAX, 9_999_999_999), (0, 1000, 1)]); + + // Weight over u64 bounds with three values + function_call_weight_check(&[(0, u64::MAX, 9_999_999_999), (0, 1, 0), (0, 1000, 1)]); // Weights with one zero and one non-zero function_call_weight_check(&[(0, 0, 0), (0, 1, 10_000_000_000)]) From 557fd7d1907f413cbb57c96df182327206334740 Mon Sep 17 00:00:00 2001 From: austinabell Date: Wed, 6 Apr 2022 12:35:20 -0400 Subject: [PATCH 2/3] update test to showcase logic --- runtime/near-vm-logic/src/tests/gas_counter.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/runtime/near-vm-logic/src/tests/gas_counter.rs b/runtime/near-vm-logic/src/tests/gas_counter.rs index 402aea3eeff..30cbc717132 100644 --- a/runtime/near-vm-logic/src/tests/gas_counter.rs +++ b/runtime/near-vm-logic/src/tests/gas_counter.rs @@ -197,8 +197,12 @@ fn function_call_weight_basic_cases_test() { // Weight over u64 bounds function_call_weight_check(&[(0, u64::MAX, 9_999_999_999), (0, 1000, 1)]); - // Weight over u64 bounds with three values - function_call_weight_check(&[(0, u64::MAX, 9_999_999_999), (0, 1, 0), (0, 1000, 1)]); + // Weight gas limit with three function calls + function_call_weight_check(&[ + (0, 10_000_000_000, 4_999_999_999), + (0, 1, 0), + (0, 10_000_000_000, 5_000_000_001), + ]); // Weights with one zero and one non-zero function_call_weight_check(&[(0, 0, 0), (0, 1, 10_000_000_000)]) From 66a5f75446da9e576dea21b994e89e511d9bc76c Mon Sep 17 00:00:00 2001 From: austinabell Date: Wed, 6 Apr 2022 12:41:01 -0400 Subject: [PATCH 3/3] typo fix --- runtime/near-vm-logic/src/tests/gas_counter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/near-vm-logic/src/tests/gas_counter.rs b/runtime/near-vm-logic/src/tests/gas_counter.rs index 30cbc717132..6fed948da7b 100644 --- a/runtime/near-vm-logic/src/tests/gas_counter.rs +++ b/runtime/near-vm-logic/src/tests/gas_counter.rs @@ -197,7 +197,7 @@ fn function_call_weight_basic_cases_test() { // Weight over u64 bounds function_call_weight_check(&[(0, u64::MAX, 9_999_999_999), (0, 1000, 1)]); - // Weight gas limit with three function calls + // Weight over gas limit with three function calls function_call_weight_check(&[ (0, 10_000_000_000, 4_999_999_999), (0, 1, 0),