Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P-chain: introducing dynamic fee calculator #3188

Closed
wants to merge 217 commits into from
Closed
Show file tree
Hide file tree
Changes from 216 commits
Commits
Show all changes
217 commits
Select commit Hold shift + click to select a range
1adc328
E fork scaffolding
abi87 Jan 10, 2024
f6d7382
Merge branch 'dev' into e-fork-scaffolding
abi87 Jan 10, 2024
3889e51
Merge branch 'dev' into e-fork-scaffolding
abi87 Jan 12, 2024
e725961
Merge branch 'dev' into e-fork-scaffolding
abi87 Jan 15, 2024
30a4343
Merge branch 'dev' into e-fork-scaffolding
abi87 Jan 16, 2024
add3a35
Merge branch 'dev' into e-fork-scaffolding
abi87 Jan 17, 2024
3d08216
Merge branch 'dev' into e-fork-scaffolding
abi87 Jan 18, 2024
8f35564
Merge branch 'dev' into e-fork-scaffolding
abi87 Jan 19, 2024
2b16538
Merge branch 'master' into e-fork-scaffolding
abi87 Jan 26, 2024
4751e79
Merge branch 'master' into e-fork-scaffolding
abi87 Jan 29, 2024
e00d7c9
drop temporary fork time
abi87 Jan 29, 2024
b454987
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 1, 2024
f832034
nits
abi87 Feb 1, 2024
e01eb83
introduced fees calculator in P-chain
abi87 Feb 2, 2024
62ab6d0
upgraded codec for dynamic fees
abi87 Feb 2, 2024
9af11ca
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 2, 2024
d33a6a2
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 7, 2024
d846cba
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 7, 2024
af2c721
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 7, 2024
8a89505
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 8, 2024
3daec34
cleanup
abi87 Feb 8, 2024
b1fdd62
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 8, 2024
e27e938
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 8, 2024
a0020b1
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 9, 2024
1fb0662
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 9, 2024
0dfe25a
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 9, 2024
f28b80b
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 12, 2024
26fcb79
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 13, 2024
4d100eb
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 13, 2024
5e09b5e
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 13, 2024
199424b
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 15, 2024
3b76de5
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 15, 2024
5ea9c0b
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 15, 2024
603fbec
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 15, 2024
da5df60
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 15, 2024
2b05cf1
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 16, 2024
0baba01
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 16, 2024
9c4a2b3
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 16, 2024
9b97764
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 19, 2024
1368b48
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 19, 2024
56343d3
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 19, 2024
a4b81e6
fork switch to the avm
abi87 Feb 20, 2024
392e935
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 21, 2024
78a1a5c
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 21, 2024
59348c7
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 21, 2024
d3a733e
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 22, 2024
a362312
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 22, 2024
3bcb51a
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 22, 2024
f735491
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 25, 2024
6a1af7c
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 25, 2024
e375a83
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 25, 2024
33e3b70
Merge branch 'master' into e-fork-scaffolding
abi87 Feb 29, 2024
507636e
latestFork in avm
abi87 Feb 29, 2024
399dfc8
default test config for a few unit tests
abi87 Feb 29, 2024
089af5e
come more unit tests helpers
abi87 Feb 29, 2024
bf58efb
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Feb 29, 2024
cf039ed
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Feb 29, 2024
3c52428
Merge branch 'master' into e-fork-scaffolding
abi87 Mar 4, 2024
198c910
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Mar 4, 2024
4c674f0
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 4, 2024
e34e3de
Merge branch 'master' into e-fork-scaffolding
abi87 Mar 5, 2024
7feb04f
Merge branch 'master' into e-fork-scaffolding
abi87 Mar 6, 2024
43169f4
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Mar 6, 2024
9265060
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 6, 2024
7d7d1f7
Merge branch 'master' into e-fork-scaffolding
abi87 Mar 7, 2024
2dd14a8
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Mar 7, 2024
d82f588
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 7, 2024
5992b33
Merge branch 'master' into e-fork-scaffolding
abi87 Mar 11, 2024
d5ccb3b
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Mar 11, 2024
dca34a5
fixed merge
abi87 Mar 11, 2024
2e4e469
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 11, 2024
cda811f
Merge branch 'master' into e-fork-scaffolding
abi87 Mar 11, 2024
cd989f3
nits from code reviews
abi87 Mar 11, 2024
32da156
some more nits from code reviews
abi87 Mar 11, 2024
be7cf3e
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Mar 11, 2024
d2525d5
fixed merge
abi87 Mar 11, 2024
287dbb5
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 11, 2024
ae8231b
Merge branch 'master' into e-fork-scaffolding
abi87 Mar 12, 2024
8270220
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Mar 12, 2024
210bac8
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 12, 2024
95d3ab5
Merge branch 'master' into e-fork-scaffolding
abi87 Mar 13, 2024
7a17a9b
drop DurangoTime from avm config
abi87 Mar 13, 2024
2906756
nit
abi87 Mar 13, 2024
d3edbaa
nit
abi87 Mar 13, 2024
3dbdd6b
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Mar 13, 2024
1c7f823
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 13, 2024
737d429
Merge branch 'master' into e-fork-scaffolding
abi87 Mar 18, 2024
b47ef55
Merge branch 'e-fork-scaffolding' into codec_upgrades_dynamic_fees
abi87 Mar 18, 2024
9646588
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 18, 2024
ee6bd99
Merge branch 'master' into codec_upgrades_dynamic_fees
abi87 Mar 19, 2024
65b11b7
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 19, 2024
cede533
Merge branch 'master' into codec_upgrades_dynamic_fees
abi87 Mar 20, 2024
7aff1c8
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 20, 2024
d2772ec
Merge branch 'master' into codec_upgrades_dynamic_fees
abi87 Mar 22, 2024
d03e145
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 22, 2024
50e75f9
Merge branch 'master' into codec_upgrades_dynamic_fees
abi87 Mar 25, 2024
b391c11
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 25, 2024
6f36d2e
Merge branch 'master' into codec_upgrades_dynamic_fees
abi87 Mar 26, 2024
9111a95
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 26, 2024
b2e0b3e
Merge branch 'master' into codec_upgrades_dynamic_fees
abi87 Mar 27, 2024
bd2311e
reverted unnecessary changes
abi87 Mar 27, 2024
326a6d5
Merge branch 'codec_upgrades_dynamic_fees' into p-chain_introducing-f…
abi87 Mar 27, 2024
4a8141a
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Mar 27, 2024
b979b51
reduced diff
abi87 Mar 27, 2024
d09f885
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Mar 28, 2024
e43c69f
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Mar 29, 2024
b5962db
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Mar 29, 2024
c313a0f
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 2, 2024
5c22480
introduced fee StaticCalculator constructor
abi87 Apr 2, 2024
23060c5
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 2, 2024
0ffc651
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 3, 2024
fed7e67
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 4, 2024
231b2eb
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 8, 2024
6b72744
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 9, 2024
ced3f8d
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 11, 2024
c00888c
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 12, 2024
465f97d
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 15, 2024
4a1f2fe
nit
abi87 Apr 15, 2024
c078f1d
simplified p-chain config
abi87 Apr 15, 2024
c81c85e
added UTs
abi87 Apr 15, 2024
1867461
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 16, 2024
3d45cc4
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 17, 2024
ab782a5
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 21, 2024
8358f84
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 23, 2024
4583289
P chain introducing fees calculators fee config (#2960)
abi87 Apr 23, 2024
095a8f6
nits to address code reviews comments
abi87 Apr 24, 2024
796fc2f
minor renaming
abi87 Apr 24, 2024
6bc3091
simplified unit tests
abi87 Apr 24, 2024
eea8069
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 24, 2024
73cc339
Fee Calculator Refactor (#2964)
joshua-kim Apr 24, 2024
f008446
nit
abi87 Apr 25, 2024
dda8de7
Merge branch 'p-chain_introducing-fees-calculators' of github.com:ava…
abi87 Apr 25, 2024
2776ea7
nit
abi87 Apr 26, 2024
7bcd8f7
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 26, 2024
a104358
nit
abi87 Apr 26, 2024
cbc99ee
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 Apr 29, 2024
2b4cdbc
nits
abi87 Apr 29, 2024
54d05d7
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 2, 2024
09cfe24
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 6, 2024
eb98d60
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 7, 2024
62fc922
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 9, 2024
bf2d5e9
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 10, 2024
db597d3
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 13, 2024
6bc5f25
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 13, 2024
66ef59c
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 14, 2024
1747485
repackaged upgrades times into upgrade package
abi87 May 14, 2024
c1d8df8
Merge branch 'p-chain_repack_config' into p-chain_introducing-fees-ca…
abi87 May 14, 2024
8cbc4e2
simplified fee unit test setup
abi87 May 14, 2024
8a268b0
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 14, 2024
8852376
nits
abi87 May 14, 2024
10176c9
nit
abi87 May 15, 2024
530084e
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 16, 2024
c815178
nit
abi87 May 16, 2024
3fd10bc
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 20, 2024
eee5aba
drop duplicated fields
abi87 May 20, 2024
be373e2
replaced genesis.TxFeeConfig with fee.StaticConfig
abi87 May 20, 2024
34631c6
moved FeeCalculator instatiation to block level
abi87 May 20, 2024
32e26d5
feeding chainTime to fee Calculator to ctor
abi87 May 20, 2024
e2f8809
nit
abi87 May 21, 2024
0fe0367
Merge branch 'master' into p-chain_introducing-fees-calculators
abi87 May 21, 2024
1956713
Merge branch 'p-chain_introducing-fees-calculators' into p-chain_bloc…
abi87 May 21, 2024
2e4cbf6
Merge branch 'master' into p-chain_block_level_fee_calculator
abi87 May 21, 2024
708bb36
Merge branch 'master' into p-chain_block_level_fee_calculator
abi87 May 21, 2024
c402171
nit
abi87 May 21, 2024
59165aa
Merge branch 'master' into p-chain_block_level_fee_calculator
abi87 May 29, 2024
ecb9090
nits
abi87 May 29, 2024
09baf61
Merge branch 'master' into p-chain_block_level_fee_calculator
abi87 Jun 3, 2024
eb023ee
Merge branch 'master' into p-chain_block_level_fee_calculator
abi87 Jun 7, 2024
7594ec7
Merge branch 'master' into p-chain_block_level_fee_calculator
abi87 Jun 7, 2024
2e4ccad
Merge branch 'master' into p-chain_block_level_fee_calculator
abi87 Jun 10, 2024
b549906
Merge branch 'master' into p-chain_block_level_fee_calculator
abi87 Jun 10, 2024
11a4ef8
Merge branch 'master' into p-chain_block_level_fee_calculator
abi87 Jun 17, 2024
34aa429
Merge branch 'master' into p-chain_block_level_fee_calculator
abi87 Jun 24, 2024
ac5b00c
restructured p-chain calculator
abi87 Jun 24, 2024
e88298c
restructured fee calculator API
abi87 Jun 24, 2024
13017be
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jun 24, 2024
1c68b9a
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jun 24, 2024
da722bc
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jun 24, 2024
71bf522
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jun 27, 2024
9a9beff
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jun 27, 2024
e65b33c
consolidated fee Calculator creation
abi87 Jun 27, 2024
dc138ad
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jun 28, 2024
25e931a
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jun 28, 2024
cecf0fd
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jul 1, 2024
dd2b382
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jul 1, 2024
e5f0fd3
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jul 1, 2024
2a6bdeb
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jul 3, 2024
fc95471
nits
abi87 Jul 3, 2024
99c930e
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jul 3, 2024
9937663
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jul 4, 2024
b18ef30
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jul 4, 2024
2aab1a4
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jul 5, 2024
a74536e
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jul 5, 2024
4c764d4
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jul 9, 2024
89d9726
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jul 10, 2024
4d6f679
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jul 12, 2024
ccb5943
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jul 12, 2024
493305e
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jul 13, 2024
999a468
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jul 13, 2024
db0cdfd
Merge branch 'master' into p-chain_improved_fee_calculator_structure
abi87 Jul 15, 2024
f6c3a49
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jul 15, 2024
270ab49
introduced dynamic fee calculator
abi87 Jul 15, 2024
b96c572
nit
abi87 Jul 15, 2024
0a2715f
reduce diff
StephenButtolph Jul 15, 2024
1fc03ef
Merge branch 'p-chain_improved_fee_calculator_structure' into p-chain…
abi87 Jul 15, 2024
6b9a309
merged
StephenButtolph Jul 15, 2024
d06a87f
Merge branch 'p-chain_block_level_fee_calculator' of github.com:ava-l…
StephenButtolph Jul 15, 2024
1a1dcc2
merged
StephenButtolph Jul 15, 2024
2951eac
Merge branch 'p-chain_block_level_fee_calculator' into p-chain_update…
abi87 Jul 15, 2024
46442c9
nits
StephenButtolph Jul 15, 2024
d288bb5
nit
StephenButtolph Jul 15, 2024
885bea0
nit
StephenButtolph Jul 15, 2024
0941ecb
nit
StephenButtolph Jul 15, 2024
9383dad
Merge branch 'p-chain_block_level_fee_calculator' into p-chain_update…
abi87 Jul 15, 2024
0c54bab
Merge branch 'master' into p-chain_update_fee_calculator
abi87 Jul 15, 2024
e43d4ff
Merge branch 'master' into p-chain_update_fee_calculator
abi87 Jul 15, 2024
7b0fc94
Merge branch 'master' into p-chain_update_fee_calculator
abi87 Jul 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions vms/components/fee/calculator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package fee

import (
"errors"
"fmt"

safemath "github.com/ava-labs/avalanchego/utils/math"
)

var errGasBoundBreached = errors.New("gas bound breached")

// Calculator performs fee-related operations that are shared among P-chain and X-chain
// Calculator is supposed to be embedded within chain specific calculators.
type Calculator struct {
// feeWeights help consolidating complexity into gas
feeWeights Dimensions

// gas cap enforced with adding gas via AddFeesFor
gasCap Gas

// Avax denominated gas price, i.e. fee per unit of gas.
gasPrice GasPrice

// cumulatedGas helps aggregating the gas consumed in a single block
// so that we can verify it's not too big/build it properly.
cumulatedGas Gas

// latestTxComplexity tracks complexity of latest tx being processed.
// latestTxComplexity is especially helpful while building a tx.
latestTxComplexity Dimensions
}

func NewCalculator(feeWeights Dimensions, gasPrice GasPrice, gasCap Gas) *Calculator {
return &Calculator{
feeWeights: feeWeights,
gasCap: gasCap,
gasPrice: gasPrice,
}
}

func (c *Calculator) GetGasPrice() GasPrice {
return c.gasPrice
}

func (c *Calculator) GetBlockGas() (Gas, error) {
txGas, err := ToGas(c.feeWeights, c.latestTxComplexity)
if err != nil {
return ZeroGas, err
}
return c.cumulatedGas + txGas, nil
}

func (c *Calculator) GetGasCap() Gas {
return c.gasCap
}

// AddFeesFor updates latest tx complexity. It should be called once when tx is being verified
// and may be called multiple times when tx is being built (and tx components are added in time).
// AddFeesFor checks that gas cap is not breached. It also returns the updated tx fee for convenience.
func (c *Calculator) AddFeesFor(complexity Dimensions) (uint64, error) {
if complexity == Empty {
return c.GetLatestTxFee()
}

// Ensure we can consume (don't want partial update of values)
uc, err := Add(c.latestTxComplexity, complexity)
if err != nil {
return 0, fmt.Errorf("%w: %w", errGasBoundBreached, err)
}
c.latestTxComplexity = uc

totalGas, err := c.GetBlockGas()
if err != nil {
return 0, fmt.Errorf("%w: %w", errGasBoundBreached, err)
}
if totalGas > c.gasCap {
return 0, fmt.Errorf("%w: total gas %d, gas cap %d", errGasBoundBreached, totalGas, c.gasCap)
}

return c.GetLatestTxFee()
}

// Sometimes, e.g. while building a tx, we'd like freedom to speculatively add complexity
// and to remove it later on. [RemoveFeesFor] grants this freedom
func (c *Calculator) RemoveFeesFor(complexity Dimensions) (uint64, error) {
if complexity == Empty {
return c.GetLatestTxFee()
}

rc, err := Remove(c.latestTxComplexity, complexity)
if err != nil {
return 0, fmt.Errorf("%w: current Gas %d, gas to revert %d", err, c.cumulatedGas, complexity)
}
c.latestTxComplexity = rc
return c.GetLatestTxFee()
}

// DoneWithLatestTx should be invoked one a tx has been fully processed, before moving to the next one
func (c *Calculator) DoneWithLatestTx() error {
txGas, err := ToGas(c.feeWeights, c.latestTxComplexity)
if err != nil {
return err
}
c.cumulatedGas += txGas
c.latestTxComplexity = Empty
return nil
}

// CalculateFee must be a stateless method
func (c *Calculator) GetLatestTxFee() (uint64, error) {
gas, err := ToGas(c.feeWeights, c.latestTxComplexity)
if err != nil {
return 0, err
}
return safemath.Mul64(uint64(c.gasPrice), uint64(gas))
}
125 changes: 125 additions & 0 deletions vms/components/fee/calculator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package fee

import (
"math"
"testing"
"time"

"github.com/stretchr/testify/require"

"github.com/ava-labs/avalanchego/utils/units"

safemath "github.com/ava-labs/avalanchego/utils/math"
)

var (
testDynamicFeeCfg = DynamicFeesConfig{
GasPrice: GasPrice(10 * units.NanoAvax),
FeeDimensionWeights: Dimensions{6, 10, 10, 1},
}
testGasCap = Gas(math.MaxUint64)
)

func TestAddAndRemoveFees(t *testing.T) {
require := require.New(t)

var (
fc = NewCalculator(testDynamicFeeCfg.FeeDimensionWeights, testDynamicFeeCfg.GasPrice, testGasCap)

complexity = Dimensions{1, 2, 3, 4}
extraComplexity = Dimensions{2, 3, 4, 5}
overComplexity = Dimensions{math.MaxUint64, math.MaxUint64, math.MaxUint64, math.MaxUint64}
)

fee0, err := fc.GetLatestTxFee()
require.NoError(err)
require.Zero(fee0)
require.NoError(fc.DoneWithLatestTx())
gas, err := fc.GetBlockGas()
require.NoError(err)
require.Zero(gas)

fee1, err := fc.AddFeesFor(complexity)
require.NoError(err)
require.Greater(fee1, fee0)
gas, err = fc.GetBlockGas()
require.NoError(err)
require.NotZero(gas)

// complexity can't overflow
_, err = fc.AddFeesFor(overComplexity)
require.ErrorIs(err, safemath.ErrOverflow)
gas, err = fc.GetBlockGas()
require.NoError(err)
require.NotZero(gas)

// can't remove more complexity than it was added
_, err = fc.RemoveFeesFor(extraComplexity)
require.ErrorIs(err, safemath.ErrUnderflow)
gas, err = fc.GetBlockGas()
require.NoError(err)
require.NotZero(gas)

rFee, err := fc.RemoveFeesFor(complexity)
require.NoError(err)
require.Equal(rFee, fee0)
gas, err = fc.GetBlockGas()
require.NoError(err)
require.Zero(gas)
}

func TestGasCap(t *testing.T) {
require := require.New(t)

var (
now = time.Now().Truncate(time.Second)
parentBlkTime = now
// childBlkTime = parentBlkTime.Add(time.Second)
// grandChildBlkTime = childBlkTime.Add(5 * time.Second)

cfg = DynamicFeesConfig{
MaxGasPerSecond: Gas(1_000),
LeakGasCoeff: Gas(5),
}

currCap = cfg.MaxGasPerSecond
)

// A block whose gas matches cap, will consume full available cap
blkGas := cfg.MaxGasPerSecond
currCap = UpdateGasCap(currCap, blkGas)
require.Equal(ZeroGas, currCap)

// capacity grows linearly in time till MaxGas
for i := 1; i <= 5; i++ {
childBlkTime := parentBlkTime.Add(time.Duration(i) * time.Second)
nextCap, err := GasCap(cfg, currCap, parentBlkTime, childBlkTime)
require.NoError(err)
require.Equal(Gas(i)*cfg.MaxGasPerSecond/cfg.LeakGasCoeff, nextCap)
}

// capacity won't grow beyond MaxGas
childBlkTime := parentBlkTime.Add(time.Duration(6) * time.Second)
nextCap, err := GasCap(cfg, currCap, parentBlkTime, childBlkTime)
require.NoError(err)
require.Equal(cfg.MaxGasPerSecond, nextCap)

// Arrival of a block will reduce GasCap of block Gas content
blkGas = cfg.MaxGasPerSecond / 4
currCap = UpdateGasCap(nextCap, blkGas)
require.Equal(3*cfg.MaxGasPerSecond/4, currCap)

// capacity keeps growing again in time after block
childBlkTime = parentBlkTime.Add(time.Second)
nextCap, err = GasCap(cfg, currCap, parentBlkTime, childBlkTime)
require.NoError(err)
require.Equal(currCap+cfg.MaxGasPerSecond/cfg.LeakGasCoeff, nextCap)

// time can only grow forward with capacity
childBlkTime = parentBlkTime.Add(-1 * time.Second)
_, err = GasCap(cfg, currCap, parentBlkTime, childBlkTime)
require.ErrorIs(err, errUnexpectedBlockTimes)
}
60 changes: 60 additions & 0 deletions vms/components/fee/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package fee

import (
"errors"
"fmt"
"time"
)

var (
errZeroLeakGasCoeff = errors.New("zero leak gas coefficient")
errUnexpectedBlockTimes = errors.New("unexpected block times")
)

type DynamicFeesConfig struct {
// At this state this is the fixed gas price applied to each block
// In the next PRs, gas price will float and this will become the
// minimum gas price
GasPrice GasPrice `json:"gas-price"`

// weights to merge fees dimensions complexities into a single gas value
FeeDimensionWeights Dimensions `json:"fee-dimension-weights"`

// Leaky bucket parameters to calculate gas cap
MaxGasPerSecond Gas // techically the unit of measure is Gas/sec, but picking Gas reduces casts needed
LeakGasCoeff Gas // techically the unit of measure is sec^{-1}, but picking Gas reduces casts needed
}

func (c *DynamicFeesConfig) Validate() error {
if c.LeakGasCoeff == 0 {
return errZeroLeakGasCoeff
}

return nil
}

// We cap the maximum gas consumed by time with a leaky bucket approach
// GasCap = min (GasCap + MaxGasPerSecond/LeakGasCoeff*ElapsedTime, MaxGasPerSecond)
func GasCap(cfg DynamicFeesConfig, currentGasCapacity Gas, parentBlkTime, childBlkTime time.Time) (Gas, error) {
if parentBlkTime.Compare(childBlkTime) > 0 {
return ZeroGas, fmt.Errorf("%w, parentBlkTim %v, childBlkTime %v", errUnexpectedBlockTimes, parentBlkTime, childBlkTime)
}

elapsedTime := uint64(childBlkTime.Unix() - parentBlkTime.Unix())
if elapsedTime > uint64(cfg.LeakGasCoeff) {
return cfg.MaxGasPerSecond, nil
}

return min(cfg.MaxGasPerSecond, currentGasCapacity+cfg.MaxGasPerSecond*Gas(elapsedTime)/cfg.LeakGasCoeff), nil
}

func UpdateGasCap(currentGasCap, blkGas Gas) Gas {
nextGasCap := Gas(0)
if currentGasCap > blkGas {
nextGasCap = currentGasCap - blkGas
}
return nextGasCap
}
70 changes: 70 additions & 0 deletions vms/components/fee/dimensions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package fee

import (
safemath "github.com/ava-labs/avalanchego/utils/math"
)

const (
Bandwidth Dimension = 0
DBRead Dimension = 1
DBWrite Dimension = 2 // includes deletes
Compute Dimension = 3

FeeDimensions = 4
)

var (
ZeroGas = Gas(0)
ZeroGasPrice = GasPrice(0)
Empty = Dimensions{}
)

type (
GasPrice uint64
Gas uint64

Dimension int
Dimensions [FeeDimensions]uint64
)

func Add(lhs, rhs Dimensions) (Dimensions, error) {
var res Dimensions
for i := 0; i < FeeDimensions; i++ {
v, err := safemath.Add64(lhs[i], rhs[i])
if err != nil {
return res, err
}
res[i] = v
}
return res, nil
}

func Remove(lhs, rhs Dimensions) (Dimensions, error) {
var res Dimensions
for i := 0; i < FeeDimensions; i++ {
v, err := safemath.Sub(lhs[i], rhs[i])
if err != nil {
return res, err
}
res[i] = v
}
return res, nil
}

func ToGas(weights, dimensions Dimensions) (Gas, error) {
res := uint64(0)
for i := 0; i < FeeDimensions; i++ {
v, err := safemath.Mul64(weights[i], dimensions[i])
if err != nil {
return ZeroGas, err
}
res, err = safemath.Add64(res, v)
if err != nil {
return ZeroGas, err
}
}
return Gas(res) / 10, nil
}
Loading
Loading