From 1adc32865ef59f9157e2578e2739e5671d878aee Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 10 Jan 2024 13:52:05 +0100 Subject: [PATCH 001/100] E fork scaffolding --- node/node.go | 3 + version/constants.go | 13 ++ vms/avm/block/executor/block_test.go | 140 +++++++++++++++++- vms/avm/block/executor/manager_test.go | 25 +++- vms/avm/config/config.go | 7 + vms/avm/environment_test.go | 3 + vms/avm/index_test.go | 17 ++- vms/avm/service_test.go | 36 ++++- .../txs/executor/syntactic_verifier_test.go | 3 + vms/avm/vm_regression_test.go | 7 +- vms/avm/vm_test.go | 24 ++- vms/platformvm/block/builder/helpers_test.go | 2 + vms/platformvm/block/executor/helpers_test.go | 2 + vms/platformvm/config/config.go | 7 + vms/platformvm/txs/executor/helpers_test.go | 1 + .../executor/staker_tx_verification_test.go | 14 ++ .../txs/executor/standard_tx_executor_test.go | 14 ++ vms/platformvm/validator_set_property_test.go | 1 + vms/platformvm/vm_regression_test.go | 1 + vms/platformvm/vm_test.go | 8 + 20 files changed, 305 insertions(+), 23 deletions(-) diff --git a/node/node.go b/node/node.go index 45e2f6a506eb..0c61b0ba848a 100644 --- a/node/node.go +++ b/node/node.go @@ -1078,6 +1078,7 @@ func (n *Node) initVMs() error { }) durangoTime := version.GetDurangoTime(n.Config.NetworkID) + eForkTime := version.GetEForkTime(n.Config.NetworkID) if err := txs.InitCodec(durangoTime); err != nil { return err } @@ -1120,6 +1121,7 @@ func (n *Node) initVMs() error { BanffTime: version.GetBanffTime(n.Config.NetworkID), CortinaTime: version.GetCortinaTime(n.Config.NetworkID), DurangoTime: durangoTime, + EForkTime: eForkTime, UseCurrentHeight: n.Config.UseCurrentHeight, }, }), @@ -1128,6 +1130,7 @@ func (n *Node) initVMs() error { TxFee: n.Config.TxFee, CreateAssetTxFee: n.Config.CreateAssetTxFee, DurangoTime: durangoTime, + EForkTime: eForkTime, }, }), vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), diff --git a/version/constants.go b/version/constants.go index 053a57a4585b..4a4187bd2774 100644 --- a/version/constants.go +++ b/version/constants.go @@ -109,6 +109,12 @@ var ( constants.MainnetID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), constants.FujiID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), } + + EForkTimes = map[uint32]time.Time{ + constants.MainnetID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), + constants.FujiID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), + } + TempForkTime = time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC) ) func init() { @@ -204,6 +210,13 @@ func GetDurangoTime(networkID uint32) time.Time { return DefaultUpgradeTime } +func GetEForkTime(networkID uint32) time.Time { + if upgradeTime, exists := EForkTimes[networkID]; exists { + return upgradeTime + } + return TempForkTime +} + func GetCompatibility(networkID uint32) Compatibility { return NewCompatibility( CurrentApp, diff --git a/vms/avm/block/executor/block_test.go b/vms/avm/block/executor/block_test.go index 0b6738822c6e..c44a69389568 100644 --- a/vms/avm/block/executor/block_test.go +++ b/vms/avm/block/executor/block_test.go @@ -23,6 +23,7 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/block" + "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/metrics" "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" @@ -46,6 +47,12 @@ func TestBlockVerify(t *testing.T) { b := &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, blkIDToState: map[ids.ID]*blockState{}, }, } @@ -63,8 +70,15 @@ func TestBlockVerify(t *testing.T) { mockBlock.EXPECT().ID().Return(ids.Empty).AnyTimes() mockBlock.EXPECT().MerkleRoot().Return(ids.GenerateTestID()).AnyTimes() return &Block{ - Block: mockBlock, - manager: &manager{}, + Block: mockBlock, + manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, + }, } }, expectedErr: ErrUnexpectedMerkleRoot, @@ -83,6 +97,12 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, clk: clk, }, } @@ -100,6 +120,12 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, blkIDToState: map[ids.ID]*blockState{}, clk: &mockable.Clock{}, }, @@ -126,6 +152,12 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), blkIDToState: map[ids.ID]*blockState{}, @@ -158,6 +190,12 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, state: mockState, blkIDToState: map[ids.ID]*blockState{}, clk: &mockable.Clock{}, @@ -194,6 +232,12 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, state: mockState, blkIDToState: map[ids.ID]*blockState{}, clk: &mockable.Clock{}, @@ -233,6 +277,12 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, blkIDToState: map[ids.ID]*blockState{ parentID: { onAcceptState: mockParentState, @@ -280,6 +330,12 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), blkIDToState: map[ids.ID]*blockState{ @@ -332,7 +388,12 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), - backend: &executor.Backend{}, + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, blkIDToState: map[ids.ID]*blockState{ parentID: { onAcceptState: mockParentState, @@ -410,7 +471,12 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), - backend: &executor.Backend{}, + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, blkIDToState: map[ids.ID]*blockState{ parentID: { onAcceptState: mockParentState, @@ -468,7 +534,12 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{}, + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, blkIDToState: map[ids.ID]*blockState{ parentID: { onAcceptState: mockParentState, @@ -520,7 +591,12 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ mempool: mockMempool, metrics: metrics.NewMockMetrics(ctrl), - backend: &executor.Backend{}, + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, blkIDToState: map[ids.ID]*blockState{ parentID: { onAcceptState: mockParentState, @@ -598,6 +674,10 @@ func TestBlockAccept(t *testing.T) { Ctx: &snow.Context{ Log: logging.NoLog{}, }, + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }, blkIDToState: map[ids.ID]*blockState{}, }, @@ -632,6 +712,10 @@ func TestBlockAccept(t *testing.T) { Ctx: &snow.Context{ Log: logging.NoLog{}, }, + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }, blkIDToState: map[ids.ID]*blockState{ blockID: { @@ -676,6 +760,10 @@ func TestBlockAccept(t *testing.T) { SharedMemory: mockSharedMemory, Log: logging.NoLog{}, }, + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }, blkIDToState: map[ids.ID]*blockState{ blockID: { @@ -724,6 +812,10 @@ func TestBlockAccept(t *testing.T) { SharedMemory: mockSharedMemory, Log: logging.NoLog{}, }, + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }, blkIDToState: map[ids.ID]*blockState{ blockID: { @@ -775,6 +867,10 @@ func TestBlockAccept(t *testing.T) { SharedMemory: mockSharedMemory, Log: logging.NoLog{}, }, + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }, blkIDToState: map[ids.ID]*blockState{ blockID: { @@ -872,6 +968,10 @@ func TestBlockReject(t *testing.T) { metrics: metrics.NewMockMetrics(ctrl), backend: &executor.Backend{ Bootstrapped: true, + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, Ctx: &snow.Context{ Log: logging.NoLog{}, }, @@ -933,6 +1033,10 @@ func TestBlockReject(t *testing.T) { Ctx: &snow.Context{ Log: logging.NoLog{}, }, + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }, state: mockState, blkIDToState: map[ids.ID]*blockState{ @@ -982,6 +1086,12 @@ func TestBlockStatus(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, lastAccepted: blockID, }, } @@ -997,6 +1107,12 @@ func TestBlockStatus(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, blkIDToState: map[ids.ID]*blockState{ blockID: {}, }, @@ -1018,6 +1134,12 @@ func TestBlockStatus(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, blkIDToState: map[ids.ID]*blockState{}, state: mockState, }, @@ -1038,6 +1160,12 @@ func TestBlockStatus(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, blkIDToState: map[ids.ID]*blockState{}, state: mockState, }, diff --git a/vms/avm/block/executor/manager_test.go b/vms/avm/block/executor/manager_test.go index 012428d582e4..89b547eed967 100644 --- a/vms/avm/block/executor/manager_test.go +++ b/vms/avm/block/executor/manager_test.go @@ -14,7 +14,9 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/block" + "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/avm/txs/executor" @@ -124,7 +126,12 @@ func TestManagerVerifyTx(t *testing.T) { }, managerF: func(ctrl *gomock.Controller) *manager { return &manager{ - backend: &executor.Backend{}, + backend: &executor.Backend{ + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + }, } }, expectedErr: ErrChainNotSynced, @@ -142,6 +149,10 @@ func TestManagerVerifyTx(t *testing.T) { return &manager{ backend: &executor.Backend{ Bootstrapped: true, + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }, } }, @@ -170,6 +181,10 @@ func TestManagerVerifyTx(t *testing.T) { return &manager{ backend: &executor.Backend{ Bootstrapped: true, + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }, state: state, lastAccepted: lastAcceptedID, @@ -202,6 +217,10 @@ func TestManagerVerifyTx(t *testing.T) { return &manager{ backend: &executor.Backend{ Bootstrapped: true, + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }, state: state, lastAccepted: lastAcceptedID, @@ -234,6 +253,10 @@ func TestManagerVerifyTx(t *testing.T) { return &manager{ backend: &executor.Backend{ Bootstrapped: true, + Config: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }, state: state, lastAccepted: lastAcceptedID, diff --git a/vms/avm/config/config.go b/vms/avm/config/config.go index df6e4f7de2ae..b4da6e3781ea 100644 --- a/vms/avm/config/config.go +++ b/vms/avm/config/config.go @@ -15,4 +15,11 @@ type Config struct { // Time of the Durango network upgrade DurangoTime time.Time + + // Time of the E network upgrade + EForkTime time.Time +} + +func (c *Config) IsEForkActivated(timestamp time.Time) bool { + return !timestamp.Before(c.EForkTime) } diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index 236c20875796..00a1b2725e47 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -29,6 +29,7 @@ import ( "github.com/ava-labs/avalanchego/utils/linkedhashmap" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/sampler" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/block/executor" "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/fxs" @@ -149,6 +150,8 @@ func setup(tb testing.TB, c *envConfig) *environment { vmStaticConfig := config.Config{ TxFee: testTxFee, CreateAssetTxFee: testTxFee, + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, } if c.vmStaticConfig != nil { vmStaticConfig = *c.vmStaticConfig diff --git a/vms/avm/index_test.go b/vms/avm/index_test.go index 03a2fd863c6a..642410951c9e 100644 --- a/vms/avm/index_test.go +++ b/vms/avm/index_test.go @@ -6,6 +6,7 @@ package avm import ( "context" "testing" + "time" "github.com/prometheus/client_golang/prometheus" @@ -20,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -31,7 +33,10 @@ func TestIndexTransaction_Ordered(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }) defer func() { require.NoError(env.vm.Shutdown(context.Background())) @@ -75,7 +80,10 @@ func TestIndexTransaction_MultipleTransactions(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }) defer func() { require.NoError(env.vm.Shutdown(context.Background())) @@ -123,7 +131,10 @@ func TestIndexTransaction_MultipleAddresses(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }) defer func() { require.NoError(env.vm.Shutdown(context.Background())) diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index c659b8e9de9e..62f81d08f48c 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -34,6 +34,7 @@ import ( "github.com/ava-labs/avalanchego/utils/formatting/address" "github.com/ava-labs/avalanchego/utils/json" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/block" "github.com/ava-labs/avalanchego/vms/avm/block/executor" "github.com/ava-labs/avalanchego/vms/avm/config" @@ -703,7 +704,10 @@ func TestServiceGetTxJSON_CreateAssetTx(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -819,7 +823,10 @@ func TestServiceGetTxJSON_OperationTxWithNftxMintOp(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -918,7 +925,10 @@ func TestServiceGetTxJSON_OperationTxWithMultipleNftxMintOp(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -1056,7 +1066,10 @@ func TestServiceGetTxJSON_OperationTxWithSecpMintOp(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -1159,7 +1172,10 @@ func TestServiceGetTxJSON_OperationTxWithMultipleSecpMintOp(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -1305,7 +1321,10 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOp(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -1405,7 +1424,10 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, diff --git a/vms/avm/txs/executor/syntactic_verifier_test.go b/vms/avm/txs/executor/syntactic_verifier_test.go index 108ac9e94a60..3b5c05d42d07 100644 --- a/vms/avm/txs/executor/syntactic_verifier_test.go +++ b/vms/avm/txs/executor/syntactic_verifier_test.go @@ -15,6 +15,7 @@ import ( "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/fxs" "github.com/ava-labs/avalanchego/vms/avm/txs" @@ -30,6 +31,8 @@ var ( feeConfig = config.Config{ TxFee: 2, CreateAssetTxFee: 3, + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, } ) diff --git a/vms/avm/vm_regression_test.go b/vms/avm/vm_regression_test.go index c6ac40df845d..1e4720f80fe1 100644 --- a/vms/avm/vm_regression_test.go +++ b/vms/avm/vm_regression_test.go @@ -6,12 +6,14 @@ package avm import ( "context" "testing" + "time" "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -24,7 +26,10 @@ func TestVerifyFxUsage(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }) env.vm.ctx.Lock.Unlock() defer func() { diff --git a/vms/avm/vm_test.go b/vms/avm/vm_test.go index d8aeaf3b8743..f7c7d11af0ea 100644 --- a/vms/avm/vm_test.go +++ b/vms/avm/vm_test.go @@ -7,6 +7,7 @@ import ( "context" "math" "testing" + "time" "github.com/stretchr/testify/require" @@ -19,6 +20,7 @@ import ( "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/fxs" "github.com/ava-labs/avalanchego/vms/avm/txs" @@ -132,7 +134,10 @@ func TestIssueNFT(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }) env.vm.ctx.Lock.Unlock() defer func() { @@ -233,7 +238,10 @@ func TestIssueProperty(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -520,7 +528,10 @@ func TestIssueImportTx(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, }) defer func() { require.NoError(env.vm.Shutdown(context.Background())) @@ -620,8 +631,11 @@ func TestForceAcceptImportTx(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{}, - notLinearized: true, + vmStaticConfig: &config.Config{ + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, + }, + notLinearized: true, }) defer func() { require.NoError(env.vm.Shutdown(context.Background())) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index fa7339be6fdb..7d84060b1346 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -298,6 +298,8 @@ func defaultConfig() *config.Config { ApricotPhase3Time: defaultValidateEndTime, ApricotPhase5Time: defaultValidateEndTime, BanffTime: time.Time{}, // neglecting fork ordering this for package tests + DurangoTime: time.Time{}, + EForkTime: mockable.MaxTime, } } diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 5e7b5a3fce1e..848cbdb5c624 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -316,6 +316,8 @@ func defaultConfig() *config.Config { ApricotPhase3Time: defaultValidateEndTime, ApricotPhase5Time: defaultValidateEndTime, BanffTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EForkTime: mockable.MaxTime, } } diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 50628c422afd..292981ddc021 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -107,6 +107,9 @@ type Config struct { // Time of the Durango network upgrade DurangoTime time.Time + // Time of the E network upgrade + EForkTime time.Time + // UseCurrentHeight forces [GetMinimumHeight] to return the current height // of the P-Chain instead of the oldest block in the [recentlyAccepted] // window. @@ -137,6 +140,10 @@ func (c *Config) IsDurangoActivated(timestamp time.Time) bool { return !timestamp.Before(c.DurangoTime) } +func (c *Config) IsEForkActivated(timestamp time.Time) bool { + return !timestamp.Before(c.EForkTime) +} + func (c *Config) GetCreateBlockchainTxFee(timestamp time.Time) uint64 { if c.IsApricotPhase3Activated(timestamp) { return c.CreateBlockchainTxFee diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 1ea645efcfb8..7f90b6ab7852 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -284,6 +284,7 @@ func defaultConfig(postBanff, postCortina, postDurango bool) *config.Config { BanffTime: banffTime, CortinaTime: cortinaTime, DurangoTime: durangoTime, + EForkTime: mockable.MaxTime, } } diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index b59daf0da2b0..204ed382a2ac 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -113,6 +113,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork + EForkTime: mockable.MaxTime, }, } }, @@ -134,6 +135,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, } @@ -159,6 +161,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Config: &config.Config{ CortinaTime: activeForkTime, DurangoTime: mockable.MaxTime, + EForkTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -185,6 +188,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork + EForkTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -214,6 +218,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork + EForkTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -243,6 +248,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork + EForkTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -273,6 +279,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork + EForkTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -306,6 +313,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork + EForkTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -339,6 +347,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork + EForkTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -374,6 +383,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork + EForkTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -403,6 +413,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork + EForkTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -449,6 +460,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Config: &config.Config{ AddSubnetValidatorFee: 1, DurangoTime: activeForkTime, // activate latest fork, + EForkTime: mockable.MaxTime, }, Ctx: ctx, Bootstrapped: bootstrapped, @@ -495,6 +507,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Config: &config.Config{ CortinaTime: activeForkTime, DurangoTime: mockable.MaxTime, + EForkTime: mockable.MaxTime, AddSubnetValidatorFee: 1, }, Ctx: ctx, @@ -547,6 +560,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Config: &config.Config{ AddSubnetValidatorFee: 1, DurangoTime: activeForkTime, // activate latest fork, + EForkTime: mockable.MaxTime, }, Ctx: ctx, Bootstrapped: bootstrapped, diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index a86c579fee79..de0e3eebecc2 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/hashing" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/config" @@ -1150,6 +1151,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1177,6 +1179,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1204,6 +1207,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1234,6 +1238,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1262,6 +1267,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1289,6 +1295,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1318,6 +1325,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1350,6 +1358,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1507,6 +1516,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1533,6 +1543,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1561,6 +1572,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, MaxStakeDuration: math.MaxInt64, + EForkTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1593,6 +1605,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, MaxStakeDuration: math.MaxInt64, }, Bootstrapped: &utils.Atomic[bool]{}, @@ -1631,6 +1644,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, + EForkTime: mockable.MaxTime, MaxStakeDuration: math.MaxInt64, }, Bootstrapped: &utils.Atomic[bool]{}, diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 5ca5bfd6c241..c2894e594f7e 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -730,6 +730,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { ApricotPhase5Time: forkTime, BanffTime: forkTime, CortinaTime: forkTime, + EForkTime: mockable.MaxTime, }} vm.clock.Set(forkTime.Add(time.Second)) diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 36186ec32ae0..a82cf6f76c67 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -373,6 +373,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { BanffTime: latestForkTime, CortinaTime: mockable.MaxTime, DurangoTime: mockable.MaxTime, + EForkTime: mockable.MaxTime, }} ctx := snowtest.Context(t, snowtest.PChainID) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 23e88a646368..6c8733550d09 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -252,6 +252,7 @@ func defaultVM(t *testing.T, fork activeFork) (*VM, database.Database, *mutableS BanffTime: banffTime, CortinaTime: cortinaTime, DurangoTime: durangoTime, + EForkTime: mockable.MaxTime, }} db := memdb.New() @@ -1135,6 +1136,7 @@ func TestRestartFullyAccepted(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, + EForkTime: mockable.MaxTime, }} firstCtx := snowtest.Context(t, snowtest.PChainID) @@ -1222,6 +1224,7 @@ func TestRestartFullyAccepted(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, + EForkTime: mockable.MaxTime, }} secondCtx := snowtest.Context(t, snowtest.PChainID) @@ -1272,6 +1275,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, + EForkTime: mockable.MaxTime, }} initialClkTime := latestForkTime.Add(time.Second) @@ -1613,6 +1617,7 @@ func TestUnverifiedParent(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, + EForkTime: mockable.MaxTime, }} initialClkTime := latestForkTime.Add(time.Second) @@ -1776,6 +1781,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, + EForkTime: mockable.MaxTime, }} firstCtx := snowtest.Context(t, snowtest.PChainID) @@ -1824,6 +1830,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, + EForkTime: mockable.MaxTime, }} secondCtx := snowtest.Context(t, snowtest.PChainID) @@ -1923,6 +1930,7 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, + EForkTime: mockable.MaxTime, }} ctx := snowtest.Context(t, snowtest.PChainID) From e00d7c9953990f7758e3fb8aa201252e641252d4 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 29 Jan 2024 13:36:20 +0100 Subject: [PATCH 002/100] drop temporary fork time --- version/constants.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/version/constants.go b/version/constants.go index a535f2a07597..f90e1188ab35 100644 --- a/version/constants.go +++ b/version/constants.go @@ -135,7 +135,6 @@ var ( constants.MainnetID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), constants.FujiID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), } - TempForkTime = time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC) ) func init() { @@ -263,7 +262,7 @@ func GetEForkTime(networkID uint32) time.Time { if upgradeTime, exists := EForkTimes[networkID]; exists { return upgradeTime } - return TempForkTime + return DefaultUpgradeTime } func GetCompatibility(networkID uint32) Compatibility { From f832034e7aadba290a87c2a88d6f40fa027919cb Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 1 Feb 2024 22:38:42 +0100 Subject: [PATCH 003/100] nits --- node/node.go | 6 +- version/constants.go | 6 +- vms/avm/block/executor/block_test.go | 96 +++++++++---------- vms/avm/block/executor/manager_test.go | 20 ++-- vms/avm/config/config.go | 6 +- vms/avm/environment_test.go | 2 +- vms/avm/index_test.go | 12 +-- vms/avm/service_test.go | 28 +++--- .../txs/executor/syntactic_verifier_test.go | 2 +- vms/avm/vm_regression_test.go | 4 +- vms/avm/vm_test.go | 16 ++-- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/config/config.go | 4 +- vms/platformvm/txs/executor/helpers_test.go | 2 +- .../executor/staker_tx_verification_test.go | 52 +++++----- .../txs/executor/standard_tx_executor_test.go | 86 ++++++++--------- vms/platformvm/validator_set_property_test.go | 2 +- vms/platformvm/vm_regression_test.go | 2 +- vms/platformvm/vm_test.go | 16 ++-- 20 files changed, 183 insertions(+), 183 deletions(-) diff --git a/node/node.go b/node/node.go index a9cfc4e951e2..88c14ba3a083 100644 --- a/node/node.go +++ b/node/node.go @@ -1182,7 +1182,7 @@ func (n *Node) initVMs() error { } durangoTime := version.GetDurangoTime(n.Config.NetworkID) - eForkTime := version.GetEForkTime(n.Config.NetworkID) + eUpgradeTime := version.GetEUpgradeTime(n.Config.NetworkID) if err := txs.InitCodec(durangoTime); err != nil { return err } @@ -1225,7 +1225,7 @@ func (n *Node) initVMs() error { BanffTime: version.GetBanffTime(n.Config.NetworkID), CortinaTime: version.GetCortinaTime(n.Config.NetworkID), DurangoTime: durangoTime, - EForkTime: eForkTime, + EUpgradeTime: eUpgradeTime, UseCurrentHeight: n.Config.UseCurrentHeight, }, }), @@ -1234,7 +1234,7 @@ func (n *Node) initVMs() error { TxFee: n.Config.TxFee, CreateAssetTxFee: n.Config.CreateAssetTxFee, DurangoTime: durangoTime, - EForkTime: eForkTime, + EUpgradeTime: eUpgradeTime, }, }), n.VMManager.RegisterFactory(context.TODO(), constants.EVMID, &coreth.Factory{}), diff --git a/version/constants.go b/version/constants.go index 494448d08301..153c87a33811 100644 --- a/version/constants.go +++ b/version/constants.go @@ -142,7 +142,7 @@ var ( constants.FujiID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), } - EForkTimes = map[uint32]time.Time{ + EUpgradeTimes = map[uint32]time.Time{ constants.MainnetID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), constants.FujiID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), } @@ -246,8 +246,8 @@ func GetDurangoTime(networkID uint32) time.Time { return DefaultUpgradeTime } -func GetEForkTime(networkID uint32) time.Time { - if upgradeTime, exists := EForkTimes[networkID]; exists { +func GetEUpgradeTime(networkID uint32) time.Time { + if upgradeTime, exists := EUpgradeTimes[networkID]; exists { return upgradeTime } return DefaultUpgradeTime diff --git a/vms/avm/block/executor/block_test.go b/vms/avm/block/executor/block_test.go index c44a69389568..00d7c89264f0 100644 --- a/vms/avm/block/executor/block_test.go +++ b/vms/avm/block/executor/block_test.go @@ -49,8 +49,8 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{}, @@ -74,8 +74,8 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, }, @@ -99,8 +99,8 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, clk: clk, @@ -122,8 +122,8 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{}, @@ -154,8 +154,8 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, mempool: mempool, @@ -192,8 +192,8 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, state: mockState, @@ -234,8 +234,8 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, state: mockState, @@ -279,8 +279,8 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{ @@ -332,8 +332,8 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, mempool: mempool, @@ -390,8 +390,8 @@ func TestBlockVerify(t *testing.T) { metrics: metrics.NewMockMetrics(ctrl), backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{ @@ -473,8 +473,8 @@ func TestBlockVerify(t *testing.T) { metrics: metrics.NewMockMetrics(ctrl), backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{ @@ -536,8 +536,8 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{ @@ -593,8 +593,8 @@ func TestBlockVerify(t *testing.T) { metrics: metrics.NewMockMetrics(ctrl), backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{ @@ -675,8 +675,8 @@ func TestBlockAccept(t *testing.T) { Log: logging.NoLog{}, }, Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{}, @@ -713,8 +713,8 @@ func TestBlockAccept(t *testing.T) { Log: logging.NoLog{}, }, Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{ @@ -761,8 +761,8 @@ func TestBlockAccept(t *testing.T) { Log: logging.NoLog{}, }, Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{ @@ -813,8 +813,8 @@ func TestBlockAccept(t *testing.T) { Log: logging.NoLog{}, }, Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{ @@ -868,8 +868,8 @@ func TestBlockAccept(t *testing.T) { Log: logging.NoLog{}, }, Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{ @@ -969,8 +969,8 @@ func TestBlockReject(t *testing.T) { backend: &executor.Backend{ Bootstrapped: true, Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, Ctx: &snow.Context{ Log: logging.NoLog{}, @@ -1034,8 +1034,8 @@ func TestBlockReject(t *testing.T) { Log: logging.NoLog{}, }, Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, state: mockState, @@ -1088,8 +1088,8 @@ func TestBlockStatus(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, lastAccepted: blockID, @@ -1109,8 +1109,8 @@ func TestBlockStatus(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{ @@ -1136,8 +1136,8 @@ func TestBlockStatus(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{}, @@ -1162,8 +1162,8 @@ func TestBlockStatus(t *testing.T) { manager: &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, blkIDToState: map[ids.ID]*blockState{}, diff --git a/vms/avm/block/executor/manager_test.go b/vms/avm/block/executor/manager_test.go index 89b547eed967..f0200f398a69 100644 --- a/vms/avm/block/executor/manager_test.go +++ b/vms/avm/block/executor/manager_test.go @@ -128,8 +128,8 @@ func TestManagerVerifyTx(t *testing.T) { return &manager{ backend: &executor.Backend{ Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, } @@ -150,8 +150,8 @@ func TestManagerVerifyTx(t *testing.T) { backend: &executor.Backend{ Bootstrapped: true, Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, } @@ -182,8 +182,8 @@ func TestManagerVerifyTx(t *testing.T) { backend: &executor.Backend{ Bootstrapped: true, Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, state: state, @@ -218,8 +218,8 @@ func TestManagerVerifyTx(t *testing.T) { backend: &executor.Backend{ Bootstrapped: true, Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, state: state, @@ -254,8 +254,8 @@ func TestManagerVerifyTx(t *testing.T) { backend: &executor.Backend{ Bootstrapped: true, Config: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }, state: state, diff --git a/vms/avm/config/config.go b/vms/avm/config/config.go index b4da6e3781ea..42e37b678a01 100644 --- a/vms/avm/config/config.go +++ b/vms/avm/config/config.go @@ -17,9 +17,9 @@ type Config struct { DurangoTime time.Time // Time of the E network upgrade - EForkTime time.Time + EUpgradeTime time.Time } -func (c *Config) IsEForkActivated(timestamp time.Time) bool { - return !timestamp.Before(c.EForkTime) +func (c *Config) IsEUpgradeActivated(timestamp time.Time) bool { + return !timestamp.Before(c.EUpgradeTime) } diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index 00a1b2725e47..5675964d1b70 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -151,7 +151,7 @@ func setup(tb testing.TB, c *envConfig) *environment { TxFee: testTxFee, CreateAssetTxFee: testTxFee, DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, } if c.vmStaticConfig != nil { vmStaticConfig = *c.vmStaticConfig diff --git a/vms/avm/index_test.go b/vms/avm/index_test.go index 642410951c9e..f164481590e9 100644 --- a/vms/avm/index_test.go +++ b/vms/avm/index_test.go @@ -34,8 +34,8 @@ func TestIndexTransaction_Ordered(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }) defer func() { @@ -81,8 +81,8 @@ func TestIndexTransaction_MultipleTransactions(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }) defer func() { @@ -132,8 +132,8 @@ func TestIndexTransaction_MultipleAddresses(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }) defer func() { diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index 62f81d08f48c..8a080c6137b6 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -705,8 +705,8 @@ func TestServiceGetTxJSON_CreateAssetTx(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, @@ -824,8 +824,8 @@ func TestServiceGetTxJSON_OperationTxWithNftxMintOp(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, @@ -926,8 +926,8 @@ func TestServiceGetTxJSON_OperationTxWithMultipleNftxMintOp(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, @@ -1067,8 +1067,8 @@ func TestServiceGetTxJSON_OperationTxWithSecpMintOp(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, @@ -1173,8 +1173,8 @@ func TestServiceGetTxJSON_OperationTxWithMultipleSecpMintOp(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, @@ -1322,8 +1322,8 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOp(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, @@ -1425,8 +1425,8 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, diff --git a/vms/avm/txs/executor/syntactic_verifier_test.go b/vms/avm/txs/executor/syntactic_verifier_test.go index 3b5c05d42d07..cc160ed79823 100644 --- a/vms/avm/txs/executor/syntactic_verifier_test.go +++ b/vms/avm/txs/executor/syntactic_verifier_test.go @@ -32,7 +32,7 @@ var ( TxFee: 2, CreateAssetTxFee: 3, DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, } ) diff --git a/vms/avm/vm_regression_test.go b/vms/avm/vm_regression_test.go index 1e4720f80fe1..2412c4e9a70c 100644 --- a/vms/avm/vm_regression_test.go +++ b/vms/avm/vm_regression_test.go @@ -27,8 +27,8 @@ func TestVerifyFxUsage(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }) env.vm.ctx.Lock.Unlock() diff --git a/vms/avm/vm_test.go b/vms/avm/vm_test.go index f7c7d11af0ea..a01aefd349d0 100644 --- a/vms/avm/vm_test.go +++ b/vms/avm/vm_test.go @@ -135,8 +135,8 @@ func TestIssueNFT(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }) env.vm.ctx.Lock.Unlock() @@ -239,8 +239,8 @@ func TestIssueProperty(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, @@ -529,8 +529,8 @@ func TestIssueImportTx(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, }) defer func() { @@ -632,8 +632,8 @@ func TestForceAcceptImportTx(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, }, notLinearized: true, }) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 15ca13e2e109..92892df75ae2 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -316,7 +316,7 @@ func defaultConfig() *config.Config { ApricotPhase5Time: defaultValidateEndTime, BanffTime: time.Time{}, // neglecting fork ordering this for package tests DurangoTime: time.Time{}, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, } } diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index f134ecd73dd8..9b98681c44cd 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -344,7 +344,7 @@ func defaultConfig() *config.Config { ApricotPhase5Time: defaultValidateEndTime, BanffTime: mockable.MaxTime, DurangoTime: mockable.MaxTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, } } diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 292981ddc021..0ac37f81f08e 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -108,7 +108,7 @@ type Config struct { DurangoTime time.Time // Time of the E network upgrade - EForkTime time.Time + EUpgradeTime time.Time // UseCurrentHeight forces [GetMinimumHeight] to return the current height // of the P-Chain instead of the oldest block in the [recentlyAccepted] @@ -141,7 +141,7 @@ func (c *Config) IsDurangoActivated(timestamp time.Time) bool { } func (c *Config) IsEForkActivated(timestamp time.Time) bool { - return !timestamp.Before(c.EForkTime) + return !timestamp.Before(c.EUpgradeTime) } func (c *Config) GetCreateBlockchainTxFee(timestamp time.Time) uint64 { diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index ce59a27e1467..3d6683529cca 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -308,7 +308,7 @@ func defaultConfig(postBanff, postCortina, postDurango bool) *config.Config { BanffTime: banffTime, CortinaTime: cortinaTime, DurangoTime: durangoTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, } } diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index c874e884561d..aa602725083f 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -112,8 +112,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ Ctx: ctx, Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EForkTime: mockable.MaxTime, + DurangoTime: activeForkTime, // activate latest fork + EUpgradeTime: mockable.MaxTime, }, } }, @@ -134,8 +134,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ Ctx: ctx, Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EForkTime: mockable.MaxTime, + DurangoTime: activeForkTime, // activate latest fork + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, } @@ -161,9 +161,9 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ Ctx: ctx, Config: &config.Config{ - CortinaTime: activeForkTime, - DurangoTime: mockable.MaxTime, - EForkTime: mockable.MaxTime, + CortinaTime: activeForkTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -189,8 +189,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ Ctx: ctx, Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EForkTime: mockable.MaxTime, + DurangoTime: activeForkTime, // activate latest fork + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -219,8 +219,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ Ctx: ctx, Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EForkTime: mockable.MaxTime, + DurangoTime: activeForkTime, // activate latest fork + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -249,8 +249,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ Ctx: ctx, Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EForkTime: mockable.MaxTime, + DurangoTime: activeForkTime, // activate latest fork + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -280,8 +280,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ Ctx: ctx, Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EForkTime: mockable.MaxTime, + DurangoTime: activeForkTime, // activate latest fork + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -314,8 +314,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ Ctx: ctx, Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EForkTime: mockable.MaxTime, + DurangoTime: activeForkTime, // activate latest fork + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -348,8 +348,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ Ctx: ctx, Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EForkTime: mockable.MaxTime, + DurangoTime: activeForkTime, // activate latest fork + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -384,8 +384,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ Ctx: ctx, Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EForkTime: mockable.MaxTime, + DurangoTime: activeForkTime, // activate latest fork + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -414,8 +414,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ Ctx: ctx, Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EForkTime: mockable.MaxTime, + DurangoTime: activeForkTime, // activate latest fork + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: bootstrapped, } @@ -462,7 +462,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Config: &config.Config{ AddSubnetValidatorFee: 1, DurangoTime: activeForkTime, // activate latest fork, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }, Ctx: ctx, Bootstrapped: bootstrapped, @@ -509,7 +509,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Config: &config.Config{ CortinaTime: activeForkTime, DurangoTime: mockable.MaxTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, AddSubnetValidatorFee: 1, }, Ctx: ctx, @@ -562,7 +562,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Config: &config.Config{ AddSubnetValidatorFee: 1, DurangoTime: activeForkTime, // activate latest fork, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }, Ctx: ctx, Bootstrapped: bootstrapped, diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index aac52b571935..6fd7fd0bc1f9 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -1749,10 +1749,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1777,10 +1777,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1806,10 +1806,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1838,10 +1838,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1868,10 +1868,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1897,10 +1897,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1928,10 +1928,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1962,10 +1962,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -2120,10 +2120,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -2148,10 +2148,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -2181,7 +2181,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, MaxStakeDuration: math.MaxInt64, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -2215,7 +2215,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, MaxStakeDuration: math.MaxInt64, }, Bootstrapped: &utils.Atomic[bool]{}, @@ -2255,7 +2255,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { BanffTime: env.latestForkTime, CortinaTime: env.latestForkTime, DurangoTime: env.latestForkTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, MaxStakeDuration: math.MaxInt64, }, Bootstrapped: &utils.Atomic[bool]{}, diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 7a879123af20..9a0fd7f88528 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -625,7 +625,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { ApricotPhase5Time: forkTime, BanffTime: forkTime, CortinaTime: forkTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }} vm.clock.Set(forkTime.Add(time.Second)) diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 761a4ad0812d..4335ae460034 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -374,7 +374,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { BanffTime: latestForkTime, CortinaTime: mockable.MaxTime, DurangoTime: mockable.MaxTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }} ctx := snowtest.Context(t, snowtest.PChainID) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 5af9deb95db4..94e158582cce 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -254,7 +254,7 @@ func defaultVM(t *testing.T, fork activeFork) (*VM, database.Database, *mutableS BanffTime: banffTime, CortinaTime: cortinaTime, DurangoTime: durangoTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }} db := memdb.New() @@ -1113,7 +1113,7 @@ func TestRestartFullyAccepted(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }} firstCtx := snowtest.Context(t, snowtest.PChainID) @@ -1201,7 +1201,7 @@ func TestRestartFullyAccepted(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }} secondCtx := snowtest.Context(t, snowtest.PChainID) @@ -1252,7 +1252,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }} initialClkTime := latestForkTime.Add(time.Second) @@ -1594,7 +1594,7 @@ func TestUnverifiedParent(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }} initialClkTime := latestForkTime.Add(time.Second) @@ -1755,7 +1755,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }} firstCtx := snowtest.Context(t, snowtest.PChainID) @@ -1804,7 +1804,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }} secondCtx := snowtest.Context(t, snowtest.PChainID) @@ -1904,7 +1904,7 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, - EForkTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }} ctx := snowtest.Context(t, snowtest.PChainID) From e01eb83263386717e4a808774dc81304a366048c Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 2 Feb 2024 09:12:54 +0100 Subject: [PATCH 004/100] introduced fees calculator in P-chain --- vms/platformvm/txs/executor/import_test.go | 2 +- .../txs/executor/staker_tx_verification.go | 80 ++++++-- .../txs/executor/standard_tx_executor.go | 67 +++++- .../txs/executor/standard_tx_executor_test.go | 192 ++++++++++-------- vms/platformvm/txs/fees/calculator.go | 104 ++++++++++ 5 files changed, 337 insertions(+), 108 deletions(-) create mode 100644 vms/platformvm/txs/fees/calculator.go diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index fed09bd882ce..d513de619d35 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -137,7 +137,7 @@ func TestNewImportTx(t *testing.T) { }, ), sourceKeys: []*secp256k1.PrivateKey{sourceKey}, - timestamp: env.config.BanffTime, + timestamp: env.config.ApricotPhase5Time, expectedErr: nil, }, } diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index ea9343f11058..092333fb9dc4 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -15,6 +15,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" safemath "github.com/ava-labs/avalanchego/utils/math" ) @@ -164,6 +165,14 @@ func verifyAddValidatorTx( } // Verify the flowcheck + feeCalculator := fees.Calculator{ + Config: backend.Config, + ChainTime: currentTimestamp, + } + if err := tx.Visit(&feeCalculator); err != nil { + return nil, err + } + if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -171,7 +180,7 @@ func verifyAddValidatorTx( outs, sTx.Creds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: backend.Config.AddPrimaryNetworkValidatorFee, + backend.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return nil, fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -254,6 +263,14 @@ func verifyAddSubnetValidatorTx( } // Verify the flowcheck + feeCalculator := fees.Calculator{ + Config: backend.Config, + ChainTime: currentTimestamp, + } + if err := tx.Visit(&feeCalculator); err != nil { + return err + } + if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -261,7 +278,7 @@ func verifyAddSubnetValidatorTx( tx.Outs, baseTxCreds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: backend.Config.AddSubnetValidatorFee, + backend.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -331,6 +348,14 @@ func verifyRemoveSubnetValidatorTx( } // Verify the flowcheck + feeCalculator := fees.Calculator{ + Config: backend.Config, + ChainTime: chainState.GetTimestamp(), + } + if err := tx.Visit(&feeCalculator); err != nil { + return nil, false, err + } + if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -338,7 +363,7 @@ func verifyRemoveSubnetValidatorTx( tx.Outs, baseTxCreds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: backend.Config.TxFee, + backend.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return nil, false, fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -446,6 +471,14 @@ func verifyAddDelegatorTx( } // Verify the flowcheck + feeCalculator := fees.Calculator{ + Config: backend.Config, + ChainTime: chainState.GetTimestamp(), + } + if err := tx.Visit(&feeCalculator); err != nil { + return nil, err + } + if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -453,7 +486,7 @@ func verifyAddDelegatorTx( outs, sTx.Creds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: backend.Config.AddPrimaryNetworkDelegatorFee, + backend.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return nil, fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -554,15 +587,10 @@ func verifyAddPermissionlessValidatorTx( ) } - var txFee uint64 if tx.Subnet != constants.PrimaryNetworkID { if err := verifySubnetValidatorPrimaryNetworkRequirements(isDurangoActive, chainState, tx.Validator); err != nil { return err } - - txFee = backend.Config.AddSubnetValidatorFee - } else { - txFee = backend.Config.AddPrimaryNetworkValidatorFee } outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.StakeOuts)) @@ -570,6 +598,14 @@ func verifyAddPermissionlessValidatorTx( copy(outs[len(tx.Outs):], tx.StakeOuts) // Verify the flowcheck + feeCalculator := fees.Calculator{ + Config: backend.Config, + ChainTime: currentTimestamp, + } + if err := tx.Visit(&feeCalculator); err != nil { + return err + } + if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -577,7 +613,7 @@ func verifyAddPermissionlessValidatorTx( outs, sTx.Creds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: txFee, + backend.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -701,7 +737,6 @@ func verifyAddPermissionlessDelegatorTx( copy(outs, tx.Outs) copy(outs[len(tx.Outs):], tx.StakeOuts) - var txFee uint64 if tx.Subnet != constants.PrimaryNetworkID { // Invariant: Delegators must only be able to reference validator // transactions that implement [txs.ValidatorTx]. All @@ -712,10 +747,15 @@ func verifyAddPermissionlessDelegatorTx( if validator.Priority.IsPermissionedValidator() { return ErrDelegateToPermissionedValidator } + } - txFee = backend.Config.AddSubnetDelegatorFee - } else { - txFee = backend.Config.AddPrimaryNetworkDelegatorFee + // Verify the flowcheck + feeCalculator := fees.Calculator{ + Config: backend.Config, + ChainTime: currentTimestamp, + } + if err := tx.Visit(&feeCalculator); err != nil { + return err } // Verify the flowcheck @@ -726,7 +766,7 @@ func verifyAddPermissionlessDelegatorTx( outs, sTx.Creds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: txFee, + backend.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -772,6 +812,14 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck + feeCalculator := fees.Calculator{ + Config: backend.Config, + ChainTime: chainState.GetTimestamp(), + } + if err := tx.Visit(&feeCalculator); err != nil { + return err + } + if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -779,7 +827,7 @@ func verifyTransferSubnetOwnershipTx( tx.Outs, baseTxCreds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: backend.Config.TxFee, + backend.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index aa3ea9a2aafe..29220ffee0b4 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" ) var ( @@ -68,7 +69,14 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - createBlockchainTxFee := e.Config.GetCreateBlockchainTxFee(currentTimestamp) + feeCalculator := fees.Calculator{ + Config: e.Backend.Config, + ChainTime: e.State.GetTimestamp(), + } + if err := tx.Visit(&feeCalculator); err != nil { + return err + } + if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -76,7 +84,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { tx.Outs, baseTxCreds, map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: createBlockchainTxFee, + e.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return err @@ -114,7 +122,14 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } // Verify the flowcheck - createSubnetTxFee := e.Config.GetCreateSubnetTxFee(currentTimestamp) + feeCalculator := fees.Calculator{ + Config: e.Backend.Config, + ChainTime: e.State.GetTimestamp(), + } + if err := tx.Visit(&feeCalculator); err != nil { + return err + } + if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -122,7 +137,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { tx.Outs, e.Tx.Creds, map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: createSubnetTxFee, + e.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return err @@ -194,6 +209,15 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins, tx.Ins) copy(ins[len(tx.Ins):], tx.ImportedInputs) + // Verify the flowcheck + feeCalculator := fees.Calculator{ + Config: e.Backend.Config, + ChainTime: e.State.GetTimestamp(), + } + if err := tx.Visit(&feeCalculator); err != nil { + return err + } + if err := e.FlowChecker.VerifySpendUTXOs( tx, utxos, @@ -201,7 +225,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { tx.Outs, e.Tx.Creds, map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: e.Config.TxFee, + e.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return err @@ -250,6 +274,14 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck + feeCalculator := fees.Calculator{ + Config: e.Backend.Config, + ChainTime: e.State.GetTimestamp(), + } + if err := tx.Visit(&feeCalculator); err != nil { + return err + } + if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -257,7 +289,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { outs, e.Tx.Creds, map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: e.Config.TxFee, + e.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return fmt.Errorf("failed verifySpend: %w", err) @@ -436,6 +468,13 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error } totalRewardAmount := tx.MaximumSupply - tx.InitialSupply + feeCalculator := fees.Calculator{ + Config: e.Backend.Config, + ChainTime: currentTimestamp, + } + if err := tx.Visit(&feeCalculator); err != nil { + return err + } if err := e.Backend.FlowChecker.VerifySpend( tx, e.State, @@ -446,7 +485,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error // entry in this map literal from being overwritten by the // second entry. map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: e.Config.TransformSubnetTxFee, + e.Ctx.AVAXAssetID: feeCalculator.Fee, tx.AssetID: totalRewardAmount, }, ); err != nil { @@ -555,6 +594,18 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { } // Verify the flowcheck + var ( + cfg = e.Backend.Config + currentTimestamp = e.State.GetTimestamp() + ) + feeCalculator := fees.Calculator{ + Config: cfg, + ChainTime: currentTimestamp, + } + if err := tx.Visit(&feeCalculator); err != nil { + return err + } + if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -562,7 +613,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { tx.Outs, e.Tx.Creds, map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: e.Config.TxFee, + e.Ctx.AVAXAssetID: feeCalculator.Fee, }, ); err != nil { return err diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 6fd7fd0bc1f9..eacd9ac57dc8 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -1735,7 +1735,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) // Set dependency expectations. - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil).Times(1) subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil).Times(1) @@ -1746,14 +1746,16 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().DeleteCurrentValidator(env.staker) env.state.EXPECT().DeleteUTXO(gomock.Any()).Times(len(env.unsignedTx.Ins)) env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + } e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1774,14 +1776,16 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { // Setting the subnet ID to the Primary Network ID makes the tx fail syntactic verification env.tx.Unsigned.(*txs.RemoveSubnetValidatorTx).Subnet = constants.PrimaryNetworkID env.state = state.NewMockDiff(ctrl) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + } e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1803,14 +1807,16 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) env.state.EXPECT().GetPendingValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + } e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1835,14 +1841,16 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { // Set dependency expectations. env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(&staker, nil).Times(1) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + } e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1865,14 +1873,16 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + } e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1894,14 +1904,16 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + } e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1925,14 +1937,16 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil) env.fx.EXPECT().VerifyPermission(gomock.Any(), env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(errTest) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + } e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1951,7 +1965,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { newExecutor: func(ctrl *gomock.Controller) (*txs.RemoveSubnetValidatorTx, *StandardTxExecutor) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil) @@ -1959,14 +1973,16 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.flowChecker.EXPECT().VerifySpend( gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), ).Return(errTest) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + } e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -2117,14 +2133,16 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { // Setting the tx to nil makes the tx fail syntactic verification env.tx.Unsigned = (*txs.TransformSubnetTx)(nil) env.state = state.NewMockDiff(ctrl) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + } e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -2144,15 +2162,17 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env := newValidTransformSubnetTxVerifyEnv(t, ctrl) env.unsignedTx.MaxStakeDuration = math.MaxUint32 env.state = state.NewMockDiff(ctrl) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + } env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -2173,16 +2193,18 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { // Remove credentials env.tx.Creds = nil env.state = state.NewMockDiff(ctrl) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + MaxStakeDuration: math.MaxInt64, + } env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - MaxStakeDuration: math.MaxInt64, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -2209,15 +2231,17 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.flowChecker.EXPECT().VerifySpend( gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), ).Return(ErrFlowCheckFailed) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + MaxStakeDuration: math.MaxInt64, + } e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - MaxStakeDuration: math.MaxInt64, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -2249,15 +2273,17 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state.EXPECT().SetCurrentSupply(env.unsignedTx.Subnet, env.unsignedTx.InitialSupply) env.state.EXPECT().DeleteUTXO(gomock.Any()).Times(len(env.unsignedTx.Ins)) env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) + + cfg := &config.Config{ + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, + EUpgradeTime: mockable.MaxTime, + MaxStakeDuration: math.MaxInt64, + } e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - MaxStakeDuration: math.MaxInt64, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go new file mode 100644 index 000000000000..123052577e54 --- /dev/null +++ b/vms/platformvm/txs/fees/calculator.go @@ -0,0 +1,104 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fees + +import ( + "time" + + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/vms/platformvm/config" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" +) + +var _ txs.Visitor = (*Calculator)(nil) + +type Calculator struct { + // Pre E-fork inputs + Config *config.Config + ChainTime time.Time + + // outputs of visitor execution + Fee uint64 +} + +func (fc *Calculator) AddValidatorTx(*txs.AddValidatorTx) error { + fc.Fee = fc.Config.AddPrimaryNetworkValidatorFee + return nil +} + +func (fc *Calculator) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { + fc.Fee = fc.Config.AddSubnetValidatorFee + return nil +} + +func (fc *Calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { + fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee + return nil +} + +func (fc *Calculator) CreateChainTx(*txs.CreateChainTx) error { + fc.Fee = fc.Config.GetCreateBlockchainTxFee(fc.ChainTime) + return nil +} + +func (fc *Calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { + fc.Fee = fc.Config.GetCreateSubnetTxFee(fc.ChainTime) + return nil +} + +func (*Calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + return nil // no fees +} + +func (*Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { + return nil // no fees +} + +func (fc *Calculator) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { + fc.Fee = fc.Config.TxFee + return nil +} + +func (fc *Calculator) TransformSubnetTx(*txs.TransformSubnetTx) error { + fc.Fee = fc.Config.TransformSubnetTxFee + return nil +} + +func (fc *Calculator) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { + fc.Fee = fc.Config.TxFee + return nil +} + +func (fc *Calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { + if tx.Subnet != constants.PrimaryNetworkID { + fc.Fee = fc.Config.AddSubnetValidatorFee + } else { + fc.Fee = fc.Config.AddPrimaryNetworkValidatorFee + } + return nil +} + +func (fc *Calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { + if tx.Subnet != constants.PrimaryNetworkID { + fc.Fee = fc.Config.AddSubnetDelegatorFee + } else { + fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee + } + return nil +} + +func (fc *Calculator) BaseTx(*txs.BaseTx) error { + fc.Fee = fc.Config.TxFee + return nil +} + +func (fc *Calculator) ImportTx(*txs.ImportTx) error { + fc.Fee = fc.Config.TxFee + return nil +} + +func (fc *Calculator) ExportTx(*txs.ExportTx) error { + fc.Fee = fc.Config.TxFee + return nil +} From 62ab6d03ec03bd6be3973820b56d11f9acd0efe1 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 2 Feb 2024 09:39:30 +0100 Subject: [PATCH 005/100] upgraded codec for dynamic fees --- codec/manager.go | 6 +- codec/reflectcodec/type_codec.go | 16 ++--- codec/test_codec.go | 81 ++++++++++++++++++++++ vms/platformvm/state/metadata_validator.go | 3 +- 4 files changed, 94 insertions(+), 12 deletions(-) diff --git a/codec/manager.go b/codec/manager.go index 6fb48aaad9f8..bf1ad3af72bc 100644 --- a/codec/manager.go +++ b/codec/manager.go @@ -13,6 +13,8 @@ import ( ) const ( + CodecVersionSize = wrappers.ShortLen + // default max size, in bytes, of something being marshalled by Marshal() defaultMaxSize = 256 * units.KiB @@ -102,8 +104,8 @@ func (m *manager) Size(version uint16, value interface{}) (int, error) { res, err := c.Size(value) - // Add [wrappers.ShortLen] for the codec version - return wrappers.ShortLen + res, err + // Add [CodecVersionSize] for the codec version + return CodecVersionSize + res, err } // To marshal an interface, [value] must be a pointer to the interface. diff --git a/codec/reflectcodec/type_codec.go b/codec/reflectcodec/type_codec.go index 312927559280..e8b19e80fe83 100644 --- a/codec/reflectcodec/type_codec.go +++ b/codec/reflectcodec/type_codec.go @@ -27,8 +27,6 @@ const ( var ( _ codec.Codec = (*genericCodec)(nil) - errMarshalNil = errors.New("can't marshal nil pointer or interface") - errUnmarshalNil = errors.New("can't unmarshal nil") errNeedPointer = errors.New("argument to unmarshal must be a pointer") errRecursiveInterfaceTypes = errors.New("recursive interface types") ) @@ -90,7 +88,7 @@ func New(typer TypeCodec, tagNames []string, durangoTime time.Time, maxSliceLen func (c *genericCodec) Size(value interface{}) (int, error) { if value == nil { - return 0, errMarshalNil // can't marshal nil + return 0, nil // can't marshal nil, we return zero size } size, _, err := c.size(reflect.ValueOf(value), nil /*=typeStack*/) @@ -126,14 +124,14 @@ func (c *genericCodec) size( return wrappers.StringLen(value.String()), false, nil case reflect.Ptr: if value.IsNil() { - return 0, false, errMarshalNil + return 0, false, nil // can't marshal nil, we return zero size } return c.size(value.Elem(), typeStack) case reflect.Interface: if value.IsNil() { - return 0, false, errMarshalNil + return 0, false, nil // can't marshal nil, we return zero size } underlyingValue := value.Interface() @@ -292,7 +290,7 @@ func (c *genericCodec) size( // To marshal an interface, [value] must be a pointer to the interface func (c *genericCodec) MarshalInto(value interface{}, p *wrappers.Packer) error { if value == nil { - return errMarshalNil // can't marshal nil + return codec.ErrMarshalNil // can't marshal nil } return c.marshal(reflect.ValueOf(value), p, nil /*=typeStack*/) @@ -339,13 +337,13 @@ func (c *genericCodec) marshal( return p.Err case reflect.Ptr: if value.IsNil() { - return errMarshalNil + return codec.ErrMarshalNil } return c.marshal(value.Elem(), p, typeStack) case reflect.Interface: if value.IsNil() { - return errMarshalNil + return codec.ErrMarshalNil } underlyingValue := value.Interface() @@ -505,7 +503,7 @@ func (c *genericCodec) marshal( // interface func (c *genericCodec) Unmarshal(bytes []byte, dest interface{}) error { if dest == nil { - return errUnmarshalNil + return codec.ErrUnmarshalNil } p := wrappers.Packer{ diff --git a/codec/test_codec.go b/codec/test_codec.go index d58e2d818f9e..ed484042941b 100644 --- a/codec/test_codec.go +++ b/codec/test_codec.go @@ -15,6 +15,8 @@ import ( var ( Tests = []func(c GeneralCodec, t testing.TB){ TestStruct, + TestPartiallyFilledStruct, + TestSliceWithEmptyElements, TestRegisterStructTwice, TestUInt32, TestUIntPtr, @@ -249,6 +251,85 @@ func TestStruct(codec GeneralCodec, t testing.TB) { require.Equal(myStructInstance, *myStructUnmarshaled) } +func TestPartiallyFilledStruct(codec GeneralCodec, t testing.TB) { + require := require.New(t) + + manager := NewDefaultManager() + require.NoError(manager.RegisterCodec(0, codec)) + + // a nil pointer cannot be marshalled but we can get its size + var nilStruct *myStruct + _, err := manager.Marshal(0, nilStruct) + require.ErrorIs(err, ErrMarshalNil) + + bytesLen, err := manager.Size(0, nilStruct) + require.NoError(err) + require.Equal(CodecVersionSize, bytesLen) + + // an empty struct cannot be marshalled but we can get its size + emptyStruct := &myStruct{} + _, err = manager.Marshal(0, nilStruct) + require.ErrorIs(err, ErrMarshalNil) + + emptyStructLen := CodecVersionSize + 117 + bytesLen, err = manager.Size(0, emptyStruct) + require.NoError(err) + require.Equal(emptyStructLen, bytesLen) + + // an partially filled struct cannot be marshalled but we can get its size + elem := &MyInnerStruct{ + Str: "a", + } + elemLen := CodecVersionSize + wrappers.StringLen(elem.Str) + + partialStruct := &myStruct{ + InnerStruct2: elem, + } + partialStructLen := emptyStructLen + elemLen - CodecVersionSize + bytesLen, err = manager.Size(0, partialStruct) + require.NoError(err) + require.Equal(partialStructLen, bytesLen) +} + +func TestSliceWithEmptyElements(codec GeneralCodec, t testing.TB) { + require := require.New(t) + + manager := NewDefaultManager() + require.NoError(manager.RegisterCodec(0, codec)) + + // a non-empty slice with nil pointers cannot be marshalled but we can get its size + slice := make([]*MyInnerStruct, 10) + + _, err := manager.Marshal(0, slice) + require.ErrorIs(err, ErrMarshalNil) + + emptySliceLen := CodecVersionSize + wrappers.IntLen // Codec version + slice size. Slice elements have zero size + bytesLen, err := manager.Size(0, slice) + require.NoError(err) + require.Equal(emptySliceLen, bytesLen) + + elem := &MyInnerStruct{ + Str: "aaa", + } + elemLen := CodecVersionSize + wrappers.StringLen(elem.Str) + bytesLen, err = manager.Size(0, elem) + require.NoError(err) + require.Equal(elemLen, bytesLen) + + // we can fill some elements and leave other empty. Size will be sub-additive + slice[1] = elem + sliceLen := emptySliceLen + elemLen - CodecVersionSize // codec version is marshelled only once + bytesLen, err = manager.Size(0, slice) + require.NoError(err) + require.Equal(sliceLen, bytesLen) + + slice[5] = elem + sliceLen += elemLen - CodecVersionSize // codec version is marshelled only once + bytesLen, err = manager.Size(0, slice) + require.NoError(err) + require.Equal(sliceLen, bytesLen) +} + func TestRegisterStructTwice(codec GeneralCodec, t testing.TB) { require := require.New(t) diff --git a/vms/platformvm/state/metadata_validator.go b/vms/platformvm/state/metadata_validator.go index 0c725368505b..74242150d37f 100644 --- a/vms/platformvm/state/metadata_validator.go +++ b/vms/platformvm/state/metadata_validator.go @@ -6,6 +6,7 @@ package state import ( "time" + "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" @@ -17,7 +18,7 @@ import ( // [preDelegateeRewardMetadata]. // // CodecVersionLen + UpDurationLen + LastUpdatedLen + PotentialRewardLen -const preDelegateeRewardSize = wrappers.ShortLen + 3*wrappers.LongLen +const preDelegateeRewardSize = codec.CodecVersionSize + 3*wrappers.LongLen var _ validatorState = (*metadata)(nil) From 3daec3411519365d01497e0e7a920e110b2e245d Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 8 Feb 2024 23:36:17 +0100 Subject: [PATCH 006/100] cleanup --- vms/platformvm/block/builder/builder_test.go | 18 ++--- vms/platformvm/block/builder/helpers_test.go | 58 ++++++++++++++--- .../block/builder/standard_block_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 57 +++++++++++++--- .../block/executor/proposal_block_test.go | 16 ++--- .../block/executor/standard_block_test.go | 14 ++-- .../txs/executor/advance_time_test.go | 22 +++---- .../txs/executor/create_chain_test.go | 10 +-- .../txs/executor/create_subnet_test.go | 2 +- vms/platformvm/txs/executor/export_test.go | 2 +- vms/platformvm/txs/executor/helpers_test.go | 65 +++++++++++++------ vms/platformvm/txs/executor/import_test.go | 2 +- .../txs/executor/proposal_tx_executor_test.go | 8 +-- .../txs/executor/reward_validator_test.go | 12 ++-- .../txs/executor/standard_tx_executor_test.go | 14 ++-- vms/platformvm/vm_test.go | 7 +- 16 files changed, 212 insertions(+), 97 deletions(-) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 56f189cb986a..039bcc92b0c8 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -33,7 +33,7 @@ import ( func TestBuildBlockBasic(t *testing.T) { require := require.New(t) - env := newEnvironment(t) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -75,7 +75,7 @@ func TestBuildBlockBasic(t *testing.T) { func TestBuildBlockDoesNotBuildWithEmptyMempool(t *testing.T) { require := require.New(t) - env := newEnvironment(t) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -92,7 +92,7 @@ func TestBuildBlockDoesNotBuildWithEmptyMempool(t *testing.T) { func TestBuildBlockShouldReward(t *testing.T) { require := require.New(t) - env := newEnvironment(t) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -193,7 +193,7 @@ func TestBuildBlockShouldReward(t *testing.T) { func TestBuildBlockAdvanceTime(t *testing.T) { require := require.New(t) - env := newEnvironment(t) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -226,7 +226,7 @@ func TestBuildBlockAdvanceTime(t *testing.T) { func TestBuildBlockForceAdvanceTime(t *testing.T) { require := require.New(t) - env := newEnvironment(t) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -280,7 +280,7 @@ func TestBuildBlockForceAdvanceTime(t *testing.T) { func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { require := require.New(t) - env := newEnvironment(t) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -383,7 +383,7 @@ func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { func TestBuildBlockInvalidStakingDurations(t *testing.T) { require := require.New(t) - env := newEnvironment(t) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -467,7 +467,7 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { func TestPreviouslyDroppedTxsCannotBeReAddedToMempool(t *testing.T) { require := require.New(t) - env := newEnvironment(t) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -510,7 +510,7 @@ func TestPreviouslyDroppedTxsCannotBeReAddedToMempool(t *testing.T) { func TestNoErrorOnUnexpectedSetPreferenceDuringBootstrapping(t *testing.T) { require := require.New(t) - env := newEnvironment(t) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 92892df75ae2..27b6573c05fe 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -5,6 +5,7 @@ package builder import ( "context" + "fmt" "testing" "time" @@ -58,8 +59,17 @@ import ( const ( defaultWeight = 10000 trackChecksum = false + + apricotPhase3 activeFork = iota + apricotPhase5 + banffFork + cortinaFork + durangoFork + eUpgradeFork ) +type activeFork uint8 + var ( defaultMinStakingDuration = 24 * time.Hour defaultMaxStakingDuration = 365 * 24 * time.Hour @@ -111,12 +121,12 @@ type environment struct { backend txexecutor.Backend } -func newEnvironment(t *testing.T) *environment { +func newEnvironment(t *testing.T, fork activeFork) *environment { //nolint:unparam require := require.New(t) res := &environment{ isBootstrapped: &utils.Atomic[bool]{}, - config: defaultConfig(), + config: defaultConfig(t, fork), clk: defaultClock(), } res.isBootstrapped.Set(true) @@ -293,7 +303,38 @@ func defaultState( return state } -func defaultConfig() *config.Config { +func defaultConfig(t *testing.T, fork activeFork) *config.Config { + var ( + apricotPhase3Time = mockable.MaxTime + apricotPhase5Time = mockable.MaxTime + banffTime = mockable.MaxTime + cortinaTime = mockable.MaxTime + durangoTime = mockable.MaxTime + eUpgradeTime = mockable.MaxTime + ) + + switch fork { + case eUpgradeFork: + eUpgradeTime = time.Time{} // neglecting fork ordering this for package tests + fallthrough + case durangoFork: + durangoTime = time.Time{} // neglecting fork ordering this for package tests + fallthrough + case cortinaFork: + cortinaTime = time.Time{} // neglecting fork ordering this for package tests + fallthrough + case banffFork: + banffTime = time.Time{} // neglecting fork ordering this for package tests + fallthrough + case apricotPhase5: + apricotPhase5Time = defaultValidateEndTime + fallthrough + case apricotPhase3: + apricotPhase3Time = defaultValidateEndTime + default: + require.NoError(t, fmt.Errorf("unhandled fork %d", fork)) + } + return &config.Config{ Chains: chains.TestManager, UptimeLockedCalculator: uptime.NewLockedCalculator(), @@ -312,11 +353,12 @@ func defaultConfig() *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - ApricotPhase3Time: defaultValidateEndTime, - ApricotPhase5Time: defaultValidateEndTime, - BanffTime: time.Time{}, // neglecting fork ordering this for package tests - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, + ApricotPhase3Time: apricotPhase3Time, + ApricotPhase5Time: apricotPhase5Time, + BanffTime: banffTime, + CortinaTime: cortinaTime, + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, } } diff --git a/vms/platformvm/block/builder/standard_block_test.go b/vms/platformvm/block/builder/standard_block_test.go index 6064b2153113..f286a9191ecf 100644 --- a/vms/platformvm/block/builder/standard_block_test.go +++ b/vms/platformvm/block/builder/standard_block_test.go @@ -22,7 +22,7 @@ import ( func TestAtomicTxImports(t *testing.T) { require := require.New(t) - env := newEnvironment(t) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 9b98681c44cd..26eb69ada86d 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -61,8 +61,17 @@ const ( defaultWeight = 10000 trackChecksum = false + + apricotPhase3 activeFork = iota + apricotPhase5 + banffFork + cortinaFork + durangoFork + eUpgradeFork ) +type activeFork uint8 + var ( defaultMinStakingDuration = 24 * time.Hour defaultMaxStakingDuration = 365 * 24 * time.Hour @@ -126,10 +135,10 @@ type environment struct { backend *executor.Backend } -func newEnvironment(t *testing.T, ctrl *gomock.Controller) *environment { +func newEnvironment(t *testing.T, ctrl *gomock.Controller, fork activeFork) *environment { res := &environment{ isBootstrapped: &utils.Atomic[bool]{}, - config: defaultConfig(), + config: defaultConfig(t, fork), clk: defaultClock(), } res.isBootstrapped.Set(true) @@ -321,7 +330,38 @@ func defaultState( return state } -func defaultConfig() *config.Config { +func defaultConfig(t *testing.T, fork activeFork) *config.Config { + var ( + apricotPhase3Time = mockable.MaxTime + apricotPhase5Time = mockable.MaxTime + banffTime = mockable.MaxTime + cortinaTime = mockable.MaxTime + durangoTime = mockable.MaxTime + eUpgradeTime = mockable.MaxTime + ) + + switch fork { + case eUpgradeFork: + eUpgradeTime = time.Time{} // neglecting fork ordering this for package tests + fallthrough + case durangoFork: + durangoTime = time.Time{} // neglecting fork ordering this for package tests + fallthrough + case cortinaFork: + cortinaTime = time.Time{} // neglecting fork ordering this for package tests + fallthrough + case banffFork: + banffTime = time.Time{} // neglecting fork ordering this for package tests + fallthrough + case apricotPhase5: + apricotPhase5Time = defaultValidateEndTime + fallthrough + case apricotPhase3: + apricotPhase3Time = defaultValidateEndTime + default: + require.NoError(t, fmt.Errorf("unhandled fork %d", fork)) + } + return &config.Config{ Chains: chains.TestManager, UptimeLockedCalculator: uptime.NewLockedCalculator(), @@ -340,11 +380,12 @@ func defaultConfig() *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - ApricotPhase3Time: defaultValidateEndTime, - ApricotPhase5Time: defaultValidateEndTime, - BanffTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + ApricotPhase3Time: apricotPhase3Time, + ApricotPhase5Time: apricotPhase5Time, + BanffTime: banffTime, + DurangoTime: durangoTime, + CortinaTime: cortinaTime, + EUpgradeTime: eUpgradeTime, } } diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 33a3877fc24b..7476c4f57726 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -36,7 +36,7 @@ func TestApricotProposalBlockTimeVerification(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - env := newEnvironment(t, ctrl) + env := newEnvironment(t, ctrl, apricotPhase5) // create apricotParentBlk. It's a standard one for simplicity parentHeight := uint64(2022) @@ -139,7 +139,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - env := newEnvironment(t, ctrl) + env := newEnvironment(t, ctrl, banffFork) env.clk.Set(defaultGenesisTime) env.config.BanffTime = time.Time{} // activate Banff env.config.DurangoTime = mockable.MaxTime // deactivate Durango @@ -550,7 +550,7 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { for _, test := range tests { t.Run(test.description, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, nil) + env := newEnvironment(t, nil, banffFork) env.config.BanffTime = time.Time{} // activate Banff subnetID := testSubnet1.ID() @@ -700,7 +700,7 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, nil) + env := newEnvironment(t, nil, banffFork) env.config.BanffTime = time.Time{} // activate Banff subnetID := testSubnet1.ID() @@ -840,7 +840,7 @@ func TestBanffProposalBlockTrackedSubnet(t *testing.T) { for _, tracked := range []bool{true, false} { t.Run(fmt.Sprintf("tracked %t", tracked), func(ts *testing.T) { require := require.New(t) - env := newEnvironment(t, nil) + env := newEnvironment(t, nil, banffFork) env.config.BanffTime = time.Time{} // activate Banff subnetID := testSubnet1.ID() @@ -943,7 +943,7 @@ func TestBanffProposalBlockTrackedSubnet(t *testing.T) { func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { require := require.New(t) - env := newEnvironment(t, nil) + env := newEnvironment(t, nil, banffFork) env.config.BanffTime = time.Time{} // activate Banff // Case: Timestamp is after next validator start time @@ -1125,7 +1125,7 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { func TestBanffProposalBlockDelegatorStakers(t *testing.T) { require := require.New(t) - env := newEnvironment(t, nil) + env := newEnvironment(t, nil, banffFork) env.config.BanffTime = time.Time{} // activate Banff // Case: Timestamp is after next validator start time @@ -1307,7 +1307,7 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { func TestAddValidatorProposalBlock(t *testing.T) { require := require.New(t) - env := newEnvironment(t, nil) + env := newEnvironment(t, nil, apricotPhase5) env.config.BanffTime = time.Time{} // activate Banff env.config.DurangoTime = time.Time{} // activate Durango diff --git a/vms/platformvm/block/executor/standard_block_test.go b/vms/platformvm/block/executor/standard_block_test.go index 3e0122c9123d..54b45b0ab7c4 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -30,7 +30,7 @@ func TestApricotStandardBlockTimeVerification(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - env := newEnvironment(t, ctrl) + env := newEnvironment(t, ctrl, apricotPhase5) // setup and store parent block // it's a standard block for simplicity @@ -83,7 +83,7 @@ func TestBanffStandardBlockTimeVerification(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - env := newEnvironment(t, ctrl) + env := newEnvironment(t, ctrl, banffFork) now := env.clk.Time() env.clk.Set(now) env.config.BanffTime = time.Time{} // activate Banff @@ -291,7 +291,7 @@ func TestBanffStandardBlockTimeVerification(t *testing.T) { func TestBanffStandardBlockUpdatePrimaryNetworkStakers(t *testing.T) { require := require.New(t) - env := newEnvironment(t, nil) + env := newEnvironment(t, nil, banffFork) env.config.BanffTime = time.Time{} // activate Banff // Case: Timestamp is after next validator start time @@ -493,7 +493,7 @@ func TestBanffStandardBlockUpdateStakers(t *testing.T) { for _, test := range tests { t.Run(test.description, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, nil) + env := newEnvironment(t, nil, banffFork) env.config.BanffTime = time.Time{} // activate Banff subnetID := testSubnet1.ID() @@ -592,7 +592,7 @@ func TestBanffStandardBlockUpdateStakers(t *testing.T) { // is after the new timestamp func TestBanffStandardBlockRemoveSubnetValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, nil) + env := newEnvironment(t, nil, banffFork) env.config.BanffTime = time.Time{} // activate Banff subnetID := testSubnet1.ID() @@ -688,7 +688,7 @@ func TestBanffStandardBlockTrackedSubnet(t *testing.T) { for _, tracked := range []bool{true, false} { t.Run(fmt.Sprintf("tracked %t", tracked), func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, nil) + env := newEnvironment(t, nil, banffFork) env.config.BanffTime = time.Time{} // activate Banff subnetID := testSubnet1.ID() @@ -748,7 +748,7 @@ func TestBanffStandardBlockTrackedSubnet(t *testing.T) { func TestBanffStandardBlockDelegatorStakerWeight(t *testing.T) { require := require.New(t) - env := newEnvironment(t, nil) + env := newEnvironment(t, nil, banffFork) env.config.BanffTime = time.Time{} // activate Banff // Case: Timestamp is after next validator start time diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index b7b636ad6dbe..eaab7ca0f04e 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -34,7 +34,7 @@ func newAdvanceTimeTx(t testing.TB, timestamp time.Time) (*txs.Tx, error) { // for the primary network func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() dummyHeight := uint64(1) @@ -97,7 +97,7 @@ func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { // Ensure semantic verification fails when proposed timestamp is at or before current timestamp func TestAdvanceTimeTxTimestampTooEarly(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) tx, err := newAdvanceTimeTx(t, env.state.GetTimestamp()) require.NoError(err) @@ -121,7 +121,7 @@ func TestAdvanceTimeTxTimestampTooEarly(t *testing.T) { // Ensure semantic verification fails when proposed timestamp is after next validator set change time func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -154,7 +154,7 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { } // Case: Timestamp is after next validator end time - env = newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env = newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -354,7 +354,7 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { for _, test := range tests { t.Run(test.description, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -457,7 +457,7 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { // is after the new timestamp func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -559,7 +559,7 @@ func TestTrackedSubnet(t *testing.T) { for _, tracked := range []bool{true, false} { t.Run(fmt.Sprintf("tracked %t", tracked), func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() dummyHeight := uint64(1) @@ -627,7 +627,7 @@ func TestTrackedSubnet(t *testing.T) { func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() dummyHeight := uint64(1) @@ -732,7 +732,7 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() dummyHeight := uint64(1) @@ -826,7 +826,7 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { func TestAdvanceTimeTxAfterBanff(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() env.clk.Set(defaultGenesisTime) // VM's clock reads the genesis time @@ -858,7 +858,7 @@ func TestAdvanceTimeTxAfterBanff(t *testing.T) { // Ensure marshaling/unmarshaling works func TestAdvanceTimeTxUnmarshal(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 0342c8dc1cfe..bfb8097382d4 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -25,7 +25,7 @@ import ( // Ensure Execute fails when there are not enough control sigs func TestCreateChainTxInsufficientControlSigs(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, banffFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -58,7 +58,7 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { // Ensure Execute fails when an incorrect control signature is given func TestCreateChainTxWrongControlSig(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, banffFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -98,7 +98,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { // its validator set doesn't exist func TestCreateChainTxNoSuchSubnet(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, banffFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -130,7 +130,7 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { // Ensure valid tx passes semanticVerify func TestCreateChainTxValid(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, banffFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -187,7 +187,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, banffFork) env.config.ApricotPhase3Time = ap3Time ins, outs, _, signers, err := env.utxosHandler.Spend(env.state, preFundedKeys, 0, test.fee, ids.ShortEmpty) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 6d968daa4df0..a2d59281cc65 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -49,7 +49,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.config.ApricotPhase3Time = ap3Time env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index d9e0ce071008..12aa12de33ef 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -15,7 +15,7 @@ import ( ) func TestNewExportTx(t *testing.T) { - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, banffFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 3d6683529cca..2975d4739f5b 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -51,8 +51,17 @@ import ( const ( defaultWeight = 5 * units.MilliAvax trackChecksum = false + + apricotPhase3 activeFork = iota + apricotPhase5 + banffFork + cortinaFork + durangoFork + eUpgradeFork ) +type activeFork uint8 + var ( defaultMinStakingDuration = 24 * time.Hour defaultMaxStakingDuration = 365 * 24 * time.Hour @@ -112,12 +121,12 @@ func (e *environment) SetState(blkID ids.ID, chainState state.Chain) { e.states[blkID] = chainState } -func newEnvironment(t *testing.T, postBanff, postCortina, postDurango bool) *environment { +func newEnvironment(t *testing.T, fork activeFork) *environment { var isBootstrapped utils.Atomic[bool] isBootstrapped.Set(true) - config := defaultConfig(postBanff, postCortina, postDurango) - clk := defaultClock(postBanff || postCortina || postDurango) + config := defaultConfig(t, fork) + clk := defaultClock(fork) baseDB := versiondb.New(memdb.New()) ctx := snowtest.Context(t, snowtest.PChainID) @@ -271,18 +280,36 @@ func defaultState( return state } -func defaultConfig(postBanff, postCortina, postDurango bool) *config.Config { - banffTime := mockable.MaxTime - if postBanff { - banffTime = defaultValidateEndTime.Add(-2 * time.Second) - } - cortinaTime := mockable.MaxTime - if postCortina { - cortinaTime = defaultValidateStartTime.Add(-2 * time.Second) - } - durangoTime := mockable.MaxTime - if postDurango { +func defaultConfig(t *testing.T, fork activeFork) *config.Config { + var ( + apricotPhase3Time = mockable.MaxTime + apricotPhase5Time = mockable.MaxTime + banffTime = mockable.MaxTime + cortinaTime = mockable.MaxTime + durangoTime = mockable.MaxTime + eUpgradeTime = mockable.MaxTime + ) + + switch fork { + case eUpgradeFork: + eUpgradeTime = defaultValidateStartTime.Add(-2 * time.Second) + fallthrough + case durangoFork: durangoTime = defaultValidateStartTime.Add(-2 * time.Second) + fallthrough + case cortinaFork: + cortinaTime = defaultValidateStartTime.Add(-2 * time.Second) + fallthrough + case banffFork: + banffTime = defaultValidateStartTime.Add(-2 * time.Second) + fallthrough + case apricotPhase5: + apricotPhase5Time = defaultValidateEndTime + fallthrough + case apricotPhase3: + apricotPhase3Time = defaultValidateEndTime + default: + require.NoError(t, fmt.Errorf("unhandled fork %d", fork)) } return &config.Config{ @@ -303,18 +330,18 @@ func defaultConfig(postBanff, postCortina, postDurango bool) *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - ApricotPhase3Time: defaultValidateEndTime, - ApricotPhase5Time: defaultValidateEndTime, + ApricotPhase3Time: apricotPhase3Time, + ApricotPhase5Time: apricotPhase5Time, BanffTime: banffTime, CortinaTime: cortinaTime, DurangoTime: durangoTime, - EUpgradeTime: mockable.MaxTime, + EUpgradeTime: eUpgradeTime, } } -func defaultClock(postFork bool) *mockable.Clock { +func defaultClock(fork activeFork) *mockable.Clock { now := defaultGenesisTime - if postFork { + if fork == eUpgradeFork || fork == durangoFork || fork == cortinaFork || fork == banffFork { // 1 second after Banff fork now = defaultValidateEndTime.Add(-2 * time.Second) } diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index fed09bd882ce..9f1c90dab501 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -22,7 +22,7 @@ import ( ) func TestNewImportTx(t *testing.T) { - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) type test struct { description string diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index e01bd267a024..d16e072a3a10 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -91,7 +91,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { require.NoError(t, target.state.Commit()) } - dummyH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + dummyH := newEnvironment(t, apricotPhase5) currentTimestamp := dummyH.state.GetTimestamp() type test struct { @@ -245,7 +245,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { require := require.New(t) - freshTH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + freshTH := newEnvironment(t, apricotPhase5) freshTH.config.ApricotPhase3Time = tt.AP3Time tx, err := freshTH.txBuilder.NewAddDelegatorTx( @@ -283,7 +283,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -716,7 +716,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { func TestProposalTxExecuteAddValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() diff --git a/vms/platformvm/txs/executor/reward_validator_test.go b/vms/platformvm/txs/executor/reward_validator_test.go index 18ba653a4e79..c9aa34f207d3 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -35,7 +35,7 @@ func newRewardValidatorTx(t testing.TB, txID ids.ID) (*txs.Tx, error) { func TestRewardValidatorTxExecuteOnCommit(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) dummyHeight := uint64(1) currentStakerIterator, err := env.state.GetCurrentStakerIterator() @@ -135,7 +135,7 @@ func TestRewardValidatorTxExecuteOnCommit(t *testing.T) { func TestRewardValidatorTxExecuteOnAbort(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) dummyHeight := uint64(1) currentStakerIterator, err := env.state.GetCurrentStakerIterator() @@ -229,7 +229,7 @@ func TestRewardValidatorTxExecuteOnAbort(t *testing.T) { func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) dummyHeight := uint64(1) vdrRewardAddress := ids.GenerateTestShortID() @@ -350,7 +350,7 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, true /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, cortinaFork) dummyHeight := uint64(1) vdrRewardAddress := ids.GenerateTestShortID() @@ -566,7 +566,7 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, true /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, cortinaFork) dummyHeight := uint64(1) vdrRewardAddress := ids.GenerateTestShortID() @@ -725,7 +725,7 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) dummyHeight := uint64(1) initialSupply, err := env.state.GetCurrentSupply(constants.PrimaryNetworkID) diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 6fd7fd0bc1f9..211bc7424091 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -46,7 +46,7 @@ var errTest = errors.New("non-nil error") func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -168,7 +168,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { require.NoError(t, target.state.Commit()) } - dummyH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + dummyH := newEnvironment(t, apricotPhase5) currentTimestamp := dummyH.state.GetTimestamp() type test struct { @@ -322,7 +322,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { require := require.New(t) - freshTH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + freshTH := newEnvironment(t, apricotPhase5) freshTH.config.ApricotPhase3Time = tt.AP3Time tx, err := freshTH.txBuilder.NewAddDelegatorTx( @@ -358,7 +358,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, apricotPhase5) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -785,7 +785,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { func TestBanffStandardTxExecutorAddValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, banffFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -1068,7 +1068,7 @@ func TestDurangoDisabledTransactions(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, true /*=postCortina*/, true /*=postDurango*/) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -1592,7 +1592,7 @@ func TestDurangoMemoField(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, true /*=postCortina*/, true /*=postDurango*/) + env := newEnvironment(t, durangoFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 94e158582cce..ea0e213d6ef3 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -80,6 +80,7 @@ const ( banffFork cortinaFork durangoFork + eUpgradeFork latestFork activeFork = durangoFork @@ -210,12 +211,16 @@ func defaultVM(t *testing.T, fork activeFork) (*VM, database.Database, *mutableS banffTime = mockable.MaxTime cortinaTime = mockable.MaxTime durangoTime = mockable.MaxTime + eUpgradeTime = mockable.MaxTime ) // always reset latestForkTime (a package level variable) // to ensure test independence latestForkTime = defaultGenesisTime.Add(time.Second) switch fork { + case eUpgradeFork: + eUpgradeTime = latestForkTime + fallthrough case durangoFork: durangoTime = latestForkTime fallthrough @@ -254,7 +259,7 @@ func defaultVM(t *testing.T, fork activeFork) (*VM, database.Database, *mutableS BanffTime: banffTime, CortinaTime: cortinaTime, DurangoTime: durangoTime, - EUpgradeTime: mockable.MaxTime, + EUpgradeTime: eUpgradeTime, }} db := memdb.New() From a4b81e65e4757932d7add5bad19c5c275bff1fdf Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 20 Feb 2024 09:22:54 +0100 Subject: [PATCH 007/100] fork switch to the avm --- vms/avm/block/executor/block_test.go | 127 +++++------------- vms/avm/block/executor/manager_test.go | 27 +--- vms/avm/environment_test.go | 45 ++++++- vms/avm/index_test.go | 26 +--- vms/avm/service_test.go | 63 +++------ vms/avm/state_test.go | 3 + vms/avm/vm_benchmark_test.go | 3 +- vms/avm/vm_regression_test.go | 10 +- vms/avm/vm_test.go | 40 ++---- vms/avm/wallet_service_test.go | 1 + vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/txs/executor/helpers_test.go | 2 +- vms/platformvm/vm_test.go | 2 +- 14 files changed, 122 insertions(+), 231 deletions(-) diff --git a/vms/avm/block/executor/block_test.go b/vms/avm/block/executor/block_test.go index 59200e5d88c1..8b2e85a83789 100644 --- a/vms/avm/block/executor/block_test.go +++ b/vms/avm/block/executor/block_test.go @@ -30,6 +30,13 @@ import ( "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" ) +var noFeesTestConfig = &config.Config{ + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, + TxFee: 0, + CreateAssetTxFee: 0, +} + func TestBlockVerify(t *testing.T) { type test struct { name string @@ -47,10 +54,7 @@ func TestBlockVerify(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{}, }, @@ -72,10 +76,7 @@ func TestBlockVerify(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, }, } @@ -97,10 +98,7 @@ func TestBlockVerify(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, clk: clk, }, @@ -120,10 +118,7 @@ func TestBlockVerify(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{}, clk: &mockable.Clock{}, @@ -152,10 +147,7 @@ func TestBlockVerify(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), @@ -190,10 +182,7 @@ func TestBlockVerify(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, state: mockState, blkIDToState: map[ids.ID]*blockState{}, @@ -232,10 +221,7 @@ func TestBlockVerify(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, state: mockState, blkIDToState: map[ids.ID]*blockState{}, @@ -277,10 +263,7 @@ func TestBlockVerify(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{ parentID: { @@ -330,10 +313,7 @@ func TestBlockVerify(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), @@ -388,10 +368,7 @@ func TestBlockVerify(t *testing.T) { mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{ parentID: { @@ -471,10 +448,7 @@ func TestBlockVerify(t *testing.T) { mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{ parentID: { @@ -534,10 +508,7 @@ func TestBlockVerify(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{ parentID: { @@ -591,10 +562,7 @@ func TestBlockVerify(t *testing.T) { mempool: mockMempool, metrics: metrics.NewMockMetrics(ctrl), backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{ parentID: { @@ -673,10 +641,7 @@ func TestBlockAccept(t *testing.T) { Ctx: &snow.Context{ Log: logging.NoLog{}, }, - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{}, }, @@ -711,10 +676,7 @@ func TestBlockAccept(t *testing.T) { Ctx: &snow.Context{ Log: logging.NoLog{}, }, - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{ blockID: { @@ -759,10 +721,7 @@ func TestBlockAccept(t *testing.T) { SharedMemory: mockSharedMemory, Log: logging.NoLog{}, }, - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{ blockID: { @@ -811,10 +770,7 @@ func TestBlockAccept(t *testing.T) { SharedMemory: mockSharedMemory, Log: logging.NoLog{}, }, - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{ blockID: { @@ -866,10 +822,7 @@ func TestBlockAccept(t *testing.T) { SharedMemory: mockSharedMemory, Log: logging.NoLog{}, }, - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{ blockID: { @@ -967,10 +920,7 @@ func TestBlockReject(t *testing.T) { metrics: metrics.NewMockMetrics(ctrl), backend: &executor.Backend{ Bootstrapped: true, - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, Ctx: &snow.Context{ Log: logging.NoLog{}, }, @@ -1032,10 +982,7 @@ func TestBlockReject(t *testing.T) { Ctx: &snow.Context{ Log: logging.NoLog{}, }, - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, state: mockState, blkIDToState: map[ids.ID]*blockState{ @@ -1086,10 +1033,7 @@ func TestBlockStatus(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, lastAccepted: blockID, }, @@ -1107,10 +1051,7 @@ func TestBlockStatus(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{ blockID: {}, @@ -1134,10 +1075,7 @@ func TestBlockStatus(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{}, state: mockState, @@ -1160,10 +1098,7 @@ func TestBlockStatus(t *testing.T) { Block: mockBlock, manager: &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, blkIDToState: map[ids.ID]*blockState{}, state: mockState, diff --git a/vms/avm/block/executor/manager_test.go b/vms/avm/block/executor/manager_test.go index 517ced98eafd..adf1650cc780 100644 --- a/vms/avm/block/executor/manager_test.go +++ b/vms/avm/block/executor/manager_test.go @@ -13,9 +13,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/block" - "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/avm/txs/executor" @@ -126,10 +124,7 @@ func TestManagerVerifyTx(t *testing.T) { managerF: func(*gomock.Controller) *manager { return &manager{ backend: &executor.Backend{ - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, } }, @@ -148,10 +143,7 @@ func TestManagerVerifyTx(t *testing.T) { return &manager{ backend: &executor.Backend{ Bootstrapped: true, - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, } }, @@ -180,10 +172,7 @@ func TestManagerVerifyTx(t *testing.T) { return &manager{ backend: &executor.Backend{ Bootstrapped: true, - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, state: state, lastAccepted: lastAcceptedID, @@ -216,10 +205,7 @@ func TestManagerVerifyTx(t *testing.T) { return &manager{ backend: &executor.Backend{ Bootstrapped: true, - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, state: state, lastAccepted: lastAcceptedID, @@ -252,10 +238,7 @@ func TestManagerVerifyTx(t *testing.T) { return &manager{ backend: &executor.Backend{ Bootstrapped: true, - Config: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + Config: noFeesTestConfig, }, state: state, lastAccepted: lastAcceptedID, diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index b4f3e899a41d..a013ec4e0393 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -6,6 +6,7 @@ package avm import ( "context" "encoding/json" + "fmt" "math/rand" "testing" "time" @@ -40,7 +41,12 @@ import ( keystoreutils "github.com/ava-labs/avalanchego/vms/components/keystore" ) +type fork uint8 + const ( + durango fork = iota + eUpgrade + testTxFee uint64 = 1000 startBalance uint64 = 50000 @@ -70,6 +76,13 @@ var ( keys = secp256k1.TestKeys()[:3] // TODO: Remove [:3] addrs []ids.ShortID // addrs[i] corresponds to keys[i] + + noFeesTestConfig = &config.Config{ + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, + TxFee: 0, + CreateAssetTxFee: 0, + } ) func init() { @@ -86,6 +99,7 @@ type user struct { } type envConfig struct { + fork fork isCustomFeeAsset bool keystoreUsers []*user vmStaticConfig *config.Config @@ -146,12 +160,7 @@ func setup(tb testing.TB, c *envConfig) *environment { require.NoError(keystoreUser.Close()) } - vmStaticConfig := config.Config{ - TxFee: testTxFee, - CreateAssetTxFee: testTxFee, - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - } + vmStaticConfig := staticConfig(tb, c.fork) if c.vmStaticConfig != nil { vmStaticConfig = *c.vmStaticConfig } @@ -224,6 +233,30 @@ func setup(tb testing.TB, c *envConfig) *environment { return env } +func staticConfig(tb testing.TB, f fork) config.Config { + var ( + durangoTime = mockable.MaxTime + eUpgradeTime = mockable.MaxTime + ) + + switch f { + case eUpgrade: + eUpgradeTime = time.Time{} + fallthrough + case durango: + durangoTime = time.Time{} + default: + require.FailNow(tb, fmt.Sprintf("unhandled fork %d", f)) + } + + return config.Config{ + TxFee: testTxFee, + CreateAssetTxFee: testTxFee, + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } +} + // Returns: // // 1. tx in genesis that creates asset diff --git a/vms/avm/index_test.go b/vms/avm/index_test.go index 8ed1887b6935..ef8a357935a4 100644 --- a/vms/avm/index_test.go +++ b/vms/avm/index_test.go @@ -6,7 +6,6 @@ package avm import ( "context" "testing" - "time" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" @@ -20,8 +19,6 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/utils/timer/mockable" - "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/index" @@ -31,12 +28,7 @@ import ( func TestIndexTransaction_Ordered(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, - }) + env := setup(t, &envConfig{vmStaticConfig: noFeesTestConfig}) defer func() { require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() @@ -78,12 +70,7 @@ func TestIndexTransaction_Ordered(t *testing.T) { func TestIndexTransaction_MultipleTransactions(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, - }) + env := setup(t, &envConfig{vmStaticConfig: noFeesTestConfig}) defer func() { require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() @@ -129,12 +116,7 @@ func TestIndexTransaction_MultipleTransactions(t *testing.T) { func TestIndexTransaction_MultipleAddresses(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, - }) + env := setup(t, &envConfig{vmStaticConfig: noFeesTestConfig}) defer func() { require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() @@ -175,7 +157,7 @@ func TestIndexTransaction_MultipleAddresses(t *testing.T) { func TestIndexer_Read(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{vmStaticConfig: noFeesTestConfig}) defer func() { require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index 00ec1c93e0cd..c725658f839f 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -28,10 +28,8 @@ import ( "github.com/ava-labs/avalanchego/utils/formatting" "github.com/ava-labs/avalanchego/utils/formatting/address" "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/block" "github.com/ava-labs/avalanchego/vms/avm/block/executor" - "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -47,7 +45,7 @@ import ( func TestServiceIssueTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) env.vm.ctx.Lock.Unlock() defer func() { @@ -73,7 +71,7 @@ func TestServiceIssueTx(t *testing.T) { func TestServiceGetTxStatus(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) env.vm.ctx.Lock.Unlock() defer func() { @@ -108,7 +106,7 @@ func TestServiceGetTxStatus(t *testing.T) { func TestServiceGetBalanceStrict(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) @@ -264,7 +262,7 @@ func TestServiceGetBalanceStrict(t *testing.T) { func TestServiceGetTxs(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) var err error env.vm.addressTxsIndexer, err = index.NewIndexer(env.vm.db, env.vm.ctx.Log, "", prometheus.NewRegistry(), false) require.NoError(err) @@ -306,7 +304,7 @@ func TestServiceGetTxs(t *testing.T) { func TestServiceGetAllBalances(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) @@ -504,7 +502,7 @@ func TestServiceGetAllBalances(t *testing.T) { func TestServiceGetTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) env.vm.ctx.Lock.Unlock() defer func() { @@ -532,7 +530,7 @@ func TestServiceGetTx(t *testing.T) { func TestServiceGetTxJSON_BaseTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() @@ -615,7 +613,7 @@ func TestServiceGetTxJSON_BaseTx(t *testing.T) { func TestServiceGetTxJSON_ExportTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() @@ -700,10 +698,7 @@ func TestServiceGetTxJSON_CreateAssetTx(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + vmStaticConfig: noFeesTestConfig, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -819,10 +814,7 @@ func TestServiceGetTxJSON_OperationTxWithNftxMintOp(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + vmStaticConfig: noFeesTestConfig, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -921,10 +913,7 @@ func TestServiceGetTxJSON_OperationTxWithMultipleNftxMintOp(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + vmStaticConfig: noFeesTestConfig, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -1062,10 +1051,7 @@ func TestServiceGetTxJSON_OperationTxWithSecpMintOp(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + vmStaticConfig: noFeesTestConfig, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -1168,10 +1154,7 @@ func TestServiceGetTxJSON_OperationTxWithMultipleSecpMintOp(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + vmStaticConfig: noFeesTestConfig, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -1317,10 +1300,7 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOp(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + vmStaticConfig: noFeesTestConfig, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -1420,10 +1400,7 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + vmStaticConfig: noFeesTestConfig, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -1802,7 +1779,7 @@ func buildOperationTxWithOp(chainID ids.ID, op ...*txs.Operation) *txs.Tx { func TestServiceGetNilTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) env.vm.ctx.Lock.Unlock() defer func() { @@ -1819,7 +1796,7 @@ func TestServiceGetNilTx(t *testing.T) { func TestServiceGetUnknownTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) env.vm.ctx.Lock.Unlock() defer func() { @@ -1834,7 +1811,7 @@ func TestServiceGetUnknownTx(t *testing.T) { } func TestServiceGetUTXOs(t *testing.T) { - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) defer func() { env.vm.ctx.Lock.Lock() require.NoError(t, env.vm.Shutdown(context.Background())) @@ -2089,7 +2066,7 @@ func TestServiceGetUTXOs(t *testing.T) { func TestGetAssetDescription(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) env.vm.ctx.Lock.Unlock() defer func() { @@ -2112,7 +2089,7 @@ func TestGetAssetDescription(t *testing.T) { func TestGetBalance(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) env.vm.ctx.Lock.Unlock() defer func() { diff --git a/vms/avm/state_test.go b/vms/avm/state_test.go index b17604b2ba62..4496ed54d80a 100644 --- a/vms/avm/state_test.go +++ b/vms/avm/state_test.go @@ -24,6 +24,7 @@ func TestSetsAndGets(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ + fork: durango, additionalFxs: []*common.Fx{{ ID: ids.GenerateTestID(), Fx: &FxTest{ @@ -86,6 +87,7 @@ func TestSetsAndGets(t *testing.T) { func TestFundingNoAddresses(t *testing.T) { env := setup(t, &envConfig{ + fork: durango, additionalFxs: []*common.Fx{{ ID: ids.GenerateTestID(), Fx: &FxTest{ @@ -118,6 +120,7 @@ func TestFundingAddresses(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ + fork: durango, additionalFxs: []*common.Fx{{ ID: ids.GenerateTestID(), Fx: &FxTest{ diff --git a/vms/avm/vm_benchmark_test.go b/vms/avm/vm_benchmark_test.go index 713f809f7f5c..4ac65c86d7d6 100644 --- a/vms/avm/vm_benchmark_test.go +++ b/vms/avm/vm_benchmark_test.go @@ -23,6 +23,7 @@ func BenchmarkLoadUser(b *testing.B) { require := require.New(b) env := setup(b, &envConfig{ + fork: durango, keystoreUsers: []*user{{ username: username, password: password, @@ -67,7 +68,7 @@ func BenchmarkLoadUser(b *testing.B) { func GetAllUTXOsBenchmark(b *testing.B, utxoCount int) { require := require.New(b) - env := setup(b, &envConfig{}) + env := setup(b, &envConfig{fork: durango}) defer func() { require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() diff --git a/vms/avm/vm_regression_test.go b/vms/avm/vm_regression_test.go index 2412c4e9a70c..34d99dcc351e 100644 --- a/vms/avm/vm_regression_test.go +++ b/vms/avm/vm_regression_test.go @@ -6,15 +6,12 @@ package avm import ( "context" "testing" - "time" "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/timer/mockable" - "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/verify" @@ -25,12 +22,7 @@ import ( func TestVerifyFxUsage(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, - }) + env := setup(t, &envConfig{vmStaticConfig: noFeesTestConfig}) env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() diff --git a/vms/avm/vm_test.go b/vms/avm/vm_test.go index a01aefd349d0..527c2e98efe4 100644 --- a/vms/avm/vm_test.go +++ b/vms/avm/vm_test.go @@ -7,7 +7,6 @@ import ( "context" "math" "testing" - "time" "github.com/stretchr/testify/require" @@ -20,8 +19,6 @@ import ( "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/timer/mockable" - "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/fxs" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -117,7 +114,7 @@ func TestFxInitializationFailure(t *testing.T) { func TestIssueTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() @@ -133,12 +130,7 @@ func TestIssueTx(t *testing.T) { func TestIssueNFT(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, - }) + env := setup(t, &envConfig{vmStaticConfig: noFeesTestConfig}) env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() @@ -238,10 +230,7 @@ func TestIssueProperty(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, + vmStaticConfig: noFeesTestConfig, additionalFxs: []*common.Fx{{ ID: propertyfx.ID, Fx: &propertyfx.Fx{}, @@ -334,6 +323,7 @@ func TestIssueTxWithFeeAsset(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ + fork: durango, isCustomFeeAsset: true, }) env.vm.ctx.Lock.Unlock() @@ -352,6 +342,7 @@ func TestIssueTxWithAnotherAsset(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ + fork: durango, isCustomFeeAsset: true, }) env.vm.ctx.Lock.Unlock() @@ -411,7 +402,7 @@ func TestIssueTxWithAnotherAsset(t *testing.T) { } func TestVMFormat(t *testing.T) { - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) defer func() { require.NoError(t, env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() @@ -440,6 +431,7 @@ func TestTxAcceptAfterParseTx(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ + fork: durango, notLinearized: true, }) defer func() { @@ -527,12 +519,7 @@ func TestTxAcceptAfterParseTx(t *testing.T) { func TestIssueImportTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, - }) + env := setup(t, &envConfig{vmStaticConfig: noFeesTestConfig}) defer func() { require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() @@ -631,11 +618,8 @@ func TestForceAcceptImportTx(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - vmStaticConfig: &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - }, - notLinearized: true, + vmStaticConfig: noFeesTestConfig, + notLinearized: true, }) defer func() { require.NoError(env.vm.Shutdown(context.Background())) @@ -711,7 +695,7 @@ func TestImportTxNotState(t *testing.T) { func TestIssueExportTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) defer func() { require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() @@ -786,7 +770,7 @@ func TestIssueExportTx(t *testing.T) { func TestClearForceAcceptedExportTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{}) + env := setup(t, &envConfig{fork: durango}) defer func() { require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() diff --git a/vms/avm/wallet_service_test.go b/vms/avm/wallet_service_test.go index 7ffdccdaaa20..a71403fa385d 100644 --- a/vms/avm/wallet_service_test.go +++ b/vms/avm/wallet_service_test.go @@ -18,6 +18,7 @@ func TestWalletService_SendMultiple(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { env := setup(t, &envConfig{ + fork: durango, isCustomFeeAsset: !tc.avaxAsset, keystoreUsers: []*user{{ username: username, diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index d75b5780e530..d07ab6140c05 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -334,7 +334,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { case apricotPhase3: apricotPhase3Time = defaultValidateEndTime default: - require.NoError(t, fmt.Errorf("unhandled fork %d", f)) + require.FailNow(t, fmt.Sprintf("unhandled fork %d", f)) } return &config.Config{ diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index a2cacb0f2771..26cd8bd566a0 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -358,7 +358,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { case apricotPhase3: apricotPhase3Time = defaultValidateEndTime default: - require.NoError(t, fmt.Errorf("unhandled fork %d", f)) + require.FailNow(t, fmt.Sprintf("unhandled fork %d", f)) } return &config.Config{ diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index ad8acaa859e3..907829f901c5 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -309,7 +309,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { case apricotPhase3: apricotPhase3Time = defaultValidateEndTime default: - require.NoError(t, fmt.Errorf("unhandled fork %d", f)) + require.FailNow(t, fmt.Sprintf("unhandled fork %d", f)) } return &config.Config{ diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 7f0974365765..b1d6a73b6454 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -235,7 +235,7 @@ func defaultVM(t *testing.T, f fork) (*VM, database.Database, *mutableSharedMemo case apricotPhase3: apricotPhase3Time = latestForkTime default: - require.NoError(fmt.Errorf("unhandled fork %d", f)) + require.FailNow(fmt.Sprintf("unhandled fork %d", f)) } vm := &VM{Config: config.Config{ From 507636e6f192e1d9d9aa9aa0ae2e4b4d5ffcc8c6 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 29 Feb 2024 11:25:35 +0100 Subject: [PATCH 008/100] latestFork in avm --- vms/avm/environment_test.go | 2 ++ vms/avm/service_test.go | 26 +++++++++++++------------- vms/avm/state_test.go | 6 +++--- vms/avm/vm_benchmark_test.go | 4 ++-- vms/avm/vm_test.go | 14 +++++++------- vms/avm/wallet_service_test.go | 2 +- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index a6c8c3aed766..3500a9bc43f3 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -47,6 +47,8 @@ const ( durango fork = iota eUpgrade + latest = durango + testTxFee uint64 = 1000 startBalance uint64 = 50000 diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index c725658f839f..7fe845b21cbc 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -45,7 +45,7 @@ import ( func TestServiceIssueTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) env.vm.ctx.Lock.Unlock() defer func() { @@ -71,7 +71,7 @@ func TestServiceIssueTx(t *testing.T) { func TestServiceGetTxStatus(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) env.vm.ctx.Lock.Unlock() defer func() { @@ -106,7 +106,7 @@ func TestServiceGetTxStatus(t *testing.T) { func TestServiceGetBalanceStrict(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) @@ -262,7 +262,7 @@ func TestServiceGetBalanceStrict(t *testing.T) { func TestServiceGetTxs(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) var err error env.vm.addressTxsIndexer, err = index.NewIndexer(env.vm.db, env.vm.ctx.Log, "", prometheus.NewRegistry(), false) require.NoError(err) @@ -304,7 +304,7 @@ func TestServiceGetTxs(t *testing.T) { func TestServiceGetAllBalances(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) @@ -502,7 +502,7 @@ func TestServiceGetAllBalances(t *testing.T) { func TestServiceGetTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) env.vm.ctx.Lock.Unlock() defer func() { @@ -530,7 +530,7 @@ func TestServiceGetTx(t *testing.T) { func TestServiceGetTxJSON_BaseTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() @@ -613,7 +613,7 @@ func TestServiceGetTxJSON_BaseTx(t *testing.T) { func TestServiceGetTxJSON_ExportTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() @@ -1779,7 +1779,7 @@ func buildOperationTxWithOp(chainID ids.ID, op ...*txs.Operation) *txs.Tx { func TestServiceGetNilTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) env.vm.ctx.Lock.Unlock() defer func() { @@ -1796,7 +1796,7 @@ func TestServiceGetNilTx(t *testing.T) { func TestServiceGetUnknownTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) env.vm.ctx.Lock.Unlock() defer func() { @@ -1811,7 +1811,7 @@ func TestServiceGetUnknownTx(t *testing.T) { } func TestServiceGetUTXOs(t *testing.T) { - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) defer func() { env.vm.ctx.Lock.Lock() require.NoError(t, env.vm.Shutdown(context.Background())) @@ -2066,7 +2066,7 @@ func TestServiceGetUTXOs(t *testing.T) { func TestGetAssetDescription(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) env.vm.ctx.Lock.Unlock() defer func() { @@ -2089,7 +2089,7 @@ func TestGetAssetDescription(t *testing.T) { func TestGetBalance(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) env.vm.ctx.Lock.Unlock() defer func() { diff --git a/vms/avm/state_test.go b/vms/avm/state_test.go index 4496ed54d80a..e71acf1251cb 100644 --- a/vms/avm/state_test.go +++ b/vms/avm/state_test.go @@ -24,7 +24,7 @@ func TestSetsAndGets(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - fork: durango, + fork: latest, additionalFxs: []*common.Fx{{ ID: ids.GenerateTestID(), Fx: &FxTest{ @@ -87,7 +87,7 @@ func TestSetsAndGets(t *testing.T) { func TestFundingNoAddresses(t *testing.T) { env := setup(t, &envConfig{ - fork: durango, + fork: latest, additionalFxs: []*common.Fx{{ ID: ids.GenerateTestID(), Fx: &FxTest{ @@ -120,7 +120,7 @@ func TestFundingAddresses(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - fork: durango, + fork: latest, additionalFxs: []*common.Fx{{ ID: ids.GenerateTestID(), Fx: &FxTest{ diff --git a/vms/avm/vm_benchmark_test.go b/vms/avm/vm_benchmark_test.go index 4ac65c86d7d6..5befa7062dda 100644 --- a/vms/avm/vm_benchmark_test.go +++ b/vms/avm/vm_benchmark_test.go @@ -23,7 +23,7 @@ func BenchmarkLoadUser(b *testing.B) { require := require.New(b) env := setup(b, &envConfig{ - fork: durango, + fork: latest, keystoreUsers: []*user{{ username: username, password: password, @@ -68,7 +68,7 @@ func BenchmarkLoadUser(b *testing.B) { func GetAllUTXOsBenchmark(b *testing.B, utxoCount int) { require := require.New(b) - env := setup(b, &envConfig{fork: durango}) + env := setup(b, &envConfig{fork: latest}) defer func() { require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() diff --git a/vms/avm/vm_test.go b/vms/avm/vm_test.go index 527c2e98efe4..270ab6b36ed2 100644 --- a/vms/avm/vm_test.go +++ b/vms/avm/vm_test.go @@ -114,7 +114,7 @@ func TestFxInitializationFailure(t *testing.T) { func TestIssueTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() @@ -323,7 +323,7 @@ func TestIssueTxWithFeeAsset(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - fork: durango, + fork: latest, isCustomFeeAsset: true, }) env.vm.ctx.Lock.Unlock() @@ -342,7 +342,7 @@ func TestIssueTxWithAnotherAsset(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - fork: durango, + fork: latest, isCustomFeeAsset: true, }) env.vm.ctx.Lock.Unlock() @@ -402,7 +402,7 @@ func TestIssueTxWithAnotherAsset(t *testing.T) { } func TestVMFormat(t *testing.T) { - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) defer func() { require.NoError(t, env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() @@ -431,7 +431,7 @@ func TestTxAcceptAfterParseTx(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{ - fork: durango, + fork: latest, notLinearized: true, }) defer func() { @@ -695,7 +695,7 @@ func TestImportTxNotState(t *testing.T) { func TestIssueExportTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) defer func() { require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() @@ -770,7 +770,7 @@ func TestIssueExportTx(t *testing.T) { func TestClearForceAcceptedExportTx(t *testing.T) { require := require.New(t) - env := setup(t, &envConfig{fork: durango}) + env := setup(t, &envConfig{fork: latest}) defer func() { require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() diff --git a/vms/avm/wallet_service_test.go b/vms/avm/wallet_service_test.go index a71403fa385d..eeb214fba9bd 100644 --- a/vms/avm/wallet_service_test.go +++ b/vms/avm/wallet_service_test.go @@ -18,7 +18,7 @@ func TestWalletService_SendMultiple(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { env := setup(t, &envConfig{ - fork: durango, + fork: latest, isCustomFeeAsset: !tc.avaxAsset, keystoreUsers: []*user{{ username: username, From 399dfc8afc16ad65c2719b6b47f031a00bae73be Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 29 Feb 2024 11:46:24 +0100 Subject: [PATCH 009/100] default test config for a few unit tests --- .../executor/staker_tx_verification_test.go | 92 +++++--------- .../txs/executor/standard_tx_executor_test.go | 115 ++++++------------ 2 files changed, 64 insertions(+), 143 deletions(-) diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index a5f426a665ab..343b89327855 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -109,11 +109,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { name: "fail syntactic verification", backendF: func(*gomock.Controller) *Backend { return &Backend{ - Ctx: ctx, - Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EUpgradeTime: mockable.MaxTime, - }, + Ctx: ctx, + Config: defaultTestConfig(activeForkTime), } }, stateF: func(*gomock.Controller) state.Chain { @@ -131,11 +128,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { name: "not bootstrapped", backendF: func(*gomock.Controller) *Backend { return &Backend{ - Ctx: ctx, - Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EUpgradeTime: mockable.MaxTime, - }, + Ctx: ctx, + Config: defaultTestConfig(activeForkTime), Bootstrapped: &utils.Atomic[bool]{}, } }, @@ -186,11 +180,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: ctx, - Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EUpgradeTime: mockable.MaxTime, - }, + Ctx: ctx, + Config: defaultTestConfig(activeForkTime), Bootstrapped: bootstrapped, } }, @@ -216,11 +207,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: ctx, - Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EUpgradeTime: mockable.MaxTime, - }, + Ctx: ctx, + Config: defaultTestConfig(activeForkTime), Bootstrapped: bootstrapped, } }, @@ -246,11 +234,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: ctx, - Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EUpgradeTime: mockable.MaxTime, - }, + Ctx: ctx, + Config: defaultTestConfig(activeForkTime), Bootstrapped: bootstrapped, } }, @@ -277,11 +262,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: ctx, - Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EUpgradeTime: mockable.MaxTime, - }, + Ctx: ctx, + Config: defaultTestConfig(activeForkTime), Bootstrapped: bootstrapped, } }, @@ -311,11 +293,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: ctx, - Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EUpgradeTime: mockable.MaxTime, - }, + Ctx: ctx, + Config: defaultTestConfig(activeForkTime), Bootstrapped: bootstrapped, } }, @@ -345,11 +324,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: ctx, - Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EUpgradeTime: mockable.MaxTime, - }, + Ctx: ctx, + Config: defaultTestConfig(activeForkTime), Bootstrapped: bootstrapped, } }, @@ -381,11 +357,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: ctx, - Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EUpgradeTime: mockable.MaxTime, - }, + Ctx: ctx, + Config: defaultTestConfig(activeForkTime), Bootstrapped: bootstrapped, } }, @@ -411,11 +384,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: ctx, - Config: &config.Config{ - DurangoTime: activeForkTime, // activate latest fork - EUpgradeTime: mockable.MaxTime, - }, + Ctx: ctx, + Config: defaultTestConfig(activeForkTime), Bootstrapped: bootstrapped, } }, @@ -456,13 +426,12 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { gomock.Any(), ).Return(ErrFlowCheckFailed) + cfg := defaultTestConfig(activeForkTime) + cfg.AddSubnetValidatorFee = 1 + return &Backend{ - FlowChecker: flowChecker, - Config: &config.Config{ - AddSubnetValidatorFee: 1, - DurangoTime: activeForkTime, // activate latest fork, - EUpgradeTime: mockable.MaxTime, - }, + FlowChecker: flowChecker, + Config: cfg, Ctx: ctx, Bootstrapped: bootstrapped, } @@ -556,13 +525,12 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { gomock.Any(), ).Return(nil) + cfg := defaultTestConfig(activeForkTime) + cfg.AddSubnetValidatorFee = 1 + return &Backend{ - FlowChecker: flowChecker, - Config: &config.Config{ - AddSubnetValidatorFee: 1, - DurangoTime: activeForkTime, // activate latest fork, - EUpgradeTime: mockable.MaxTime, - }, + FlowChecker: flowChecker, + Config: cfg, Ctx: ctx, Bootstrapped: bootstrapped, } diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 55e6289f070f..17553e2f8018 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -1543,12 +1543,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: defaultTestConfig(env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1571,12 +1566,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: defaultTestConfig(env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1600,12 +1590,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetPendingValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: defaultTestConfig(env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1632,12 +1617,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(&staker, nil).Times(1) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: defaultTestConfig(env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1662,12 +1642,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: defaultTestConfig(env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1691,12 +1666,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: defaultTestConfig(env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1722,12 +1692,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.fx.EXPECT().VerifyPermission(gomock.Any(), env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(errTest) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: defaultTestConfig(env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1756,12 +1721,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { ).Return(errTest) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: defaultTestConfig(env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1914,12 +1874,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: defaultTestConfig(env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1942,12 +1897,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - }, + Config: defaultTestConfig(env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1969,15 +1919,13 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.tx.Creds = nil env.state = state.NewMockDiff(ctrl) env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + + cfg := defaultTestConfig(env.latestForkTime) + cfg.MaxStakeDuration = math.MaxInt64 + e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - MaxStakeDuration: math.MaxInt64, - EUpgradeTime: mockable.MaxTime, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -2004,15 +1952,13 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.flowChecker.EXPECT().VerifySpend( gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), ).Return(ErrFlowCheckFailed) + + cfg := defaultTestConfig(env.latestForkTime) + cfg.MaxStakeDuration = math.MaxInt64 + e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - MaxStakeDuration: math.MaxInt64, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -2044,15 +1990,13 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state.EXPECT().SetCurrentSupply(env.unsignedTx.Subnet, env.unsignedTx.InitialSupply) env.state.EXPECT().DeleteUTXO(gomock.Any()).Times(len(env.unsignedTx.Ins)) env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) + + cfg := defaultTestConfig(env.latestForkTime) + cfg.MaxStakeDuration = math.MaxInt64 + e := &StandardTxExecutor{ Backend: &Backend{ - Config: &config.Config{ - BanffTime: env.latestForkTime, - CortinaTime: env.latestForkTime, - DurangoTime: env.latestForkTime, - EUpgradeTime: mockable.MaxTime, - MaxStakeDuration: math.MaxInt64, - }, + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -2078,3 +2022,12 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { }) } } + +func defaultTestConfig(latestForkTime time.Time) *config.Config { + return &config.Config{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + } +} From 089af5e04c3c5379e74ee6121c84d586b6bef7e1 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 29 Feb 2024 12:55:15 +0100 Subject: [PATCH 010/100] come more unit tests helpers --- vms/avm/block/executor/block_test.go | 155 +++++++------------------ vms/avm/block/executor/manager_test.go | 25 +--- 2 files changed, 50 insertions(+), 130 deletions(-) diff --git a/vms/avm/block/executor/block_test.go b/vms/avm/block/executor/block_test.go index 8b2e85a83789..e8b08ab0346a 100644 --- a/vms/avm/block/executor/block_test.go +++ b/vms/avm/block/executor/block_test.go @@ -30,13 +30,6 @@ import ( "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" ) -var noFeesTestConfig = &config.Config{ - DurangoTime: time.Time{}, - EUpgradeTime: mockable.MaxTime, - TxFee: 0, - CreateAssetTxFee: 0, -} - func TestBlockVerify(t *testing.T) { type test struct { name string @@ -53,9 +46,7 @@ func TestBlockVerify(t *testing.T) { b := &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{}, }, } @@ -75,9 +66,7 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), }, } }, @@ -97,10 +86,8 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, - clk: clk, + backend: defaultTestBackend(false, nil), + clk: clk, }, } }, @@ -117,9 +104,7 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{}, clk: &mockable.Clock{}, }, @@ -146,9 +131,7 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), blkIDToState: map[ids.ID]*blockState{}, @@ -181,9 +164,7 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), state: mockState, blkIDToState: map[ids.ID]*blockState{}, clk: &mockable.Clock{}, @@ -220,9 +201,7 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), state: mockState, blkIDToState: map[ids.ID]*blockState{}, clk: &mockable.Clock{}, @@ -262,9 +241,7 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{ parentID: { onAcceptState: mockParentState, @@ -312,9 +289,7 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), blkIDToState: map[ids.ID]*blockState{ @@ -367,9 +342,7 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{ parentID: { onAcceptState: mockParentState, @@ -447,9 +420,7 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{ parentID: { onAcceptState: mockParentState, @@ -507,9 +478,7 @@ func TestBlockVerify(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{ parentID: { onAcceptState: mockParentState, @@ -561,9 +530,7 @@ func TestBlockVerify(t *testing.T) { manager: &manager{ mempool: mockMempool, metrics: metrics.NewMockMetrics(ctrl), - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{ parentID: { onAcceptState: mockParentState, @@ -635,14 +602,9 @@ func TestBlockAccept(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - mempool: mempool, - metrics: metrics.NewMockMetrics(ctrl), - backend: &executor.Backend{ - Ctx: &snow.Context{ - Log: logging.NoLog{}, - }, - Config: noFeesTestConfig, - }, + mempool: mempool, + metrics: metrics.NewMockMetrics(ctrl), + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{}, }, } @@ -672,12 +634,7 @@ func TestBlockAccept(t *testing.T) { manager: &manager{ state: mockManagerState, mempool: mempool, - backend: &executor.Backend{ - Ctx: &snow.Context{ - Log: logging.NoLog{}, - }, - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{ blockID: { onAcceptState: mockOnAcceptState, @@ -716,13 +673,7 @@ func TestBlockAccept(t *testing.T) { manager: &manager{ state: mockManagerState, mempool: mempool, - backend: &executor.Backend{ - Ctx: &snow.Context{ - SharedMemory: mockSharedMemory, - Log: logging.NoLog{}, - }, - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, mockSharedMemory), blkIDToState: map[ids.ID]*blockState{ blockID: { onAcceptState: mockOnAcceptState, @@ -765,13 +716,7 @@ func TestBlockAccept(t *testing.T) { state: mockManagerState, mempool: mempool, metrics: metrics, - backend: &executor.Backend{ - Ctx: &snow.Context{ - SharedMemory: mockSharedMemory, - Log: logging.NoLog{}, - }, - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, mockSharedMemory), blkIDToState: map[ids.ID]*blockState{ blockID: { onAcceptState: mockOnAcceptState, @@ -817,13 +762,7 @@ func TestBlockAccept(t *testing.T) { state: mockManagerState, mempool: mempool, metrics: metrics, - backend: &executor.Backend{ - Ctx: &snow.Context{ - SharedMemory: mockSharedMemory, - Log: logging.NoLog{}, - }, - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, mockSharedMemory), blkIDToState: map[ids.ID]*blockState{ blockID: { onAcceptState: mockOnAcceptState, @@ -918,14 +857,8 @@ func TestBlockReject(t *testing.T) { lastAccepted: lastAcceptedID, mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), - backend: &executor.Backend{ - Bootstrapped: true, - Config: noFeesTestConfig, - Ctx: &snow.Context{ - Log: logging.NoLog{}, - }, - }, - state: mockState, + backend: defaultTestBackend(true, nil), + state: mockState, blkIDToState: map[ids.ID]*blockState{ blockID: {}, }, @@ -977,14 +910,8 @@ func TestBlockReject(t *testing.T) { lastAccepted: lastAcceptedID, mempool: mempool, metrics: metrics.NewMockMetrics(ctrl), - backend: &executor.Backend{ - Bootstrapped: true, - Ctx: &snow.Context{ - Log: logging.NoLog{}, - }, - Config: noFeesTestConfig, - }, - state: mockState, + backend: defaultTestBackend(true, nil), + state: mockState, blkIDToState: map[ids.ID]*blockState{ blockID: {}, }, @@ -1032,9 +959,7 @@ func TestBlockStatus(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), lastAccepted: blockID, }, } @@ -1050,9 +975,7 @@ func TestBlockStatus(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{ blockID: {}, }, @@ -1074,9 +997,7 @@ func TestBlockStatus(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{}, state: mockState, }, @@ -1097,9 +1018,7 @@ func TestBlockStatus(t *testing.T) { return &Block{ Block: mockBlock, manager: &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), blkIDToState: map[ids.ID]*blockState{}, state: mockState, }, @@ -1118,3 +1037,19 @@ func TestBlockStatus(t *testing.T) { }) } } + +func defaultTestBackend(bootstrapped bool, sharedMemory atomic.SharedMemory) *executor.Backend { + return &executor.Backend{ + Bootstrapped: bootstrapped, + Ctx: &snow.Context{ + SharedMemory: sharedMemory, + Log: logging.NoLog{}, + }, + Config: &config.Config{ + DurangoTime: time.Time{}, + EUpgradeTime: mockable.MaxTime, + TxFee: 0, + CreateAssetTxFee: 0, + }, + } +} diff --git a/vms/avm/block/executor/manager_test.go b/vms/avm/block/executor/manager_test.go index adf1650cc780..14484fcbb559 100644 --- a/vms/avm/block/executor/manager_test.go +++ b/vms/avm/block/executor/manager_test.go @@ -16,7 +16,6 @@ import ( "github.com/ava-labs/avalanchego/vms/avm/block" "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" - "github.com/ava-labs/avalanchego/vms/avm/txs/executor" ) var ( @@ -123,9 +122,7 @@ func TestManagerVerifyTx(t *testing.T) { }, managerF: func(*gomock.Controller) *manager { return &manager{ - backend: &executor.Backend{ - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(false, nil), } }, expectedErr: ErrChainNotSynced, @@ -141,10 +138,7 @@ func TestManagerVerifyTx(t *testing.T) { }, managerF: func(*gomock.Controller) *manager { return &manager{ - backend: &executor.Backend{ - Bootstrapped: true, - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(true, nil), } }, expectedErr: errTestSyntacticVerifyFail, @@ -170,10 +164,7 @@ func TestManagerVerifyTx(t *testing.T) { state.EXPECT().GetTimestamp().Return(time.Time{}) return &manager{ - backend: &executor.Backend{ - Bootstrapped: true, - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(true, nil), state: state, lastAccepted: lastAcceptedID, } @@ -203,10 +194,7 @@ func TestManagerVerifyTx(t *testing.T) { state.EXPECT().GetTimestamp().Return(time.Time{}) return &manager{ - backend: &executor.Backend{ - Bootstrapped: true, - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(true, nil), state: state, lastAccepted: lastAcceptedID, } @@ -236,10 +224,7 @@ func TestManagerVerifyTx(t *testing.T) { state.EXPECT().GetTimestamp().Return(time.Time{}) return &manager{ - backend: &executor.Backend{ - Bootstrapped: true, - Config: noFeesTestConfig, - }, + backend: defaultTestBackend(true, nil), state: state, lastAccepted: lastAcceptedID, } From dca34a5297c904c4859ed563c5863b1496676bc1 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 11 Mar 2024 10:56:25 +0100 Subject: [PATCH 011/100] fixed merge --- codec/reflectcodec/type_codec.go | 4 ---- codec/test_codec.go | 3 ++- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/codec/reflectcodec/type_codec.go b/codec/reflectcodec/type_codec.go index c3da55c22a87..486ab006f3f2 100644 --- a/codec/reflectcodec/type_codec.go +++ b/codec/reflectcodec/type_codec.go @@ -157,10 +157,6 @@ func (c *genericCodec) size( return 0, false, err } - if size == 0 { - return 0, false, fmt.Errorf("can't marshal slice of zero length values: %w", codec.ErrMarshalZeroLength) - } - // For fixed-size types we manually calculate lengths rather than // processing each element separately to improve performance. if constSize { diff --git a/codec/test_codec.go b/codec/test_codec.go index 809cd84f21c7..37127f0de9bc 100644 --- a/codec/test_codec.go +++ b/codec/test_codec.go @@ -864,8 +864,9 @@ func TestSliceWithEmptySerializationError(codec GeneralCodec, t testing.TB) { _, err := manager.Marshal(0, val) require.ErrorIs(err, ErrMarshalZeroLength) + // we cannot marshal/unmarshal an empty slice, but we can ask its size _, err = manager.Size(0, val) - require.ErrorIs(err, ErrMarshalZeroLength) + require.NoError(err) b := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x01} // codec version (0x00, 0x00) then (0x00, 0x00, 0x00, 0x01) for numElts From cd989f37d630472cb2b5fd98b8c1125c35598685 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 11 Mar 2024 15:18:37 +0100 Subject: [PATCH 012/100] nits from code reviews --- vms/avm/config/config.go | 2 +- vms/platformvm/config/config.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vms/avm/config/config.go b/vms/avm/config/config.go index 42e37b678a01..fb376fb77a30 100644 --- a/vms/avm/config/config.go +++ b/vms/avm/config/config.go @@ -20,6 +20,6 @@ type Config struct { EUpgradeTime time.Time } -func (c *Config) IsEUpgradeActivated(timestamp time.Time) bool { +func (c *Config) IsEUActivated(timestamp time.Time) bool { return !timestamp.Before(c.EUpgradeTime) } diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 0ac37f81f08e..0c5fcf15a475 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -140,7 +140,7 @@ func (c *Config) IsDurangoActivated(timestamp time.Time) bool { return !timestamp.Before(c.DurangoTime) } -func (c *Config) IsEForkActivated(timestamp time.Time) bool { +func (c *Config) IsEActivated(timestamp time.Time) bool { return !timestamp.Before(c.EUpgradeTime) } From 32da156991d9c6fd5320cb697a2fa81b1b25c7ec Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 11 Mar 2024 15:34:13 +0100 Subject: [PATCH 013/100] some more nits from code reviews --- .../executor/staker_tx_verification_test.go | 24 +++---- .../txs/executor/standard_tx_executor_test.go | 70 ++++++++++++++----- 2 files changed, 64 insertions(+), 30 deletions(-) diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index a4c65395ba07..f9081fdf5ded 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -110,7 +110,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { backendF: func(*gomock.Controller) *Backend { return &Backend{ Ctx: ctx, - Config: defaultTestConfig(activeForkTime), + Config: defaultTestConfig(t, durango, activeForkTime), } }, stateF: func(*gomock.Controller) state.Chain { @@ -129,7 +129,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { backendF: func(*gomock.Controller) *Backend { return &Backend{ Ctx: ctx, - Config: defaultTestConfig(activeForkTime), + Config: defaultTestConfig(t, durango, activeForkTime), Bootstrapped: &utils.Atomic[bool]{}, } }, @@ -181,7 +181,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped.Set(true) return &Backend{ Ctx: ctx, - Config: defaultTestConfig(activeForkTime), + Config: defaultTestConfig(t, durango, activeForkTime), Bootstrapped: bootstrapped, } }, @@ -208,7 +208,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped.Set(true) return &Backend{ Ctx: ctx, - Config: defaultTestConfig(activeForkTime), + Config: defaultTestConfig(t, durango, activeForkTime), Bootstrapped: bootstrapped, } }, @@ -235,7 +235,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped.Set(true) return &Backend{ Ctx: ctx, - Config: defaultTestConfig(activeForkTime), + Config: defaultTestConfig(t, durango, activeForkTime), Bootstrapped: bootstrapped, } }, @@ -263,7 +263,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped.Set(true) return &Backend{ Ctx: ctx, - Config: defaultTestConfig(activeForkTime), + Config: defaultTestConfig(t, durango, activeForkTime), Bootstrapped: bootstrapped, } }, @@ -294,7 +294,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped.Set(true) return &Backend{ Ctx: ctx, - Config: defaultTestConfig(activeForkTime), + Config: defaultTestConfig(t, durango, activeForkTime), Bootstrapped: bootstrapped, } }, @@ -325,7 +325,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped.Set(true) return &Backend{ Ctx: ctx, - Config: defaultTestConfig(activeForkTime), + Config: defaultTestConfig(t, durango, activeForkTime), Bootstrapped: bootstrapped, } }, @@ -358,7 +358,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped.Set(true) return &Backend{ Ctx: ctx, - Config: defaultTestConfig(activeForkTime), + Config: defaultTestConfig(t, durango, activeForkTime), Bootstrapped: bootstrapped, } }, @@ -385,7 +385,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped.Set(true) return &Backend{ Ctx: ctx, - Config: defaultTestConfig(activeForkTime), + Config: defaultTestConfig(t, durango, activeForkTime), Bootstrapped: bootstrapped, } }, @@ -426,7 +426,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { gomock.Any(), ).Return(ErrFlowCheckFailed) - cfg := defaultTestConfig(activeForkTime) + cfg := defaultTestConfig(t, durango, activeForkTime) cfg.AddSubnetValidatorFee = 1 return &Backend{ @@ -472,7 +472,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { gomock.Any(), ).Return(nil) - cfg := defaultTestConfig(activeForkTime) + cfg := defaultTestConfig(t, durango, activeForkTime) cfg.AddSubnetValidatorFee = 1 return &Backend{ diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 9fca25a9a289..6e58a4bcfda8 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -5,6 +5,7 @@ package executor import ( "errors" + "fmt" "math" "testing" "time" @@ -1503,7 +1504,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(env.latestForkTime), + Config: defaultTestConfig(t, durango, env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1526,7 +1527,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(env.latestForkTime), + Config: defaultTestConfig(t, durango, env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1550,7 +1551,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetPendingValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(env.latestForkTime), + Config: defaultTestConfig(t, durango, env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1577,7 +1578,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(&staker, nil).Times(1) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(env.latestForkTime), + Config: defaultTestConfig(t, durango, env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1602,7 +1603,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(env.latestForkTime), + Config: defaultTestConfig(t, durango, env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1626,7 +1627,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(env.latestForkTime), + Config: defaultTestConfig(t, durango, env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1652,7 +1653,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.fx.EXPECT().VerifyPermission(gomock.Any(), env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(errTest) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(env.latestForkTime), + Config: defaultTestConfig(t, durango, env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1681,7 +1682,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { ).Return(errTest) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(env.latestForkTime), + Config: defaultTestConfig(t, durango, env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1834,7 +1835,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(env.latestForkTime), + Config: defaultTestConfig(t, durango, env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1857,7 +1858,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(env.latestForkTime), + Config: defaultTestConfig(t, durango, env.latestForkTime), Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, @@ -1880,7 +1881,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) - cfg := defaultTestConfig(env.latestForkTime) + cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 e := &StandardTxExecutor{ @@ -1913,7 +1914,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), ).Return(ErrFlowCheckFailed) - cfg := defaultTestConfig(env.latestForkTime) + cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 e := &StandardTxExecutor{ @@ -1951,7 +1952,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state.EXPECT().DeleteUTXO(gomock.Any()).Times(len(env.unsignedTx.Ins)) env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) - cfg := defaultTestConfig(env.latestForkTime) + cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 e := &StandardTxExecutor{ @@ -1983,11 +1984,44 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { } } -func defaultTestConfig(latestForkTime time.Time) *config.Config { +func defaultTestConfig(t *testing.T, f fork, tm time.Time) *config.Config { //nolint: unparam + var ( + apricotPhase3Time = mockable.MaxTime + apricotPhase5Time = mockable.MaxTime + banffTime = mockable.MaxTime + cortinaTime = mockable.MaxTime + durangoTime = mockable.MaxTime + eUpgradeTime = mockable.MaxTime + ) + + switch f { + case eUpgrade: + eUpgradeTime = tm + fallthrough + case durango: + durangoTime = tm + fallthrough + case cortina: + cortinaTime = tm + fallthrough + case banff: + banffTime = tm + fallthrough + case apricotPhase5: + apricotPhase5Time = tm + fallthrough + case apricotPhase3: + apricotPhase3Time = tm + default: + require.FailNow(t, fmt.Sprintf("unhandled fork %d", f)) + } + return &config.Config{ - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + EUpgradeTime: eUpgradeTime, + DurangoTime: durangoTime, + CortinaTime: cortinaTime, + BanffTime: banffTime, + ApricotPhase5Time: apricotPhase5Time, + ApricotPhase3Time: apricotPhase3Time, } } From d2525d5d2160a11984cb60e86cfe67afd1ba0f4c Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 11 Mar 2024 16:06:17 +0100 Subject: [PATCH 014/100] fixed merge --- codec/test_codec.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/codec/test_codec.go b/codec/test_codec.go index 910e72da917f..2712d2ada9f4 100644 --- a/codec/test_codec.go +++ b/codec/test_codec.go @@ -8,6 +8,8 @@ import ( "testing" "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/utils/wrappers" ) var ( From 7a17a9bfe5fffbacc023ae91e978c6682364bf7f Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 13 Mar 2024 17:43:54 +0100 Subject: [PATCH 015/100] drop DurangoTime from avm config --- vms/avm/block/executor/block_test.go | 1 - vms/avm/config/config.go | 5 +---- vms/avm/environment_test.go | 10 ++-------- vms/avm/txs/executor/syntactic_verifier_test.go | 2 -- 4 files changed, 3 insertions(+), 15 deletions(-) diff --git a/vms/avm/block/executor/block_test.go b/vms/avm/block/executor/block_test.go index e8b08ab0346a..8e72f4c21ebe 100644 --- a/vms/avm/block/executor/block_test.go +++ b/vms/avm/block/executor/block_test.go @@ -1046,7 +1046,6 @@ func defaultTestBackend(bootstrapped bool, sharedMemory atomic.SharedMemory) *ex Log: logging.NoLog{}, }, Config: &config.Config{ - DurangoTime: time.Time{}, EUpgradeTime: mockable.MaxTime, TxFee: 0, CreateAssetTxFee: 0, diff --git a/vms/avm/config/config.go b/vms/avm/config/config.go index fb376fb77a30..0d026eb05dbb 100644 --- a/vms/avm/config/config.go +++ b/vms/avm/config/config.go @@ -13,13 +13,10 @@ type Config struct { // Fee that must be burned by every asset creating transaction CreateAssetTxFee uint64 - // Time of the Durango network upgrade - DurangoTime time.Time - // Time of the E network upgrade EUpgradeTime time.Time } -func (c *Config) IsEUActivated(timestamp time.Time) bool { +func (c *Config) IsEActivated(timestamp time.Time) bool { return !timestamp.Before(c.EUpgradeTime) } diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index 35db1462b94a..1ab7cf068d7f 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -80,7 +80,6 @@ var ( addrs []ids.ShortID // addrs[i] corresponds to keys[i] noFeesTestConfig = &config.Config{ - DurangoTime: time.Time{}, EUpgradeTime: mockable.MaxTime, TxFee: 0, CreateAssetTxFee: 0, @@ -236,17 +235,13 @@ func setup(tb testing.TB, c *envConfig) *environment { } func staticConfig(tb testing.TB, f fork) config.Config { - var ( - durangoTime = mockable.MaxTime - eUpgradeTime = mockable.MaxTime - ) + var eUpgradeTime time.Time switch f { case eUpgrade: eUpgradeTime = time.Time{} - fallthrough case durango: - durangoTime = time.Time{} + eUpgradeTime = mockable.MaxTime default: require.FailNow(tb, fmt.Sprintf("unhandled fork %d", f)) } @@ -254,7 +249,6 @@ func staticConfig(tb testing.TB, f fork) config.Config { return config.Config{ TxFee: testTxFee, CreateAssetTxFee: testTxFee, - DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } } diff --git a/vms/avm/txs/executor/syntactic_verifier_test.go b/vms/avm/txs/executor/syntactic_verifier_test.go index a95df8354c0b..c5762a81c74b 100644 --- a/vms/avm/txs/executor/syntactic_verifier_test.go +++ b/vms/avm/txs/executor/syntactic_verifier_test.go @@ -7,7 +7,6 @@ import ( "math" "strings" "testing" - "time" "github.com/stretchr/testify/require" @@ -31,7 +30,6 @@ var ( feeConfig = config.Config{ TxFee: 2, CreateAssetTxFee: 3, - DurangoTime: time.Time{}, EUpgradeTime: mockable.MaxTime, } ) From 29067561e1dbb7d9965b652c96644c19153af21e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 13 Mar 2024 17:48:53 +0100 Subject: [PATCH 016/100] nit --- .../txs/executor/standard_tx_executor_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 6e58a4bcfda8..eef52f4b46d8 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -2017,11 +2017,11 @@ func defaultTestConfig(t *testing.T, f fork, tm time.Time) *config.Config { //no } return &config.Config{ - EUpgradeTime: eUpgradeTime, - DurangoTime: durangoTime, - CortinaTime: cortinaTime, - BanffTime: banffTime, - ApricotPhase5Time: apricotPhase5Time, ApricotPhase3Time: apricotPhase3Time, + ApricotPhase5Time: apricotPhase5Time, + BanffTime: banffTime, + CortinaTime: cortinaTime, + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, } } From d3edbaae5618518da96d55b712f9bb46dd06140a Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 13 Mar 2024 17:52:11 +0100 Subject: [PATCH 017/100] nit --- .../txs/executor/staker_tx_verification_test.go | 8 ++------ vms/platformvm/txs/executor/standard_tx_executor_test.go | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index f9081fdf5ded..24e1df2a0db6 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -152,12 +152,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: ctx, - Config: &config.Config{ - CortinaTime: activeForkTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, - }, + Ctx: ctx, + Config: defaultTestConfig(t, cortina, activeForkTime), Bootstrapped: bootstrapped, } }, diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index eef52f4b46d8..f8d5a76811ca 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -1984,7 +1984,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { } } -func defaultTestConfig(t *testing.T, f fork, tm time.Time) *config.Config { //nolint: unparam +func defaultTestConfig(t *testing.T, f fork, tm time.Time) *config.Config { var ( apricotPhase3Time = mockable.MaxTime apricotPhase5Time = mockable.MaxTime From bd2311e437425e7f5279410e2fc5bb3629c51349 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 27 Mar 2024 09:41:34 +0100 Subject: [PATCH 018/100] reverted unnecessary changes --- codec/manager.go | 4 +- codec/reflectcodec/type_codec.go | 10 ++- codec/test_codec.go | 86 +--------------------- vms/platformvm/state/metadata_validator.go | 2 +- 4 files changed, 11 insertions(+), 91 deletions(-) diff --git a/codec/manager.go b/codec/manager.go index bf1ad3af72bc..27e5e392260c 100644 --- a/codec/manager.go +++ b/codec/manager.go @@ -13,7 +13,7 @@ import ( ) const ( - CodecVersionSize = wrappers.ShortLen + VersionSize = wrappers.ShortLen // default max size, in bytes, of something being marshalled by Marshal() defaultMaxSize = 256 * units.KiB @@ -105,7 +105,7 @@ func (m *manager) Size(version uint16, value interface{}) (int, error) { res, err := c.Size(value) // Add [CodecVersionSize] for the codec version - return CodecVersionSize + res, err + return VersionSize + res, err } // To marshal an interface, [value] must be a pointer to the interface. diff --git a/codec/reflectcodec/type_codec.go b/codec/reflectcodec/type_codec.go index bfec299a3e51..45818a741814 100644 --- a/codec/reflectcodec/type_codec.go +++ b/codec/reflectcodec/type_codec.go @@ -82,7 +82,7 @@ func New(typer TypeCodec, tagNames []string) codec.Codec { func (c *genericCodec) Size(value interface{}) (int, error) { if value == nil { - return 0, nil // can't marshal nil, we return zero size + return 0, codec.ErrMarshalNil // can't marshal nil, we return zero size } size, _, err := c.size(reflect.ValueOf(value), nil /*=typeStack*/) @@ -118,14 +118,14 @@ func (c *genericCodec) size( return wrappers.StringLen(value.String()), false, nil case reflect.Ptr: if value.IsNil() { - return 0, false, nil // can't marshal nil, we return zero size + return 0, false, codec.ErrMarshalNil // can't marshal nil, we return zero size } return c.size(value.Elem(), typeStack) case reflect.Interface: if value.IsNil() { - return 0, false, nil // can't marshal nil, we return zero size + return 0, false, codec.ErrMarshalNil // can't marshal nil, we return zero size } underlyingValue := value.Interface() @@ -152,6 +152,10 @@ func (c *genericCodec) size( return 0, false, err } + if size == 0 { + return 0, false, fmt.Errorf("can't marshal slice of zero length values: %w", codec.ErrMarshalZeroLength) + } + // For fixed-size types we manually calculate lengths rather than // processing each element separately to improve performance. if constSize { diff --git a/codec/test_codec.go b/codec/test_codec.go index 2712d2ada9f4..2dc8b3e2add9 100644 --- a/codec/test_codec.go +++ b/codec/test_codec.go @@ -8,15 +8,11 @@ import ( "testing" "github.com/stretchr/testify/require" - - "github.com/ava-labs/avalanchego/utils/wrappers" ) var ( Tests = []func(c GeneralCodec, t testing.TB){ TestStruct, - TestPartiallyFilledStruct, - TestSliceWithEmptyElements, TestRegisterStructTwice, TestUInt32, TestUIntPtr, @@ -245,85 +241,6 @@ func TestStruct(codec GeneralCodec, t testing.TB) { require.Equal(myStructInstance, *myStructUnmarshaled) } -func TestPartiallyFilledStruct(codec GeneralCodec, t testing.TB) { - require := require.New(t) - - manager := NewDefaultManager() - require.NoError(manager.RegisterCodec(0, codec)) - - // a nil pointer cannot be marshalled but we can get its size - var nilStruct *myStruct - _, err := manager.Marshal(0, nilStruct) - require.ErrorIs(err, ErrMarshalNil) - - bytesLen, err := manager.Size(0, nilStruct) - require.NoError(err) - require.Equal(CodecVersionSize, bytesLen) - - // an empty struct cannot be marshalled but we can get its size - emptyStruct := &myStruct{} - _, err = manager.Marshal(0, nilStruct) - require.ErrorIs(err, ErrMarshalNil) - - emptyStructLen := CodecVersionSize + 117 - bytesLen, err = manager.Size(0, emptyStruct) - require.NoError(err) - require.Equal(emptyStructLen, bytesLen) - - // an partially filled struct cannot be marshalled but we can get its size - elem := &MyInnerStruct{ - Str: "a", - } - elemLen := CodecVersionSize + wrappers.StringLen(elem.Str) - - partialStruct := &myStruct{ - InnerStruct2: elem, - } - partialStructLen := emptyStructLen + elemLen - CodecVersionSize - bytesLen, err = manager.Size(0, partialStruct) - require.NoError(err) - require.Equal(partialStructLen, bytesLen) -} - -func TestSliceWithEmptyElements(codec GeneralCodec, t testing.TB) { - require := require.New(t) - - manager := NewDefaultManager() - require.NoError(manager.RegisterCodec(0, codec)) - - // a non-empty slice with nil pointers cannot be marshalled but we can get its size - slice := make([]*MyInnerStruct, 10) - - _, err := manager.Marshal(0, slice) - require.ErrorIs(err, ErrMarshalNil) - - emptySliceLen := CodecVersionSize + wrappers.IntLen // Codec version + slice size. Slice elements have zero size - bytesLen, err := manager.Size(0, slice) - require.NoError(err) - require.Equal(emptySliceLen, bytesLen) - - elem := &MyInnerStruct{ - Str: "aaa", - } - elemLen := CodecVersionSize + wrappers.StringLen(elem.Str) - bytesLen, err = manager.Size(0, elem) - require.NoError(err) - require.Equal(elemLen, bytesLen) - - // we can fill some elements and leave other empty. Size will be sub-additive - slice[1] = elem - sliceLen := emptySliceLen + elemLen - CodecVersionSize // codec version is marshelled only once - bytesLen, err = manager.Size(0, slice) - require.NoError(err) - require.Equal(sliceLen, bytesLen) - - slice[5] = elem - sliceLen += elemLen - CodecVersionSize // codec version is marshelled only once - bytesLen, err = manager.Size(0, slice) - require.NoError(err) - require.Equal(sliceLen, bytesLen) -} - func TestRegisterStructTwice(codec GeneralCodec, t testing.TB) { require := require.New(t) @@ -856,9 +773,8 @@ func TestSliceWithEmptySerializationError(codec GeneralCodec, t testing.TB) { _, err := manager.Marshal(0, val) require.ErrorIs(err, ErrMarshalZeroLength) - // we cannot marshal/unmarshal an empty slice, but we can ask its size _, err = manager.Size(0, val) - require.NoError(err) + require.ErrorIs(err, ErrMarshalZeroLength) b := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x01} // codec version (0x00, 0x00) then (0x00, 0x00, 0x00, 0x01) for numElts diff --git a/vms/platformvm/state/metadata_validator.go b/vms/platformvm/state/metadata_validator.go index 74242150d37f..340c7205350a 100644 --- a/vms/platformvm/state/metadata_validator.go +++ b/vms/platformvm/state/metadata_validator.go @@ -18,7 +18,7 @@ import ( // [preDelegateeRewardMetadata]. // // CodecVersionLen + UpDurationLen + LastUpdatedLen + PotentialRewardLen -const preDelegateeRewardSize = codec.CodecVersionSize + 3*wrappers.LongLen +const preDelegateeRewardSize = codec.VersionSize + 3*wrappers.LongLen var _ validatorState = (*metadata)(nil) From b979b51faa478022d61178a7d6ba4ecce0e447e0 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 27 Mar 2024 17:49:50 +0100 Subject: [PATCH 019/100] reduced diff --- .../txs/executor/standard_tx_executor_test.go | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index d7f5865e41ef..d495785c8663 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -1501,7 +1501,6 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().DeleteCurrentValidator(env.staker) env.state.EXPECT().DeleteUTXO(gomock.Any()).Times(len(env.unsignedTx.Ins)) env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) - e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1525,7 +1524,6 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { // Setting the subnet ID to the Primary Network ID makes the tx fail syntactic verification env.tx.Unsigned.(*txs.RemoveSubnetValidatorTx).Subnet = constants.PrimaryNetworkID env.state = state.NewMockDiff(ctrl) - e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1550,7 +1548,6 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) env.state.EXPECT().GetPendingValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) - e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1578,7 +1575,6 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { // Set dependency expectations. env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(&staker, nil).Times(1) - e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1604,7 +1600,6 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) - e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1629,7 +1624,6 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound) - e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1656,7 +1650,6 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil) env.fx.EXPECT().VerifyPermission(gomock.Any(), env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(errTest) - e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1686,7 +1679,6 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.flowChecker.EXPECT().VerifySpend( gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), ).Return(errTest) - e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1840,7 +1832,6 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { // Setting the tx to nil makes the tx fail syntactic verification env.tx.Unsigned = (*txs.TransformSubnetTx)(nil) env.state = state.NewMockDiff(ctrl) - e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1863,7 +1854,6 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env := newValidTransformSubnetTxVerifyEnv(t, ctrl) env.unsignedTx.MaxStakeDuration = math.MaxUint32 env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ @@ -1888,10 +1878,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { // Remove credentials env.tx.Creds = nil env.state = state.NewMockDiff(ctrl) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ From 5c22480ba70c83ce9f2ef1a508f0e2d023b8d9ce Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 2 Apr 2024 13:28:27 +0200 Subject: [PATCH 020/100] introduced fee StaticCalculator constructor --- .../txs/executor/staker_tx_verification.go | 49 ++++++------------- .../txs/executor/standard_tx_executor.go | 42 +++++----------- vms/platformvm/txs/fees/calculator.go | 41 +++++++++------- 3 files changed, 50 insertions(+), 82 deletions(-) diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index b441fcc7d973..c74ae5a4d5d0 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -164,11 +164,8 @@ func verifyAddValidatorTx( } // Verify the flowcheck - feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: currentTimestamp, - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(backend.Config, currentTimestamp) + if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -260,11 +257,8 @@ func verifyAddSubnetValidatorTx( } // Verify the flowcheck - feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: currentTimestamp, - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(backend.Config, currentTimestamp) + if err := tx.Visit(feeCalculator); err != nil { return err } @@ -343,11 +337,8 @@ func verifyRemoveSubnetValidatorTx( } // Verify the flowcheck - feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: chainState.GetTimestamp(), - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + if err := tx.Visit(feeCalculator); err != nil { return nil, false, err } @@ -466,11 +457,8 @@ func verifyAddDelegatorTx( } // Verify the flowcheck - feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: chainState.GetTimestamp(), - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -591,11 +579,8 @@ func verifyAddPermissionlessValidatorTx( copy(outs[len(tx.Outs):], tx.StakeOuts) // Verify the flowcheck - feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: currentTimestamp, - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(backend.Config, currentTimestamp) + if err := tx.Visit(feeCalculator); err != nil { return err } @@ -741,11 +726,8 @@ func verifyAddPermissionlessDelegatorTx( } // Verify the flowcheck - feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: currentTimestamp, - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(backend.Config, currentTimestamp) + if err := tx.Visit(feeCalculator); err != nil { return err } @@ -801,11 +783,8 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck - feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: chainState.GetTimestamp(), - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + if err := tx.Visit(feeCalculator); err != nil { return err } diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 29220ffee0b4..74ebef4aa7f7 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -69,11 +69,8 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - feeCalculator := fees.Calculator{ - Config: e.Backend.Config, - ChainTime: e.State.GetTimestamp(), - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + if err := tx.Visit(feeCalculator); err != nil { return err } @@ -122,11 +119,8 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } // Verify the flowcheck - feeCalculator := fees.Calculator{ - Config: e.Backend.Config, - ChainTime: e.State.GetTimestamp(), - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + if err := tx.Visit(feeCalculator); err != nil { return err } @@ -210,11 +204,8 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - feeCalculator := fees.Calculator{ - Config: e.Backend.Config, - ChainTime: e.State.GetTimestamp(), - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + if err := tx.Visit(feeCalculator); err != nil { return err } @@ -274,11 +265,8 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - feeCalculator := fees.Calculator{ - Config: e.Backend.Config, - ChainTime: e.State.GetTimestamp(), - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + if err := tx.Visit(feeCalculator); err != nil { return err } @@ -468,11 +456,8 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error } totalRewardAmount := tx.MaximumSupply - tx.InitialSupply - feeCalculator := fees.Calculator{ - Config: e.Backend.Config, - ChainTime: currentTimestamp, - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(e.Backend.Config, currentTimestamp) + if err := tx.Visit(feeCalculator); err != nil { return err } if err := e.Backend.FlowChecker.VerifySpend( @@ -598,11 +583,8 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { cfg = e.Backend.Config currentTimestamp = e.State.GetTimestamp() ) - feeCalculator := fees.Calculator{ - Config: cfg, - ChainTime: currentTimestamp, - } - if err := tx.Visit(&feeCalculator); err != nil { + feeCalculator := fees.NewStaticCalculator(cfg, currentTimestamp) + if err := tx.Visit(feeCalculator); err != nil { return err } diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index 123052577e54..a20d7c5bd176 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -15,35 +15,42 @@ var _ txs.Visitor = (*Calculator)(nil) type Calculator struct { // Pre E-fork inputs - Config *config.Config - ChainTime time.Time + config *config.Config + chainTime time.Time // outputs of visitor execution Fee uint64 } +func NewStaticCalculator(cfg *config.Config, chainTime time.Time) *Calculator { + return &Calculator{ + config: cfg, + chainTime: chainTime, + } +} + func (fc *Calculator) AddValidatorTx(*txs.AddValidatorTx) error { - fc.Fee = fc.Config.AddPrimaryNetworkValidatorFee + fc.Fee = fc.config.AddPrimaryNetworkValidatorFee return nil } func (fc *Calculator) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { - fc.Fee = fc.Config.AddSubnetValidatorFee + fc.Fee = fc.config.AddSubnetValidatorFee return nil } func (fc *Calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { - fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee + fc.Fee = fc.config.AddPrimaryNetworkDelegatorFee return nil } func (fc *Calculator) CreateChainTx(*txs.CreateChainTx) error { - fc.Fee = fc.Config.GetCreateBlockchainTxFee(fc.ChainTime) + fc.Fee = fc.config.GetCreateBlockchainTxFee(fc.chainTime) return nil } func (fc *Calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { - fc.Fee = fc.Config.GetCreateSubnetTxFee(fc.ChainTime) + fc.Fee = fc.config.GetCreateSubnetTxFee(fc.chainTime) return nil } @@ -56,49 +63,49 @@ func (*Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { } func (fc *Calculator) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { - fc.Fee = fc.Config.TxFee + fc.Fee = fc.config.TxFee return nil } func (fc *Calculator) TransformSubnetTx(*txs.TransformSubnetTx) error { - fc.Fee = fc.Config.TransformSubnetTxFee + fc.Fee = fc.config.TransformSubnetTxFee return nil } func (fc *Calculator) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { - fc.Fee = fc.Config.TxFee + fc.Fee = fc.config.TxFee return nil } func (fc *Calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { if tx.Subnet != constants.PrimaryNetworkID { - fc.Fee = fc.Config.AddSubnetValidatorFee + fc.Fee = fc.config.AddSubnetValidatorFee } else { - fc.Fee = fc.Config.AddPrimaryNetworkValidatorFee + fc.Fee = fc.config.AddPrimaryNetworkValidatorFee } return nil } func (fc *Calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { if tx.Subnet != constants.PrimaryNetworkID { - fc.Fee = fc.Config.AddSubnetDelegatorFee + fc.Fee = fc.config.AddSubnetDelegatorFee } else { - fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee + fc.Fee = fc.config.AddPrimaryNetworkDelegatorFee } return nil } func (fc *Calculator) BaseTx(*txs.BaseTx) error { - fc.Fee = fc.Config.TxFee + fc.Fee = fc.config.TxFee return nil } func (fc *Calculator) ImportTx(*txs.ImportTx) error { - fc.Fee = fc.Config.TxFee + fc.Fee = fc.config.TxFee return nil } func (fc *Calculator) ExportTx(*txs.ExportTx) error { - fc.Fee = fc.Config.TxFee + fc.Fee = fc.config.TxFee return nil } From 4a1f2fee298cd96ca3c479c5f0bce0862a77cd68 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 15 Apr 2024 10:23:28 +0200 Subject: [PATCH 021/100] nit --- .../txs/executor/staker_tx_verification.go | 16 ++++++++-------- .../txs/executor/standard_tx_executor.go | 14 +++++++------- vms/platformvm/txs/{fees => fee}/calculator.go | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) rename vms/platformvm/txs/{fees => fee}/calculator.go (99%) diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index c74ae5a4d5d0..86cf4b179985 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -15,7 +15,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" safemath "github.com/ava-labs/avalanchego/utils/math" ) @@ -164,7 +164,7 @@ func verifyAddValidatorTx( } // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(backend.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -257,7 +257,7 @@ func verifyAddSubnetValidatorTx( } // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(backend.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -337,7 +337,7 @@ func verifyRemoveSubnetValidatorTx( } // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + feeCalculator := fee.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) if err := tx.Visit(feeCalculator); err != nil { return nil, false, err } @@ -457,7 +457,7 @@ func verifyAddDelegatorTx( } // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + feeCalculator := fee.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -579,7 +579,7 @@ func verifyAddPermissionlessValidatorTx( copy(outs[len(tx.Outs):], tx.StakeOuts) // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(backend.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -726,7 +726,7 @@ func verifyAddPermissionlessDelegatorTx( } // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(backend.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -783,7 +783,7 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + feeCalculator := fee.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) if err := tx.Visit(feeCalculator); err != nil { return err } diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 74ebef4aa7f7..8cbc0a58cd5a 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -19,7 +19,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) var ( @@ -69,7 +69,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -119,7 +119,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -204,7 +204,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -265,7 +265,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -456,7 +456,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error } totalRewardAmount := tx.MaximumSupply - tx.InitialSupply - feeCalculator := fees.NewStaticCalculator(e.Backend.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -583,7 +583,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { cfg = e.Backend.Config currentTimestamp = e.State.GetTimestamp() ) - feeCalculator := fees.NewStaticCalculator(cfg, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(cfg, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fee/calculator.go similarity index 99% rename from vms/platformvm/txs/fees/calculator.go rename to vms/platformvm/txs/fee/calculator.go index a20d7c5bd176..d0823cd523a8 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package fees +package fee import ( "time" From c078f1d1b2c1234a3e5bc19f2712b8ef632a4531 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 15 Apr 2024 10:47:03 +0200 Subject: [PATCH 022/100] simplified p-chain config --- vms/platformvm/config/config.go | 14 ----- vms/platformvm/service_test.go | 8 ++- vms/platformvm/txs/fee/calculator.go | 12 +++- vms/platformvm/txs/txstest/builder.go | 79 +++++++++++++++++++++------ vms/platformvm/txs/txstest/context.go | 25 +++++++-- 5 files changed, 99 insertions(+), 39 deletions(-) diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 0c5fcf15a475..07cb74a8fd18 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -144,20 +144,6 @@ func (c *Config) IsEActivated(timestamp time.Time) bool { return !timestamp.Before(c.EUpgradeTime) } -func (c *Config) GetCreateBlockchainTxFee(timestamp time.Time) uint64 { - if c.IsApricotPhase3Activated(timestamp) { - return c.CreateBlockchainTxFee - } - return c.CreateAssetTxFee -} - -func (c *Config) GetCreateSubnetTxFee(timestamp time.Time) uint64 { - if c.IsApricotPhase3Activated(timestamp) { - return c.CreateSubnetTxFee - } - return c.CreateAssetTxFee -} - // Create the blockchain described in [tx], but only if this node is a member of // the subnet that validates the chain func (c *Config) CreateChain(chainID ids.ID, tx *txs.CreateChainTx) { diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 8f39770548b8..3224edb2d73d 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -39,6 +39,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -365,6 +366,11 @@ func TestGetBalance(t *testing.T) { require := require.New(t) service, _, _ := defaultService(t) + staticFeeCalc := fee.NewStaticCalculator(&service.vm.Config, service.vm.clock.Time()) + dummyCreateSubnetTx := &txs.CreateSubnetTx{} + require.NoError(dummyCreateSubnetTx.Visit(staticFeeCalc)) + createSubnetFee := staticFeeCalc.Fee + // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) for idx, utxo := range genesis.UTXOs { @@ -380,7 +386,7 @@ func TestGetBalance(t *testing.T) { if idx == 0 { // we use the first key to fund a subnet creation in [defaultGenesis]. // As such we need to account for the subnet creation fee - balance = defaultBalance - service.vm.Config.GetCreateSubnetTxFee(service.vm.clock.Time()) + balance = defaultBalance - createSubnetFee } require.Equal(avajson.Uint64(balance), reply.Balance) require.Equal(avajson.Uint64(balance), reply.Unlocked) diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index d0823cd523a8..038cbdc7ebf5 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -45,12 +45,20 @@ func (fc *Calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { } func (fc *Calculator) CreateChainTx(*txs.CreateChainTx) error { - fc.Fee = fc.config.GetCreateBlockchainTxFee(fc.chainTime) + if fc.config.IsApricotPhase3Activated(fc.chainTime) { + fc.Fee = fc.config.CreateBlockchainTxFee + } else { + fc.Fee = fc.config.CreateAssetTxFee + } return nil } func (fc *Calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { - fc.Fee = fc.config.GetCreateSubnetTxFee(fc.chainTime) + if fc.config.IsApricotPhase3Activated(fc.chainTime) { + fc.Fee = fc.config.CreateSubnetTxFee + } else { + fc.Fee = fc.config.CreateAssetTxFee + } return nil } diff --git a/vms/platformvm/txs/txstest/builder.go b/vms/platformvm/txs/txstest/builder.go index e9d9c8d40061..92f40f4b4176 100644 --- a/vms/platformvm/txs/txstest/builder.go +++ b/vms/platformvm/txs/txstest/builder.go @@ -47,7 +47,10 @@ func (b *Builder) NewImportTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewImportTx( chainID, @@ -67,7 +70,10 @@ func (b *Builder) NewExportTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewExportTx( chainID, @@ -90,7 +96,10 @@ func (b *Builder) NewCreateChainTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewCreateChainTx( subnetID, @@ -112,7 +121,10 @@ func (b *Builder) NewCreateSubnetTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewCreateSubnetTx( owner, @@ -143,7 +155,10 @@ func (b *Builder) NewTransformSubnetTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewTransformSubnetTx( subnetID, @@ -176,7 +191,10 @@ func (b *Builder) NewAddValidatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewAddValidatorTx( vdr, @@ -201,7 +219,10 @@ func (b *Builder) NewAddPermissionlessValidatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewAddPermissionlessValidatorTx( vdr, @@ -225,7 +246,10 @@ func (b *Builder) NewAddDelegatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewAddDelegatorTx( vdr, @@ -246,7 +270,10 @@ func (b *Builder) NewAddPermissionlessDelegatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewAddPermissionlessDelegatorTx( vdr, @@ -266,7 +293,10 @@ func (b *Builder) NewAddSubnetValidatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewAddSubnetValidatorTx( vdr, @@ -285,7 +315,10 @@ func (b *Builder) NewRemoveSubnetValidatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewRemoveSubnetValidatorTx( nodeID, @@ -305,7 +338,10 @@ func (b *Builder) NewTransferSubnetOwnershipTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewTransferSubnetOwnershipTx( subnetID, @@ -324,7 +360,10 @@ func (b *Builder) NewBaseTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner := b.builders(keys) + pBuilder, pSigner, err := b.builders(keys) + if err != nil { + return nil, err + } utx, err := pBuilder.NewBaseTx( outputs, @@ -337,15 +376,19 @@ func (b *Builder) NewBaseTx( return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *Builder) builders(keys []*secp256k1.PrivateKey) (builder.Builder, walletsigner.Signer) { +func (b *Builder) builders(keys []*secp256k1.PrivateKey) (builder.Builder, walletsigner.Signer, error) { var ( kc = secp256k1fx.NewKeychain(keys...) addrs = kc.Addresses() backend = newBackend(addrs, b.state, b.ctx.SharedMemory) - context = newContext(b.ctx, b.cfg, b.state.GetTimestamp()) - builder = builder.New(addrs, context, backend) - signer = walletsigner.New(kc, backend) ) - return builder, signer + context, err := newContext(b.ctx, b.cfg, b.state.GetTimestamp()) + if err != nil { + return nil, nil, err + } + + builder := builder.New(addrs, context, backend) + signer := walletsigner.New(kc, backend) + return builder, signer, nil } diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index 514a85e2bae7..e756d145e57b 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -8,6 +8,8 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/vms/platformvm/config" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) @@ -15,17 +17,32 @@ func newContext( ctx *snow.Context, cfg *config.Config, timestamp time.Time, -) *builder.Context { +) (*builder.Context, error) { + var ( + staticFeeCalc = fee.NewStaticCalculator(cfg, timestamp) + createSubnetTx = &txs.CreateSubnetTx{} + createChainTx = &txs.CreateChainTx{} + ) + if err := createSubnetTx.Visit(staticFeeCalc); err != nil { + return nil, err + } + createSubnetFee := staticFeeCalc.Fee + + if err := createChainTx.Visit(staticFeeCalc); err != nil { + return nil, err + } + createChainFee := staticFeeCalc.Fee + return &builder.Context{ NetworkID: ctx.NetworkID, AVAXAssetID: ctx.AVAXAssetID, BaseTxFee: cfg.TxFee, - CreateSubnetTxFee: cfg.GetCreateSubnetTxFee(timestamp), + CreateSubnetTxFee: createSubnetFee, TransformSubnetTxFee: cfg.TransformSubnetTxFee, - CreateBlockchainTxFee: cfg.GetCreateBlockchainTxFee(timestamp), + CreateBlockchainTxFee: createChainFee, AddPrimaryNetworkValidatorFee: cfg.AddPrimaryNetworkValidatorFee, AddPrimaryNetworkDelegatorFee: cfg.AddPrimaryNetworkDelegatorFee, AddSubnetValidatorFee: cfg.AddSubnetValidatorFee, AddSubnetDelegatorFee: cfg.AddSubnetDelegatorFee, - } + }, nil } From c81c85e7bf26fbc2a0c203be46b1ba492b55e57f Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 15 Apr 2024 11:18:41 +0200 Subject: [PATCH 023/100] added UTs --- vms/platformvm/txs/fee/calculator_test.go | 797 ++++++++++++++++++++++ 1 file changed, 797 insertions(+) create mode 100644 vms/platformvm/txs/fee/calculator_test.go diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go new file mode 100644 index 000000000000..fd2348dd6d0a --- /dev/null +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -0,0 +1,797 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/timer/mockable" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/config" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +var ( + feeTestsDefaultCfg = config.Config{ + TxFee: 1 * units.Avax, + CreateAssetTxFee: 2 * units.Avax, + CreateSubnetTxFee: 3 * units.Avax, + TransformSubnetTxFee: 4 * units.Avax, + CreateBlockchainTxFee: 5 * units.Avax, + AddPrimaryNetworkValidatorFee: 6 * units.Avax, + AddPrimaryNetworkDelegatorFee: 7 * units.Avax, + AddSubnetValidatorFee: 8 * units.Avax, + AddSubnetDelegatorFee: 9 * units.Avax, + } + + preFundedKeys = secp256k1.TestKeys() + feeTestSigners = [][]*secp256k1.PrivateKey{preFundedKeys} + feeTestDefaultStakeWeight = uint64(2024) + durangoTime = time.Time{} // assume durango is active in these tests +) + +type feeTests struct { + description string + cfgAndChainTimeF func() (*config.Config, time.Time) + unsignedAndSignedTx func(t *testing.T) (txs.UnsignedTx, *txs.Tx) + expectedError error + checksF func(*testing.T, *Calculator) +} + +func TestTxFees(t *testing.T) { + r := require.New(t) + + tests := []feeTests{ + { + description: "AddValidatorTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: addValidatorTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.AddPrimaryNetworkValidatorFee, fc.Fee) + }, + }, + { + description: "AddSubnetValidatorTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: addSubnetValidatorTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.AddSubnetValidatorFee, fc.Fee) + }, + }, + { + description: "AddDelegatorTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: addDelegatorTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.AddPrimaryNetworkDelegatorFee, fc.Fee) + }, + }, + { + description: "CreateChainTx pre ApricotPhase3", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + apricotPhase3Time := time.Now().Truncate(time.Second) + chainTime := apricotPhase3Time.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.ApricotPhase3Time = apricotPhase3Time + cfg.DurangoTime = mockable.MaxTime + cfg.EUpgradeTime = mockable.MaxTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: createChainTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.CreateAssetTxFee, fc.Fee) + }, + }, + { + description: "CreateChainTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: createChainTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.CreateBlockchainTxFee, fc.Fee) + }, + }, + { + description: "CreateSubnetTx pre ApricotPhase3", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + apricotPhase3Time := time.Now().Truncate(time.Second) + chainTime := apricotPhase3Time.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.ApricotPhase3Time = apricotPhase3Time + cfg.DurangoTime = mockable.MaxTime + cfg.EUpgradeTime = mockable.MaxTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: createSubnetTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.CreateAssetTxFee, fc.Fee) + }, + }, + { + description: "CreateSubnetTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: createSubnetTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.CreateSubnetTxFee, fc.Fee) + }, + }, + { + description: "RemoveSubnetValidatorTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: removeSubnetValidatorTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.TxFee, fc.Fee) + }, + }, + { + description: "TransformSubnetTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: transformSubnetTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.TransformSubnetTxFee, fc.Fee) + }, + }, + { + description: "TransferSubnetOwnershipTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: transferSubnetOwnershipTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.TxFee, fc.Fee) + }, + }, + { + description: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + return addPermissionlessValidatorTx(t, constants.PrimaryNetworkID) + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.AddPrimaryNetworkValidatorFee, fc.Fee) + }, + }, + { + description: "AddPermissionlessValidatorTx Subnet pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + subnetID := ids.GenerateTestID() + require.NotEqual(t, constants.PrimaryNetworkID, subnetID) + return addPermissionlessValidatorTx(t, subnetID) + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.AddSubnetValidatorFee, fc.Fee) + }, + }, + { + description: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.AddPrimaryNetworkDelegatorFee, fc.Fee) + }, + }, + { + description: "AddPermissionlessDelegatorTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + subnetID := ids.GenerateTestID() + require.NotEqual(t, constants.PrimaryNetworkID, subnetID) + return addPermissionlessDelegatorTx(t, subnetID) + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.AddSubnetDelegatorFee, fc.Fee) + }, + }, + { + description: "BaseTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: baseTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.TxFee, fc.Fee) + }, + }, + { + description: "ImportTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: importTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.TxFee, fc.Fee) + }, + }, + { + description: "ExportTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: exportTx, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.config.TxFee, fc.Fee) + }, + }, + { + description: "RewardValidatorTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: func(_ *testing.T) (txs.UnsignedTx, *txs.Tx) { + return &txs.RewardValidatorTx{ + TxID: ids.GenerateTestID(), + }, nil + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, uint64(0), fc.Fee) + }, + }, + { + description: "AdvanceTimeTx pre EUpgrade", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eUpgradeTime + + return &cfg, chainTime + }, + unsignedAndSignedTx: func(_ *testing.T) (txs.UnsignedTx, *txs.Tx) { + return &txs.AdvanceTimeTx{ + Time: uint64(time.Now().Unix()), + }, nil + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, uint64(0), fc.Fee) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + uTx, _ := tt.unsignedAndSignedTx(t) + fc := NewStaticCalculator(cfg, chainTime) + + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func addValidatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, stakes, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.AddValidatorTx{ + BaseTx: baseTx, + Validator: txs.Validator{ + NodeID: defaultCtx.NodeID, + Start: uint64(time.Now().Truncate(time.Second).Unix()), + End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), + Wght: feeTestDefaultStakeWeight, + }, + StakeOuts: stakes, + RewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + DelegationShares: reward.PercentDenominator, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + + return uTx, sTx +} + +func addSubnetValidatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + subnetID := ids.GenerateTestID() + baseTx, _, subnetAuth := txsCreationHelpers(defaultCtx) + uTx := &txs.AddSubnetValidatorTx{ + BaseTx: baseTx, + SubnetValidator: txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: defaultCtx.NodeID, + Start: uint64(time.Now().Truncate(time.Second).Unix()), + End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), + Wght: feeTestDefaultStakeWeight, + }, + Subnet: subnetID, + }, + SubnetAuth: subnetAuth, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func addDelegatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, stakes, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.AddDelegatorTx{ + BaseTx: baseTx, + Validator: txs.Validator{ + NodeID: defaultCtx.NodeID, + Start: uint64(time.Now().Truncate(time.Second).Unix()), + End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), + Wght: feeTestDefaultStakeWeight, + }, + StakeOuts: stakes, + DelegationRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func createChainTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, subnetAuth := txsCreationHelpers(defaultCtx) + uTx := &txs.CreateChainTx{ + BaseTx: baseTx, + SubnetID: ids.GenerateTestID(), + ChainName: "testingStuff", + VMID: ids.GenerateTestID(), + FxIDs: []ids.ID{ids.GenerateTestID()}, + GenesisData: []byte{0xff}, + SubnetAuth: subnetAuth, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func createSubnetTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.CreateSubnetTx{ + BaseTx: baseTx, + Owner: &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func removeSubnetValidatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, auth := txsCreationHelpers(defaultCtx) + uTx := &txs.RemoveSubnetValidatorTx{ + BaseTx: baseTx, + NodeID: ids.GenerateTestNodeID(), + Subnet: ids.GenerateTestID(), + SubnetAuth: auth, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func transformSubnetTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, auth := txsCreationHelpers(defaultCtx) + uTx := &txs.TransformSubnetTx{ + BaseTx: baseTx, + Subnet: ids.GenerateTestID(), + AssetID: ids.GenerateTestID(), + InitialSupply: 0x1000000000000000, + MaximumSupply: 0x1000000000000000, + MinConsumptionRate: 0, + MaxConsumptionRate: 0, + MinValidatorStake: 1, + MaxValidatorStake: 0x1000000000000000, + MinStakeDuration: 1, + MaxStakeDuration: 1, + MinDelegationFee: 0, + MinDelegatorStake: 0xffffffffffffffff, + MaxValidatorWeightFactor: 255, + UptimeRequirement: 0, + SubnetAuth: auth, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func transferSubnetOwnershipTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.TransferSubnetOwnershipTx{ + BaseTx: baseTx, + Subnet: ids.GenerateTestID(), + SubnetAuth: &secp256k1fx.Input{ + SigIndices: []uint32{3}, + }, + Owner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func addPermissionlessValidatorTx(t *testing.T, subnetID ids.ID) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, stakes, _ := txsCreationHelpers(defaultCtx) + sk, err := bls.NewSecretKey() + r.NoError(err) + uTx := &txs.AddPermissionlessValidatorTx{ + BaseTx: baseTx, + Subnet: subnetID, + Signer: signer.NewProofOfPossession(sk), + StakeOuts: stakes, + ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + DelegationShares: reward.PercentDenominator, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func addPermissionlessDelegatorTx(t *testing.T, subnetID ids.ID) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, stakes, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.AddPermissionlessDelegatorTx{ + BaseTx: baseTx, + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: 12345, + End: 12345 + 200*24*60*60, + Wght: 2 * units.KiloAvax, + }, + Subnet: subnetID, + StakeOuts: stakes, + DelegationRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func baseTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, _ := txsCreationHelpers(defaultCtx) + uTx := &baseTx + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func importTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.ImportTx{ + BaseTx: baseTx, + SourceChain: ids.GenerateTestID(), + ImportedInputs: []*avax.TransferableInput{{ + UTXOID: avax.UTXOID{ + TxID: ids.Empty.Prefix(1), + OutputIndex: 1, + }, + Asset: avax.Asset{ID: ids.ID{'a', 's', 's', 'e', 'r', 't'}}, + In: &secp256k1fx.TransferInput{ + Amt: 50000, + Input: secp256k1fx.Input{SigIndices: []uint32{0}}, + }, + }}, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func exportTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, outputs, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.ExportTx{ + BaseTx: baseTx, + DestinationChain: ids.GenerateTestID(), + ExportedOutputs: outputs, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return uTx, sTx +} + +func txsCreationHelpers(defaultCtx *snow.Context) ( + baseTx txs.BaseTx, + stakes []*avax.TransferableOutput, + auth *secp256k1fx.Input, +) { + inputs := []*avax.TransferableInput{{ + UTXOID: avax.UTXOID{ + TxID: ids.ID{'t', 'x', 'I', 'D'}, + OutputIndex: 2, + }, + Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, + In: &secp256k1fx.TransferInput{ + Amt: uint64(5678), + Input: secp256k1fx.Input{SigIndices: []uint32{0}}, + }, + }} + outputs := []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: uint64(1234), + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + }, + }} + stakes = []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, + Out: &stakeable.LockOut{ + Locktime: uint64(time.Now().Add(time.Second).Unix()), + TransferableOut: &secp256k1fx.TransferOutput{ + Amt: feeTestDefaultStakeWeight, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + }, + }, + }} + auth = &secp256k1fx.Input{ + SigIndices: []uint32{0, 1}, + } + baseTx = txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: defaultCtx.NetworkID, + BlockchainID: defaultCtx.ChainID, + Ins: inputs, + Outs: outputs, + }, + } + + return baseTx, stakes, auth +} From 4583289ba03635d9022680fadb7e34ef2e66d234 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 23 Apr 2024 15:20:26 +0200 Subject: [PATCH 024/100] P chain introducing fees calculators fee config (#2960) Signed-off-by: Alberto Benegiamo --- node/node.go | 66 +++-- vms/platformvm/block/builder/helpers_test.go | 34 ++- vms/platformvm/block/executor/helpers_test.go | 34 ++- .../block/executor/verifier_test.go | 67 +++-- vms/platformvm/config/config.go | 72 +---- vms/platformvm/service_test.go | 10 +- vms/platformvm/txs/executor/helpers_test.go | 34 ++- .../txs/executor/staker_tx_verification.go | 43 ++- .../txs/executor/standard_tx_executor.go | 38 ++- .../txs/executor/standard_tx_executor_test.go | 19 +- vms/platformvm/txs/fee/calculator.go | 48 ++-- vms/platformvm/txs/fee/calculator_test.go | 257 ++++++++++-------- vms/platformvm/txs/fee/static_config.go | 65 +++++ vms/platformvm/txs/txstest/builder.go | 75 ++--- vms/platformvm/txs/txstest/context.go | 36 +-- vms/platformvm/upgrade/times.go | 50 ++++ vms/platformvm/validator_set_property_test.go | 36 ++- vms/platformvm/vm_regression_test.go | 11 +- vms/platformvm/vm_test.go | 108 +++++--- 19 files changed, 625 insertions(+), 478 deletions(-) create mode 100644 vms/platformvm/txs/fee/static_config.go create mode 100644 vms/platformvm/upgrade/times.go diff --git a/node/node.go b/node/node.go index 58e903404470..fd5781c9490c 100644 --- a/node/node.go +++ b/node/node.go @@ -75,6 +75,8 @@ import ( "github.com/ava-labs/avalanchego/vms/avm" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/registry" "github.com/ava-labs/avalanchego/vms/rpcchainvm/runtime" @@ -1126,36 +1128,40 @@ func (n *Node) initVMs() error { err := utils.Err( n.VMManager.RegisterFactory(context.TODO(), constants.PlatformVMID, &platformvm.Factory{ Config: platformconfig.Config{ - Chains: n.chainManager, - Validators: vdrs, - UptimeLockedCalculator: n.uptimeCalculator, - SybilProtectionEnabled: n.Config.SybilProtectionEnabled, - PartialSyncPrimaryNetwork: n.Config.PartialSyncPrimaryNetwork, - TrackedSubnets: n.Config.TrackedSubnets, - TxFee: n.Config.TxFee, - CreateAssetTxFee: n.Config.CreateAssetTxFee, - CreateSubnetTxFee: n.Config.CreateSubnetTxFee, - TransformSubnetTxFee: n.Config.TransformSubnetTxFee, - CreateBlockchainTxFee: n.Config.CreateBlockchainTxFee, - AddPrimaryNetworkValidatorFee: n.Config.AddPrimaryNetworkValidatorFee, - AddPrimaryNetworkDelegatorFee: n.Config.AddPrimaryNetworkDelegatorFee, - AddSubnetValidatorFee: n.Config.AddSubnetValidatorFee, - AddSubnetDelegatorFee: n.Config.AddSubnetDelegatorFee, - UptimePercentage: n.Config.UptimeRequirement, - MinValidatorStake: n.Config.MinValidatorStake, - MaxValidatorStake: n.Config.MaxValidatorStake, - MinDelegatorStake: n.Config.MinDelegatorStake, - MinDelegationFee: n.Config.MinDelegationFee, - MinStakeDuration: n.Config.MinStakeDuration, - MaxStakeDuration: n.Config.MaxStakeDuration, - RewardConfig: n.Config.RewardConfig, - ApricotPhase3Time: version.GetApricotPhase3Time(n.Config.NetworkID), - ApricotPhase5Time: version.GetApricotPhase5Time(n.Config.NetworkID), - BanffTime: version.GetBanffTime(n.Config.NetworkID), - CortinaTime: version.GetCortinaTime(n.Config.NetworkID), - DurangoTime: version.GetDurangoTime(n.Config.NetworkID), - EUpgradeTime: eUpgradeTime, - UseCurrentHeight: n.Config.UseCurrentHeight, + Chains: n.chainManager, + Validators: vdrs, + UptimeLockedCalculator: n.uptimeCalculator, + SybilProtectionEnabled: n.Config.SybilProtectionEnabled, + PartialSyncPrimaryNetwork: n.Config.PartialSyncPrimaryNetwork, + TrackedSubnets: n.Config.TrackedSubnets, + StaticConfig: fee.StaticConfig{ + TxFee: n.Config.TxFee, + CreateAssetTxFee: n.Config.CreateAssetTxFee, + CreateSubnetTxFee: n.Config.CreateSubnetTxFee, + TransformSubnetTxFee: n.Config.TransformSubnetTxFee, + CreateBlockchainTxFee: n.Config.CreateBlockchainTxFee, + AddPrimaryNetworkValidatorFee: n.Config.AddPrimaryNetworkValidatorFee, + AddPrimaryNetworkDelegatorFee: n.Config.AddPrimaryNetworkDelegatorFee, + AddSubnetValidatorFee: n.Config.AddSubnetValidatorFee, + AddSubnetDelegatorFee: n.Config.AddSubnetDelegatorFee, + }, + UptimePercentage: n.Config.UptimeRequirement, + MinValidatorStake: n.Config.MinValidatorStake, + MaxValidatorStake: n.Config.MaxValidatorStake, + MinDelegatorStake: n.Config.MinDelegatorStake, + MinDelegationFee: n.Config.MinDelegationFee, + MinStakeDuration: n.Config.MinStakeDuration, + MaxStakeDuration: n.Config.MaxStakeDuration, + RewardConfig: n.Config.RewardConfig, + Times: upgrade.Times{ + ApricotPhase3Time: version.GetApricotPhase3Time(n.Config.NetworkID), + ApricotPhase5Time: version.GetApricotPhase5Time(n.Config.NetworkID), + BanffTime: version.GetBanffTime(n.Config.NetworkID), + CortinaTime: version.GetCortinaTime(n.Config.NetworkID), + DurangoTime: version.GetDurangoTime(n.Config.NetworkID), + EUpgradeTime: eUpgradeTime, + }, + UseCurrentHeight: n.Config.UseCurrentHeight, }, }), n.VMManager.RegisterFactory(context.TODO(), constants.AVMID, &avm.Factory{ diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 958ef92ae5c2..46f1731f6efe 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -43,8 +43,10 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -307,26 +309,30 @@ func defaultConfig(t *testing.T, f fork) *config.Config { Chains: chains.TestManager, UptimeLockedCalculator: uptime.NewLockedCalculator(), Validators: validators.NewManager(), - TxFee: defaultTxFee, - CreateSubnetTxFee: 100 * defaultTxFee, - CreateBlockchainTxFee: 100 * defaultTxFee, - MinValidatorStake: 5 * units.MilliAvax, - MaxValidatorStake: 500 * units.MilliAvax, - MinDelegatorStake: 1 * units.MilliAvax, - MinStakeDuration: defaultMinStakingDuration, - MaxStakeDuration: defaultMaxStakingDuration, + StaticConfig: fee.StaticConfig{ + TxFee: defaultTxFee, + CreateSubnetTxFee: 100 * defaultTxFee, + CreateBlockchainTxFee: 100 * defaultTxFee, + }, + MinValidatorStake: 5 * units.MilliAvax, + MaxValidatorStake: 500 * units.MilliAvax, + MinDelegatorStake: 1 * units.MilliAvax, + MinStakeDuration: defaultMinStakingDuration, + MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: reward.Config{ MaxConsumptionRate: .12 * reward.PercentDenominator, MinConsumptionRate: .10 * reward.PercentDenominator, MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - ApricotPhase3Time: mockable.MaxTime, - ApricotPhase5Time: mockable.MaxTime, - BanffTime: mockable.MaxTime, - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + ApricotPhase3Time: mockable.MaxTime, + ApricotPhase5Time: mockable.MaxTime, + BanffTime: mockable.MaxTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, } switch f { diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 0849146afcf6..bf17dcc84dd1 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -44,8 +44,10 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -329,26 +331,30 @@ func defaultConfig(t *testing.T, f fork) *config.Config { Chains: chains.TestManager, UptimeLockedCalculator: uptime.NewLockedCalculator(), Validators: validators.NewManager(), - TxFee: defaultTxFee, - CreateSubnetTxFee: 100 * defaultTxFee, - CreateBlockchainTxFee: 100 * defaultTxFee, - MinValidatorStake: 5 * units.MilliAvax, - MaxValidatorStake: 500 * units.MilliAvax, - MinDelegatorStake: 1 * units.MilliAvax, - MinStakeDuration: defaultMinStakingDuration, - MaxStakeDuration: defaultMaxStakingDuration, + StaticConfig: fee.StaticConfig{ + TxFee: defaultTxFee, + CreateSubnetTxFee: 100 * defaultTxFee, + CreateBlockchainTxFee: 100 * defaultTxFee, + }, + MinValidatorStake: 5 * units.MilliAvax, + MaxValidatorStake: 500 * units.MilliAvax, + MinDelegatorStake: 1 * units.MilliAvax, + MinStakeDuration: defaultMinStakingDuration, + MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: reward.Config{ MaxConsumptionRate: .12 * reward.PercentDenominator, MinConsumptionRate: .10 * reward.PercentDenominator, MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - ApricotPhase3Time: mockable.MaxTime, - ApricotPhase5Time: mockable.MaxTime, - BanffTime: mockable.MaxTime, - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + ApricotPhase3Time: mockable.MaxTime, + ApricotPhase5Time: mockable.MaxTime, + BanffTime: mockable.MaxTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, } switch f { diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index ba24fb2f1298..c8ea158f9dfa 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" ) func TestVerifierVisitProposalBlock(t *testing.T) { @@ -58,7 +59,9 @@ func TestVerifierVisitProposalBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + Times: upgrade.Times{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -142,8 +145,10 @@ func TestVerifierVisitAtomicBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - ApricotPhase5Time: time.Now().Add(time.Hour), - BanffTime: mockable.MaxTime, // banff is not activated + Times: upgrade.Times{ + ApricotPhase5Time: time.Now().Add(time.Hour), + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -229,8 +234,10 @@ func TestVerifierVisitStandardBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - ApricotPhase5Time: time.Now().Add(time.Hour), - BanffTime: mockable.MaxTime, // banff is not activated + Times: upgrade.Times{ + ApricotPhase5Time: time.Now().Add(time.Hour), + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -334,7 +341,9 @@ func TestVerifierVisitCommitBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + Times: upgrade.Times{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -405,7 +414,9 @@ func TestVerifierVisitAbortBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + Times: upgrade.Times{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -464,7 +475,9 @@ func TestVerifyUnverifiedParent(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + Times: upgrade.Times{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -536,7 +549,9 @@ func TestBanffAbortBlockTimestampChecks(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: time.Time{}, // banff is activated + Times: upgrade.Times{ + BanffTime: time.Time{}, // banff is activated + }, }, Clk: &mockable.Clock{}, }, @@ -632,7 +647,9 @@ func TestBanffCommitBlockTimestampChecks(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: time.Time{}, // banff is activated + Times: upgrade.Times{ + BanffTime: time.Time{}, // banff is activated + }, }, Clk: &mockable.Clock{}, }, @@ -711,8 +728,10 @@ func TestVerifierVisitStandardBlockWithDuplicateInputs(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - ApricotPhase5Time: time.Now().Add(time.Hour), - BanffTime: mockable.MaxTime, // banff is not activated + Times: upgrade.Times{ + ApricotPhase5Time: time.Now().Add(time.Hour), + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -800,7 +819,9 @@ func TestVerifierVisitApricotStandardBlockWithProposalBlockParent(t *testing.T) verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + Times: upgrade.Times{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -857,7 +878,9 @@ func TestVerifierVisitBanffStandardBlockWithProposalBlockParent(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: time.Time{}, // banff is activated + Times: upgrade.Times{ + BanffTime: time.Time{}, // banff is activated + }, }, Clk: &mockable.Clock{}, }, @@ -894,7 +917,9 @@ func TestVerifierVisitApricotCommitBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + Times: upgrade.Times{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -937,7 +962,9 @@ func TestVerifierVisitBanffCommitBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: time.Time{}, // banff is activated + Times: upgrade.Times{ + BanffTime: time.Time{}, // banff is activated + }, }, Clk: &mockable.Clock{}, }, @@ -981,7 +1008,9 @@ func TestVerifierVisitApricotAbortBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + Times: upgrade.Times{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -1024,7 +1053,9 @@ func TestVerifierVisitBanffAbortBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: time.Time{}, // banff is activated + Times: upgrade.Times{ + BanffTime: time.Time{}, // banff is activated + }, }, Clk: &mockable.Clock{}, }, diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 07cb74a8fd18..ed7ab7945ec7 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -14,6 +14,8 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" ) // Struct collecting all foundational parameters of PlatformVM @@ -41,32 +43,7 @@ type Config struct { // Set of subnets that this node is validating TrackedSubnets set.Set[ids.ID] - // Fee that is burned by every non-state creating transaction - TxFee uint64 - - // Fee that must be burned by every state creating transaction before AP3 - CreateAssetTxFee uint64 - - // Fee that must be burned by every subnet creating transaction after AP3 - CreateSubnetTxFee uint64 - - // Fee that must be burned by every transform subnet transaction - TransformSubnetTxFee uint64 - - // Fee that must be burned by every blockchain creating transaction after AP3 - CreateBlockchainTxFee uint64 - - // Transaction fee for adding a primary network validator - AddPrimaryNetworkValidatorFee uint64 - - // Transaction fee for adding a primary network delegator - AddPrimaryNetworkDelegatorFee uint64 - - // Transaction fee for adding a subnet validator - AddSubnetValidatorFee uint64 - - // Transaction fee for adding a subnet delegator - AddSubnetDelegatorFee uint64 + fee.StaticConfig // The minimum amount of tokens one must bond to be a validator MinValidatorStake uint64 @@ -92,23 +69,8 @@ type Config struct { // Config for the minting function RewardConfig reward.Config - // Time of the AP3 network upgrade - ApricotPhase3Time time.Time - - // Time of the AP5 network upgrade - ApricotPhase5Time time.Time - - // Time of the Banff network upgrade - BanffTime time.Time - - // Time of the Cortina network upgrade - CortinaTime time.Time - - // Time of the Durango network upgrade - DurangoTime time.Time - - // Time of the E network upgrade - EUpgradeTime time.Time + // All network upgrade timestamps + upgrade.Times // UseCurrentHeight forces [GetMinimumHeight] to return the current height // of the P-Chain instead of the oldest block in the [recentlyAccepted] @@ -120,30 +82,6 @@ type Config struct { UseCurrentHeight bool } -func (c *Config) IsApricotPhase3Activated(timestamp time.Time) bool { - return !timestamp.Before(c.ApricotPhase3Time) -} - -func (c *Config) IsApricotPhase5Activated(timestamp time.Time) bool { - return !timestamp.Before(c.ApricotPhase5Time) -} - -func (c *Config) IsBanffActivated(timestamp time.Time) bool { - return !timestamp.Before(c.BanffTime) -} - -func (c *Config) IsCortinaActivated(timestamp time.Time) bool { - return !timestamp.Before(c.CortinaTime) -} - -func (c *Config) IsDurangoActivated(timestamp time.Time) bool { - return !timestamp.Before(c.DurangoTime) -} - -func (c *Config) IsEActivated(timestamp time.Time) bool { - return !timestamp.Before(c.EUpgradeTime) -} - // Create the blockchain described in [tx], but only if this node is a member of // the subnet that validates the chain func (c *Config) CreateChain(chainID ids.ID, tx *txs.CreateChainTx) { diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 3224edb2d73d..60d599bfeb12 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -39,7 +39,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -366,10 +365,9 @@ func TestGetBalance(t *testing.T) { require := require.New(t) service, _, _ := defaultService(t) - staticFeeCalc := fee.NewStaticCalculator(&service.vm.Config, service.vm.clock.Time()) - dummyCreateSubnetTx := &txs.CreateSubnetTx{} - require.NoError(dummyCreateSubnetTx.Visit(staticFeeCalc)) - createSubnetFee := staticFeeCalc.Fee + staticFeesCfg := service.vm.Config.StaticConfig + upgrades := service.vm.Config.Times + createSubnetFee := staticFeesCfg.GetCreateSubnetTxFee(upgrades, service.vm.clock.Time()) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) @@ -755,7 +753,7 @@ func TestGetBlock(t *testing.T) { service, _, txBuilder := defaultService(t) service.vm.ctx.Lock.Lock() - service.vm.Config.CreateAssetTxFee = 100 * defaultTxFee + service.vm.CreateAssetTxFee = 100 * defaultTxFee // Make a block an accept it, then check we can get it. tx, err := txBuilder.NewCreateChainTx( // Test GetTx works for standard blocks diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 387b5d2a831d..c14dbe9c459c 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -41,7 +41,9 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -278,26 +280,30 @@ func defaultConfig(t *testing.T, f fork) *config.Config { Chains: chains.TestManager, UptimeLockedCalculator: uptime.NewLockedCalculator(), Validators: validators.NewManager(), - TxFee: defaultTxFee, - CreateSubnetTxFee: 100 * defaultTxFee, - CreateBlockchainTxFee: 100 * defaultTxFee, - MinValidatorStake: 5 * units.MilliAvax, - MaxValidatorStake: 500 * units.MilliAvax, - MinDelegatorStake: 1 * units.MilliAvax, - MinStakeDuration: defaultMinStakingDuration, - MaxStakeDuration: defaultMaxStakingDuration, + StaticConfig: fee.StaticConfig{ + TxFee: defaultTxFee, + CreateSubnetTxFee: 100 * defaultTxFee, + CreateBlockchainTxFee: 100 * defaultTxFee, + }, + MinValidatorStake: 5 * units.MilliAvax, + MaxValidatorStake: 500 * units.MilliAvax, + MinDelegatorStake: 1 * units.MilliAvax, + MinStakeDuration: defaultMinStakingDuration, + MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: reward.Config{ MaxConsumptionRate: .12 * reward.PercentDenominator, MinConsumptionRate: .10 * reward.PercentDenominator, MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - ApricotPhase3Time: mockable.MaxTime, - ApricotPhase5Time: mockable.MaxTime, - BanffTime: mockable.MaxTime, - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + ApricotPhase3Time: mockable.MaxTime, + ApricotPhase5Time: mockable.MaxTime, + BanffTime: mockable.MaxTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, } switch f { diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 86cf4b179985..6a235a0fa011 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -164,7 +164,11 @@ func verifyAddValidatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config, currentTimestamp) + var ( + staticFeesCfg = backend.Config.StaticConfig + upgrades = backend.Config.Times + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -257,7 +261,11 @@ func verifyAddSubnetValidatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config, currentTimestamp) + var ( + staticFeesCfg = backend.Config.StaticConfig + upgrades = backend.Config.Times + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -337,7 +345,11 @@ func verifyRemoveSubnetValidatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + var ( + staticFeesCfg = backend.Config.StaticConfig + upgrades = backend.Config.Times + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, false, err } @@ -457,7 +469,11 @@ func verifyAddDelegatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + var ( + staticFeesCfg = backend.Config.StaticConfig + upgrades = backend.Config.Times + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -579,7 +595,11 @@ func verifyAddPermissionlessValidatorTx( copy(outs[len(tx.Outs):], tx.StakeOuts) // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config, currentTimestamp) + var ( + staticFeesCfg = backend.Config.StaticConfig + upgrades = backend.Config.Times + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -726,7 +746,11 @@ func verifyAddPermissionlessDelegatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config, currentTimestamp) + var ( + staticFeesCfg = backend.Config.StaticConfig + upgrades = backend.Config.Times + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -783,7 +807,12 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + var ( + staticFeesCfg = backend.Config.StaticConfig + upgrades = backend.Config.Times + currentTimestamp = chainState.GetTimestamp() + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 8cbc0a58cd5a..487420e1142a 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -69,7 +69,11 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + var ( + staticFeesCfg = e.Backend.Config.StaticConfig + upgrades = e.Backend.Config.Times + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -119,7 +123,11 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + var ( + staticFeesCfg = e.Backend.Config.StaticConfig + upgrades = e.Backend.Config.Times + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -204,7 +212,11 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + var ( + staticFeesCfg = e.Backend.Config.StaticConfig + upgrades = e.Backend.Config.Times + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -265,7 +277,11 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + var ( + staticFeesCfg = e.Backend.Config.StaticConfig + upgrades = e.Backend.Config.Times + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -455,11 +471,16 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error return err } - totalRewardAmount := tx.MaximumSupply - tx.InitialSupply - feeCalculator := fee.NewStaticCalculator(e.Backend.Config, currentTimestamp) + var ( + staticFeesCfg = e.Backend.Config.StaticConfig + upgrades = e.Backend.Config.Times + ) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } + + totalRewardAmount := tx.MaximumSupply - tx.InitialSupply if err := e.Backend.FlowChecker.VerifySpend( tx, e.State, @@ -580,10 +601,11 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { // Verify the flowcheck var ( - cfg = e.Backend.Config + staticFeesCfg = e.Backend.Config.StaticConfig + upgrades = e.Backend.Config.Times currentTimestamp = e.State.GetTimestamp() ) - feeCalculator := fee.NewStaticCalculator(cfg, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 0e274dd85860..8463645a624a 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -31,6 +31,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -1585,7 +1586,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) // Set dependency expectations. - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil).Times(1) subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil).Times(1) @@ -1766,7 +1767,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { newExecutor: func(ctrl *gomock.Controller) (*txs.RemoveSubnetValidatorTx, *StandardTxExecutor) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil) @@ -2080,12 +2081,14 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { func defaultTestConfig(t *testing.T, f fork, tm time.Time) *config.Config { c := &config.Config{ - ApricotPhase3Time: mockable.MaxTime, - ApricotPhase5Time: mockable.MaxTime, - BanffTime: mockable.MaxTime, - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + ApricotPhase3Time: mockable.MaxTime, + ApricotPhase5Time: mockable.MaxTime, + BanffTime: mockable.MaxTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, } switch f { diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 038cbdc7ebf5..2b69dbff8478 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -7,58 +7,52 @@ import ( "time" "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" ) var _ txs.Visitor = (*Calculator)(nil) type Calculator struct { // Pre E-fork inputs - config *config.Config + upgrades upgrade.Times + staticCfg StaticConfig chainTime time.Time // outputs of visitor execution Fee uint64 } -func NewStaticCalculator(cfg *config.Config, chainTime time.Time) *Calculator { +func NewStaticCalculator(cfg StaticConfig, ut upgrade.Times, chainTime time.Time) *Calculator { return &Calculator{ - config: cfg, + upgrades: ut, + staticCfg: cfg, chainTime: chainTime, } } func (fc *Calculator) AddValidatorTx(*txs.AddValidatorTx) error { - fc.Fee = fc.config.AddPrimaryNetworkValidatorFee + fc.Fee = fc.staticCfg.AddPrimaryNetworkValidatorFee return nil } func (fc *Calculator) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { - fc.Fee = fc.config.AddSubnetValidatorFee + fc.Fee = fc.staticCfg.AddSubnetValidatorFee return nil } func (fc *Calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { - fc.Fee = fc.config.AddPrimaryNetworkDelegatorFee + fc.Fee = fc.staticCfg.AddPrimaryNetworkDelegatorFee return nil } func (fc *Calculator) CreateChainTx(*txs.CreateChainTx) error { - if fc.config.IsApricotPhase3Activated(fc.chainTime) { - fc.Fee = fc.config.CreateBlockchainTxFee - } else { - fc.Fee = fc.config.CreateAssetTxFee - } + fc.Fee = fc.staticCfg.GetCreateBlockchainTxFee(fc.upgrades, fc.chainTime) return nil } func (fc *Calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { - if fc.config.IsApricotPhase3Activated(fc.chainTime) { - fc.Fee = fc.config.CreateSubnetTxFee - } else { - fc.Fee = fc.config.CreateAssetTxFee - } + fc.Fee = fc.staticCfg.GetCreateSubnetTxFee(fc.upgrades, fc.chainTime) return nil } @@ -71,49 +65,49 @@ func (*Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { } func (fc *Calculator) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { - fc.Fee = fc.config.TxFee + fc.Fee = fc.staticCfg.TxFee return nil } func (fc *Calculator) TransformSubnetTx(*txs.TransformSubnetTx) error { - fc.Fee = fc.config.TransformSubnetTxFee + fc.Fee = fc.staticCfg.TransformSubnetTxFee return nil } func (fc *Calculator) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { - fc.Fee = fc.config.TxFee + fc.Fee = fc.staticCfg.TxFee return nil } func (fc *Calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { if tx.Subnet != constants.PrimaryNetworkID { - fc.Fee = fc.config.AddSubnetValidatorFee + fc.Fee = fc.staticCfg.AddSubnetValidatorFee } else { - fc.Fee = fc.config.AddPrimaryNetworkValidatorFee + fc.Fee = fc.staticCfg.AddPrimaryNetworkValidatorFee } return nil } func (fc *Calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { if tx.Subnet != constants.PrimaryNetworkID { - fc.Fee = fc.config.AddSubnetDelegatorFee + fc.Fee = fc.staticCfg.AddSubnetDelegatorFee } else { - fc.Fee = fc.config.AddPrimaryNetworkDelegatorFee + fc.Fee = fc.staticCfg.AddPrimaryNetworkDelegatorFee } return nil } func (fc *Calculator) BaseTx(*txs.BaseTx) error { - fc.Fee = fc.config.TxFee + fc.Fee = fc.staticCfg.TxFee return nil } func (fc *Calculator) ImportTx(*txs.ImportTx) error { - fc.Fee = fc.config.TxFee + fc.Fee = fc.staticCfg.TxFee return nil } func (fc *Calculator) ExportTx(*txs.ExportTx) error { - fc.Fee = fc.config.TxFee + fc.Fee = fc.staticCfg.TxFee return nil } diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index fd2348dd6d0a..c4424e3a2d4f 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -18,16 +18,16 @@ import ( "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) var ( - feeTestsDefaultCfg = config.Config{ + feeTestsDefaultCfg = StaticConfig{ TxFee: 1 * units.Avax, CreateAssetTxFee: 2 * units.Avax, CreateSubnetTxFee: 3 * units.Avax, @@ -47,7 +47,7 @@ var ( type feeTests struct { description string - cfgAndChainTimeF func() (*config.Config, time.Time) + cfgAndChainTimeF func() (StaticConfig, upgrade.Times, time.Time) unsignedAndSignedTx func(t *testing.T) (txs.UnsignedTx, *txs.Tx) expectedError error checksF func(*testing.T, *Calculator) @@ -59,217 +59,229 @@ func TestTxFees(t *testing.T) { tests := []feeTests{ { description: "AddValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: addValidatorTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.AddPrimaryNetworkValidatorFee, fc.Fee) + require.Equal(t, fc.staticCfg.AddPrimaryNetworkValidatorFee, fc.Fee) }, }, { description: "AddSubnetValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: addSubnetValidatorTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.AddSubnetValidatorFee, fc.Fee) + require.Equal(t, fc.staticCfg.AddSubnetValidatorFee, fc.Fee) }, }, { description: "AddDelegatorTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: addDelegatorTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.AddPrimaryNetworkDelegatorFee, fc.Fee) + require.Equal(t, fc.staticCfg.AddPrimaryNetworkDelegatorFee, fc.Fee) }, }, { description: "CreateChainTx pre ApricotPhase3", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { apricotPhase3Time := time.Now().Truncate(time.Second) chainTime := apricotPhase3Time.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.ApricotPhase3Time = apricotPhase3Time - cfg.DurangoTime = mockable.MaxTime - cfg.EUpgradeTime = mockable.MaxTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + ApricotPhase3Time: apricotPhase3Time, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: createChainTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.CreateAssetTxFee, fc.Fee) + require.Equal(t, fc.staticCfg.CreateAssetTxFee, fc.Fee) }, }, { description: "CreateChainTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: createChainTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.CreateBlockchainTxFee, fc.Fee) + require.Equal(t, fc.staticCfg.CreateBlockchainTxFee, fc.Fee) }, }, { description: "CreateSubnetTx pre ApricotPhase3", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { apricotPhase3Time := time.Now().Truncate(time.Second) chainTime := apricotPhase3Time.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.ApricotPhase3Time = apricotPhase3Time - cfg.DurangoTime = mockable.MaxTime - cfg.EUpgradeTime = mockable.MaxTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + ApricotPhase3Time: apricotPhase3Time, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: createSubnetTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.CreateAssetTxFee, fc.Fee) + require.Equal(t, fc.staticCfg.CreateAssetTxFee, fc.Fee) }, }, { description: "CreateSubnetTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: createSubnetTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.CreateSubnetTxFee, fc.Fee) + require.Equal(t, fc.staticCfg.CreateSubnetTxFee, fc.Fee) }, }, { description: "RemoveSubnetValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: removeSubnetValidatorTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.TxFee, fc.Fee) + require.Equal(t, fc.staticCfg.TxFee, fc.Fee) }, }, { description: "TransformSubnetTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: transformSubnetTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.TransformSubnetTxFee, fc.Fee) + require.Equal(t, fc.staticCfg.TransformSubnetTxFee, fc.Fee) }, }, { description: "TransferSubnetOwnershipTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: transferSubnetOwnershipTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.TxFee, fc.Fee) + require.Equal(t, fc.staticCfg.TxFee, fc.Fee) }, }, { description: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { return addPermissionlessValidatorTx(t, constants.PrimaryNetworkID) }, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.AddPrimaryNetworkValidatorFee, fc.Fee) + require.Equal(t, fc.staticCfg.AddPrimaryNetworkValidatorFee, fc.Fee) }, }, { description: "AddPermissionlessValidatorTx Subnet pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { subnetID := ids.GenerateTestID() @@ -278,40 +290,42 @@ func TestTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.AddSubnetValidatorFee, fc.Fee) + require.Equal(t, fc.staticCfg.AddSubnetValidatorFee, fc.Fee) }, }, { description: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) }, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.AddPrimaryNetworkDelegatorFee, fc.Fee) + require.Equal(t, fc.staticCfg.AddPrimaryNetworkDelegatorFee, fc.Fee) }, }, { description: "AddPermissionlessDelegatorTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { subnetID := ids.GenerateTestID() @@ -320,74 +334,78 @@ func TestTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.AddSubnetDelegatorFee, fc.Fee) + require.Equal(t, fc.staticCfg.AddSubnetDelegatorFee, fc.Fee) }, }, { description: "BaseTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: baseTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.TxFee, fc.Fee) + require.Equal(t, fc.staticCfg.TxFee, fc.Fee) }, }, { description: "ImportTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: importTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.TxFee, fc.Fee) + require.Equal(t, fc.staticCfg.TxFee, fc.Fee) }, }, { description: "ExportTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: exportTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.config.TxFee, fc.Fee) + require.Equal(t, fc.staticCfg.TxFee, fc.Fee) }, }, { description: "RewardValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: func(_ *testing.T) (txs.UnsignedTx, *txs.Tx) { return &txs.RewardValidatorTx{ @@ -401,15 +419,16 @@ func TestTxFees(t *testing.T) { }, { description: "AdvanceTimeTx pre EUpgrade", - cfgAndChainTimeF: func() (*config.Config, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eUpgradeTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: func(_ *testing.T) (txs.UnsignedTx, *txs.Tx) { return &txs.AdvanceTimeTx{ @@ -425,10 +444,10 @@ func TestTxFees(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() + cfg, upgrades, chainTime := tt.cfgAndChainTimeF() uTx, _ := tt.unsignedAndSignedTx(t) - fc := NewStaticCalculator(cfg, chainTime) + fc := NewStaticCalculator(cfg, upgrades, chainTime) err := uTx.Visit(fc) r.ErrorIs(err, tt.expectedError) diff --git a/vms/platformvm/txs/fee/static_config.go b/vms/platformvm/txs/fee/static_config.go new file mode 100644 index 000000000000..f2abb6d4d569 --- /dev/null +++ b/vms/platformvm/txs/fee/static_config.go @@ -0,0 +1,65 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "time" + + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" +) + +type StaticConfig struct { + // Fee that is burned by every non-state creating transaction + TxFee uint64 + + // Fee that must be burned by every state creating transaction before AP3 + CreateAssetTxFee uint64 + + // Fee that must be burned by every subnet creating transaction after AP3 + CreateSubnetTxFee uint64 + + // Fee that must be burned by every transform subnet transaction + TransformSubnetTxFee uint64 + + // Fee that must be burned by every blockchain creating transaction after AP3 + CreateBlockchainTxFee uint64 + + // Transaction fee for adding a primary network validator + AddPrimaryNetworkValidatorFee uint64 + + // Transaction fee for adding a primary network delegator + AddPrimaryNetworkDelegatorFee uint64 + + // Transaction fee for adding a subnet validator + AddSubnetValidatorFee uint64 + + // Transaction fee for adding a subnet delegator + AddSubnetDelegatorFee uint64 + + // The minimum amount of tokens one must bond to be a validator + MinValidatorStake uint64 + + // The maximum amount of tokens that can be bonded on a validator + MaxValidatorStake uint64 + + // Minimum stake, in nAVAX, that can be delegated on the primary network + MinDelegatorStake uint64 + + // Minimum fee that can be charged for delegation + MinDelegationFee uint32 +} + +func (c *StaticConfig) GetCreateBlockchainTxFee(upgrades upgrade.Times, timestamp time.Time) uint64 { + if upgrades.IsApricotPhase3Activated(timestamp) { + return c.CreateBlockchainTxFee + } + return c.CreateAssetTxFee +} + +func (c *StaticConfig) GetCreateSubnetTxFee(upgrades upgrade.Times, timestamp time.Time) uint64 { + if upgrades.IsApricotPhase3Activated(timestamp) { + return c.CreateSubnetTxFee + } + return c.CreateAssetTxFee +} diff --git a/vms/platformvm/txs/txstest/builder.go b/vms/platformvm/txs/txstest/builder.go index 92f40f4b4176..bfc50d7454d6 100644 --- a/vms/platformvm/txs/txstest/builder.go +++ b/vms/platformvm/txs/txstest/builder.go @@ -47,10 +47,7 @@ func (b *Builder) NewImportTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewImportTx( chainID, @@ -70,10 +67,7 @@ func (b *Builder) NewExportTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewExportTx( chainID, @@ -96,10 +90,7 @@ func (b *Builder) NewCreateChainTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewCreateChainTx( subnetID, @@ -121,10 +112,7 @@ func (b *Builder) NewCreateSubnetTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewCreateSubnetTx( owner, @@ -155,10 +143,7 @@ func (b *Builder) NewTransformSubnetTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewTransformSubnetTx( subnetID, @@ -191,10 +176,7 @@ func (b *Builder) NewAddValidatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewAddValidatorTx( vdr, @@ -219,10 +201,7 @@ func (b *Builder) NewAddPermissionlessValidatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewAddPermissionlessValidatorTx( vdr, @@ -246,10 +225,7 @@ func (b *Builder) NewAddDelegatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewAddDelegatorTx( vdr, @@ -270,10 +246,7 @@ func (b *Builder) NewAddPermissionlessDelegatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewAddPermissionlessDelegatorTx( vdr, @@ -293,10 +266,7 @@ func (b *Builder) NewAddSubnetValidatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewAddSubnetValidatorTx( vdr, @@ -315,10 +285,7 @@ func (b *Builder) NewRemoveSubnetValidatorTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewRemoveSubnetValidatorTx( nodeID, @@ -338,10 +305,7 @@ func (b *Builder) NewTransferSubnetOwnershipTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewTransferSubnetOwnershipTx( subnetID, @@ -360,10 +324,7 @@ func (b *Builder) NewBaseTx( keys []*secp256k1.PrivateKey, options ...common.Option, ) (*txs.Tx, error) { - pBuilder, pSigner, err := b.builders(keys) - if err != nil { - return nil, err - } + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewBaseTx( outputs, @@ -376,19 +337,15 @@ func (b *Builder) NewBaseTx( return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *Builder) builders(keys []*secp256k1.PrivateKey) (builder.Builder, walletsigner.Signer, error) { +func (b *Builder) builders(keys []*secp256k1.PrivateKey) (builder.Builder, walletsigner.Signer) { var ( kc = secp256k1fx.NewKeychain(keys...) addrs = kc.Addresses() + context = newContext(b.ctx, b.cfg, b.state.GetTimestamp()) backend = newBackend(addrs, b.state, b.ctx.SharedMemory) ) - context, err := newContext(b.ctx, b.cfg, b.state.GetTimestamp()) - if err != nil { - return nil, nil, err - } - builder := builder.New(addrs, context, backend) signer := walletsigner.New(kc, backend) - return builder, signer, nil + return builder, signer } diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index e756d145e57b..88e03c07fd1c 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -8,8 +8,6 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/vms/platformvm/config" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) @@ -17,32 +15,22 @@ func newContext( ctx *snow.Context, cfg *config.Config, timestamp time.Time, -) (*builder.Context, error) { +) *builder.Context { var ( - staticFeeCalc = fee.NewStaticCalculator(cfg, timestamp) - createSubnetTx = &txs.CreateSubnetTx{} - createChainTx = &txs.CreateChainTx{} + staticFeesCfg = cfg.StaticConfig + upgrades = cfg.Times ) - if err := createSubnetTx.Visit(staticFeeCalc); err != nil { - return nil, err - } - createSubnetFee := staticFeeCalc.Fee - - if err := createChainTx.Visit(staticFeeCalc); err != nil { - return nil, err - } - createChainFee := staticFeeCalc.Fee return &builder.Context{ NetworkID: ctx.NetworkID, AVAXAssetID: ctx.AVAXAssetID, - BaseTxFee: cfg.TxFee, - CreateSubnetTxFee: createSubnetFee, - TransformSubnetTxFee: cfg.TransformSubnetTxFee, - CreateBlockchainTxFee: createChainFee, - AddPrimaryNetworkValidatorFee: cfg.AddPrimaryNetworkValidatorFee, - AddPrimaryNetworkDelegatorFee: cfg.AddPrimaryNetworkDelegatorFee, - AddSubnetValidatorFee: cfg.AddSubnetValidatorFee, - AddSubnetDelegatorFee: cfg.AddSubnetDelegatorFee, - }, nil + BaseTxFee: staticFeesCfg.TxFee, + CreateSubnetTxFee: staticFeesCfg.GetCreateSubnetTxFee(upgrades, timestamp), + TransformSubnetTxFee: staticFeesCfg.TransformSubnetTxFee, + CreateBlockchainTxFee: staticFeesCfg.GetCreateBlockchainTxFee(upgrades, timestamp), + AddPrimaryNetworkValidatorFee: staticFeesCfg.AddPrimaryNetworkValidatorFee, + AddPrimaryNetworkDelegatorFee: staticFeesCfg.AddPrimaryNetworkDelegatorFee, + AddSubnetValidatorFee: staticFeesCfg.AddSubnetValidatorFee, + AddSubnetDelegatorFee: staticFeesCfg.AddSubnetDelegatorFee, + } } diff --git a/vms/platformvm/upgrade/times.go b/vms/platformvm/upgrade/times.go new file mode 100644 index 000000000000..f4c6bacecf9c --- /dev/null +++ b/vms/platformvm/upgrade/times.go @@ -0,0 +1,50 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package upgrade + +import "time" + +type Times struct { + // Time of the AP3 network upgrade + ApricotPhase3Time time.Time + + // Time of the AP5 network upgrade + ApricotPhase5Time time.Time + + // Time of the Banff network upgrade + BanffTime time.Time + + // Time of the Cortina network upgrade + CortinaTime time.Time + + // Time of the Durango network upgrade + DurangoTime time.Time + + // Time of the E network upgrade + EUpgradeTime time.Time +} + +func (t *Times) IsApricotPhase3Activated(timestamp time.Time) bool { + return !timestamp.Before(t.ApricotPhase3Time) +} + +func (t *Times) IsApricotPhase5Activated(timestamp time.Time) bool { + return !timestamp.Before(t.ApricotPhase5Time) +} + +func (t *Times) IsBanffActivated(timestamp time.Time) bool { + return !timestamp.Before(t.BanffTime) +} + +func (t *Times) IsCortinaActivated(timestamp time.Time) bool { + return !timestamp.Before(t.CortinaTime) +} + +func (t *Times) IsDurangoActivated(timestamp time.Time) bool { + return !timestamp.Before(t.DurangoTime) +} + +func (t *Times) IsEActivated(timestamp time.Time) bool { + return !timestamp.Before(t.EUpgradeTime) +} diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 9effc6fbeeb2..5c7d3eb415ff 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -43,7 +43,9 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" @@ -651,21 +653,25 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { UptimeLockedCalculator: uptime.NewLockedCalculator(), SybilProtectionEnabled: true, Validators: validators.NewManager(), - TxFee: defaultTxFee, - CreateSubnetTxFee: 100 * defaultTxFee, - TransformSubnetTxFee: 100 * defaultTxFee, - CreateBlockchainTxFee: 100 * defaultTxFee, - MinValidatorStake: defaultMinValidatorStake, - MaxValidatorStake: defaultMaxValidatorStake, - MinDelegatorStake: defaultMinDelegatorStake, - MinStakeDuration: defaultMinStakingDuration, - MaxStakeDuration: defaultMaxStakingDuration, - RewardConfig: defaultRewardConfig, - ApricotPhase3Time: forkTime, - ApricotPhase5Time: forkTime, - BanffTime: forkTime, - CortinaTime: forkTime, - EUpgradeTime: mockable.MaxTime, + StaticConfig: fee.StaticConfig{ + TxFee: defaultTxFee, + CreateSubnetTxFee: 100 * defaultTxFee, + TransformSubnetTxFee: 100 * defaultTxFee, + CreateBlockchainTxFee: 100 * defaultTxFee, + }, + MinValidatorStake: defaultMinValidatorStake, + MaxValidatorStake: defaultMaxValidatorStake, + MinDelegatorStake: defaultMinDelegatorStake, + MinStakeDuration: defaultMinStakingDuration, + MaxStakeDuration: defaultMaxStakingDuration, + RewardConfig: defaultRewardConfig, + Times: upgrade.Times{ + ApricotPhase3Time: forkTime, + ApricotPhase5Time: forkTime, + BanffTime: forkTime, + CortinaTime: forkTime, + EUpgradeTime: mockable.MaxTime, + }, }} vm.clock.Set(forkTime.Add(time.Second)) diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 0218e115521d..bbab930cbe96 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -45,6 +45,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" @@ -442,10 +443,12 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: latestForkTime, - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + BanffTime: latestForkTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, }} ctx := snowtest.Context(t, snowtest.PChainID) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 479788b47097..c6c39f5c3f46 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -57,7 +57,9 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" p2ppb "github.com/ava-labs/avalanchego/proto/pb/p2p" @@ -244,22 +246,26 @@ func defaultVM(t *testing.T, f fork) (*VM, *txstest.Builder, database.Database, UptimeLockedCalculator: uptime.NewLockedCalculator(), SybilProtectionEnabled: true, Validators: validators.NewManager(), - TxFee: defaultTxFee, - CreateSubnetTxFee: 100 * defaultTxFee, - TransformSubnetTxFee: 100 * defaultTxFee, - CreateBlockchainTxFee: 100 * defaultTxFee, - MinValidatorStake: defaultMinValidatorStake, - MaxValidatorStake: defaultMaxValidatorStake, - MinDelegatorStake: defaultMinDelegatorStake, - MinStakeDuration: defaultMinStakingDuration, - MaxStakeDuration: defaultMaxStakingDuration, - RewardConfig: defaultRewardConfig, - ApricotPhase3Time: apricotPhase3Time, - ApricotPhase5Time: apricotPhase5Time, - BanffTime: banffTime, - CortinaTime: cortinaTime, - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, + StaticConfig: fee.StaticConfig{ + TxFee: defaultTxFee, + CreateSubnetTxFee: 100 * defaultTxFee, + TransformSubnetTxFee: 100 * defaultTxFee, + CreateBlockchainTxFee: 100 * defaultTxFee, + }, + MinValidatorStake: defaultMinValidatorStake, + MaxValidatorStake: defaultMaxValidatorStake, + MinDelegatorStake: defaultMinDelegatorStake, + MinStakeDuration: defaultMinStakingDuration, + MaxStakeDuration: defaultMaxStakingDuration, + RewardConfig: defaultRewardConfig, + Times: upgrade.Times{ + ApricotPhase3Time: apricotPhase3Time, + ApricotPhase5Time: apricotPhase5Time, + BanffTime: banffTime, + CortinaTime: cortinaTime, + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + }, }} db := memdb.New() @@ -1178,10 +1184,12 @@ func TestRestartFullyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} firstCtx := snowtest.Context(t, snowtest.PChainID) @@ -1266,10 +1274,12 @@ func TestRestartFullyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} secondCtx := snowtest.Context(t, snowtest.PChainID) @@ -1315,10 +1325,12 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} initialClkTime := latestForkTime.Add(time.Second) @@ -1663,10 +1675,12 @@ func TestUnverifiedParent(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} initialClkTime := latestForkTime.Add(time.Second) @@ -1824,10 +1838,12 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { RewardConfig: defaultRewardConfig, Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} firstCtx := snowtest.Context(t, snowtest.PChainID) @@ -1873,10 +1889,12 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { UptimePercentage: secondUptimePercentage / 100., Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} secondCtx := snowtest.Context(t, snowtest.PChainID) @@ -1973,10 +1991,12 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { RewardConfig: defaultRewardConfig, Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} ctx := snowtest.Context(t, snowtest.PChainID) From 095a8f69a12b326f8793d389f635ea81199db640 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 24 Apr 2024 09:10:43 +0200 Subject: [PATCH 025/100] nits to address code reviews comments --- vms/platformvm/config/config.go | 11 ++-- vms/platformvm/service_test.go | 4 +- .../txs/executor/staker_tx_verification.go | 50 ++++++------------- .../txs/executor/standard_tx_executor.go | 38 +++----------- vms/platformvm/txs/txstest/builder.go | 6 +-- vms/platformvm/txs/txstest/context.go | 21 +++----- 6 files changed, 39 insertions(+), 91 deletions(-) diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index ed7ab7945ec7..0e8b24b903b1 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -20,6 +20,12 @@ import ( // Struct collecting all foundational parameters of PlatformVM type Config struct { + // All network upgrade timestamps + upgrade.Times + + // All static fees config active before E-upgrade + fee.StaticConfig + // The node's chain manager Chains chains.Manager @@ -43,8 +49,6 @@ type Config struct { // Set of subnets that this node is validating TrackedSubnets set.Set[ids.ID] - fee.StaticConfig - // The minimum amount of tokens one must bond to be a validator MinValidatorStake uint64 @@ -69,9 +73,6 @@ type Config struct { // Config for the minting function RewardConfig reward.Config - // All network upgrade timestamps - upgrade.Times - // UseCurrentHeight forces [GetMinimumHeight] to return the current height // of the P-Chain instead of the oldest block in the [recentlyAccepted] // window. diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 60d599bfeb12..13b5c36d49ed 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -365,9 +365,7 @@ func TestGetBalance(t *testing.T) { require := require.New(t) service, _, _ := defaultService(t) - staticFeesCfg := service.vm.Config.StaticConfig - upgrades := service.vm.Config.Times - createSubnetFee := staticFeesCfg.GetCreateSubnetTxFee(upgrades, service.vm.clock.Time()) + createSubnetFee := service.vm.Config.GetCreateSubnetTxFee(service.vm.Config.Times, service.vm.clock.Time()) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 6a235a0fa011..885005412b1d 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -164,11 +164,8 @@ func verifyAddValidatorTx( } // Verify the flowcheck - var ( - staticFeesCfg = backend.Config.StaticConfig - upgrades = backend.Config.Times - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -261,11 +258,8 @@ func verifyAddSubnetValidatorTx( } // Verify the flowcheck - var ( - staticFeesCfg = backend.Config.StaticConfig - upgrades = backend.Config.Times - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -345,11 +339,8 @@ func verifyRemoveSubnetValidatorTx( } // Verify the flowcheck - var ( - staticFeesCfg = backend.Config.StaticConfig - upgrades = backend.Config.Times - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, false, err } @@ -469,11 +460,8 @@ func verifyAddDelegatorTx( } // Verify the flowcheck - var ( - staticFeesCfg = backend.Config.StaticConfig - upgrades = backend.Config.Times - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -595,11 +583,8 @@ func verifyAddPermissionlessValidatorTx( copy(outs[len(tx.Outs):], tx.StakeOuts) // Verify the flowcheck - var ( - staticFeesCfg = backend.Config.StaticConfig - upgrades = backend.Config.Times - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -746,11 +731,8 @@ func verifyAddPermissionlessDelegatorTx( } // Verify the flowcheck - var ( - staticFeesCfg = backend.Config.StaticConfig - upgrades = backend.Config.Times - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -807,12 +789,8 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck - var ( - staticFeesCfg = backend.Config.StaticConfig - upgrades = backend.Config.Times - currentTimestamp = chainState.GetTimestamp() - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + currentTimestamp := chainState.GetTimestamp() + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 487420e1142a..22f288488b9a 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -69,11 +69,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - var ( - staticFeesCfg = e.Backend.Config.StaticConfig - upgrades = e.Backend.Config.Times - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -123,11 +119,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } // Verify the flowcheck - var ( - staticFeesCfg = e.Backend.Config.StaticConfig - upgrades = e.Backend.Config.Times - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -212,11 +204,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - var ( - staticFeesCfg = e.Backend.Config.StaticConfig - upgrades = e.Backend.Config.Times - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -277,11 +265,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - var ( - staticFeesCfg = e.Backend.Config.StaticConfig - upgrades = e.Backend.Config.Times - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -471,11 +455,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error return err } - var ( - staticFeesCfg = e.Backend.Config.StaticConfig - upgrades = e.Backend.Config.Times - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -600,12 +580,8 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { } // Verify the flowcheck - var ( - staticFeesCfg = e.Backend.Config.StaticConfig - upgrades = e.Backend.Config.Times - currentTimestamp = e.State.GetTimestamp() - ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) + currentTimestamp := e.State.GetTimestamp() + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } diff --git a/vms/platformvm/txs/txstest/builder.go b/vms/platformvm/txs/txstest/builder.go index bfc50d7454d6..e9d9c8d40061 100644 --- a/vms/platformvm/txs/txstest/builder.go +++ b/vms/platformvm/txs/txstest/builder.go @@ -341,11 +341,11 @@ func (b *Builder) builders(keys []*secp256k1.PrivateKey) (builder.Builder, walle var ( kc = secp256k1fx.NewKeychain(keys...) addrs = kc.Addresses() - context = newContext(b.ctx, b.cfg, b.state.GetTimestamp()) backend = newBackend(addrs, b.state, b.ctx.SharedMemory) + context = newContext(b.ctx, b.cfg, b.state.GetTimestamp()) + builder = builder.New(addrs, context, backend) + signer = walletsigner.New(kc, backend) ) - builder := builder.New(addrs, context, backend) - signer := walletsigner.New(kc, backend) return builder, signer } diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index 88e03c07fd1c..df6d6ed0e250 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -16,21 +16,16 @@ func newContext( cfg *config.Config, timestamp time.Time, ) *builder.Context { - var ( - staticFeesCfg = cfg.StaticConfig - upgrades = cfg.Times - ) - return &builder.Context{ NetworkID: ctx.NetworkID, AVAXAssetID: ctx.AVAXAssetID, - BaseTxFee: staticFeesCfg.TxFee, - CreateSubnetTxFee: staticFeesCfg.GetCreateSubnetTxFee(upgrades, timestamp), - TransformSubnetTxFee: staticFeesCfg.TransformSubnetTxFee, - CreateBlockchainTxFee: staticFeesCfg.GetCreateBlockchainTxFee(upgrades, timestamp), - AddPrimaryNetworkValidatorFee: staticFeesCfg.AddPrimaryNetworkValidatorFee, - AddPrimaryNetworkDelegatorFee: staticFeesCfg.AddPrimaryNetworkDelegatorFee, - AddSubnetValidatorFee: staticFeesCfg.AddSubnetValidatorFee, - AddSubnetDelegatorFee: staticFeesCfg.AddSubnetDelegatorFee, + BaseTxFee: cfg.TxFee, + CreateSubnetTxFee: cfg.GetCreateSubnetTxFee(cfg.Times, timestamp), + TransformSubnetTxFee: cfg.TransformSubnetTxFee, + CreateBlockchainTxFee: cfg.GetCreateBlockchainTxFee(cfg.Times, timestamp), + AddPrimaryNetworkValidatorFee: cfg.AddPrimaryNetworkValidatorFee, + AddPrimaryNetworkDelegatorFee: cfg.AddPrimaryNetworkDelegatorFee, + AddSubnetValidatorFee: cfg.AddSubnetValidatorFee, + AddSubnetDelegatorFee: cfg.AddSubnetDelegatorFee, } } From 796fc2f691c747604b1e32cac8573607552c3e21 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 24 Apr 2024 09:18:31 +0200 Subject: [PATCH 026/100] minor renaming --- node/node.go | 2 +- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 2 +- .../block/executor/verifier_test.go | 30 +++---- vms/platformvm/config/config.go | 2 +- vms/platformvm/service_test.go | 2 +- vms/platformvm/txs/executor/helpers_test.go | 2 +- .../txs/executor/staker_tx_verification.go | 14 ++-- .../txs/executor/standard_tx_executor.go | 12 +-- .../txs/executor/standard_tx_executor_test.go | 2 +- vms/platformvm/txs/fee/calculator.go | 4 +- vms/platformvm/txs/fee/calculator_test.go | 78 +++++++++---------- vms/platformvm/txs/fee/static_config.go | 4 +- vms/platformvm/txs/txstest/context.go | 4 +- vms/platformvm/upgrade/config.go | 50 ++++++++++++ vms/platformvm/upgrade/times.go | 50 ------------ vms/platformvm/validator_set_property_test.go | 2 +- vms/platformvm/vm_regression_test.go | 2 +- vms/platformvm/vm_test.go | 16 ++-- 19 files changed, 140 insertions(+), 140 deletions(-) create mode 100644 vms/platformvm/upgrade/config.go delete mode 100644 vms/platformvm/upgrade/times.go diff --git a/node/node.go b/node/node.go index fd5781c9490c..64daf9fc0685 100644 --- a/node/node.go +++ b/node/node.go @@ -1153,7 +1153,7 @@ func (n *Node) initVMs() error { MinStakeDuration: n.Config.MinStakeDuration, MaxStakeDuration: n.Config.MaxStakeDuration, RewardConfig: n.Config.RewardConfig, - Times: upgrade.Times{ + Config: upgrade.Config{ ApricotPhase3Time: version.GetApricotPhase3Time(n.Config.NetworkID), ApricotPhase5Time: version.GetApricotPhase5Time(n.Config.NetworkID), BanffTime: version.GetBanffTime(n.Config.NetworkID), diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 46f1731f6efe..3d3fd1958773 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -325,7 +325,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - Times: upgrade.Times{ + Config: upgrade.Config{ ApricotPhase3Time: mockable.MaxTime, ApricotPhase5Time: mockable.MaxTime, BanffTime: mockable.MaxTime, diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index bf17dcc84dd1..885276c04ff6 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -347,7 +347,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - Times: upgrade.Times{ + Config: upgrade.Config{ ApricotPhase3Time: mockable.MaxTime, ApricotPhase5Time: mockable.MaxTime, BanffTime: mockable.MaxTime, diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index c8ea158f9dfa..1e55aa9f52a9 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -59,7 +59,7 @@ func TestVerifierVisitProposalBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -145,7 +145,7 @@ func TestVerifierVisitAtomicBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ ApricotPhase5Time: time.Now().Add(time.Hour), BanffTime: mockable.MaxTime, // banff is not activated }, @@ -234,7 +234,7 @@ func TestVerifierVisitStandardBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ ApricotPhase5Time: time.Now().Add(time.Hour), BanffTime: mockable.MaxTime, // banff is not activated }, @@ -341,7 +341,7 @@ func TestVerifierVisitCommitBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -414,7 +414,7 @@ func TestVerifierVisitAbortBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -475,7 +475,7 @@ func TestVerifyUnverifiedParent(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -549,7 +549,7 @@ func TestBanffAbortBlockTimestampChecks(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: time.Time{}, // banff is activated }, }, @@ -647,7 +647,7 @@ func TestBanffCommitBlockTimestampChecks(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: time.Time{}, // banff is activated }, }, @@ -728,7 +728,7 @@ func TestVerifierVisitStandardBlockWithDuplicateInputs(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ ApricotPhase5Time: time.Now().Add(time.Hour), BanffTime: mockable.MaxTime, // banff is not activated }, @@ -819,7 +819,7 @@ func TestVerifierVisitApricotStandardBlockWithProposalBlockParent(t *testing.T) verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -878,7 +878,7 @@ func TestVerifierVisitBanffStandardBlockWithProposalBlockParent(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: time.Time{}, // banff is activated }, }, @@ -917,7 +917,7 @@ func TestVerifierVisitApricotCommitBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -962,7 +962,7 @@ func TestVerifierVisitBanffCommitBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: time.Time{}, // banff is activated }, }, @@ -1008,7 +1008,7 @@ func TestVerifierVisitApricotAbortBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -1053,7 +1053,7 @@ func TestVerifierVisitBanffAbortBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: time.Time{}, // banff is activated }, }, diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 0e8b24b903b1..745a2713d431 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -21,7 +21,7 @@ import ( // Struct collecting all foundational parameters of PlatformVM type Config struct { // All network upgrade timestamps - upgrade.Times + upgrade.Config // All static fees config active before E-upgrade fee.StaticConfig diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 13b5c36d49ed..db1132fc0451 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -365,7 +365,7 @@ func TestGetBalance(t *testing.T) { require := require.New(t) service, _, _ := defaultService(t) - createSubnetFee := service.vm.Config.GetCreateSubnetTxFee(service.vm.Config.Times, service.vm.clock.Time()) + createSubnetFee := service.vm.Config.GetCreateSubnetTxFee(service.vm.Config.Config, service.vm.clock.Time()) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index c14dbe9c459c..a98475d6dc90 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -296,7 +296,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - Times: upgrade.Times{ + Config: upgrade.Config{ ApricotPhase3Time: mockable.MaxTime, ApricotPhase5Time: mockable.MaxTime, BanffTime: mockable.MaxTime, diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 885005412b1d..562bbcbcfa82 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -165,7 +165,7 @@ func verifyAddValidatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -259,7 +259,7 @@ func verifyAddSubnetValidatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -340,7 +340,7 @@ func verifyRemoveSubnetValidatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, false, err } @@ -461,7 +461,7 @@ func verifyAddDelegatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -584,7 +584,7 @@ func verifyAddPermissionlessValidatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -732,7 +732,7 @@ func verifyAddPermissionlessDelegatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -790,7 +790,7 @@ func verifyTransferSubnetOwnershipTx( // Verify the flowcheck currentTimestamp := chainState.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 22f288488b9a..6635540344bb 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -69,7 +69,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -119,7 +119,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -204,7 +204,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -265,7 +265,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -455,7 +455,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error return err } - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -581,7 +581,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { // Verify the flowcheck currentTimestamp := e.State.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Times, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 8463645a624a..3c16f333c330 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -2081,7 +2081,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { func defaultTestConfig(t *testing.T, f fork, tm time.Time) *config.Config { c := &config.Config{ - Times: upgrade.Times{ + Config: upgrade.Config{ ApricotPhase3Time: mockable.MaxTime, ApricotPhase5Time: mockable.MaxTime, BanffTime: mockable.MaxTime, diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 2b69dbff8478..741d3918b325 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -15,7 +15,7 @@ var _ txs.Visitor = (*Calculator)(nil) type Calculator struct { // Pre E-fork inputs - upgrades upgrade.Times + upgrades upgrade.Config staticCfg StaticConfig chainTime time.Time @@ -23,7 +23,7 @@ type Calculator struct { Fee uint64 } -func NewStaticCalculator(cfg StaticConfig, ut upgrade.Times, chainTime time.Time) *Calculator { +func NewStaticCalculator(cfg StaticConfig, ut upgrade.Config, chainTime time.Time) *Calculator { return &Calculator{ upgrades: ut, staticCfg: cfg, diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index c4424e3a2d4f..370088d67c56 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -47,7 +47,7 @@ var ( type feeTests struct { description string - cfgAndChainTimeF func() (StaticConfig, upgrade.Times, time.Time) + cfgAndChainTimeF func() (StaticConfig, upgrade.Config, time.Time) unsignedAndSignedTx func(t *testing.T) (txs.UnsignedTx, *txs.Tx) expectedError error checksF func(*testing.T, *Calculator) @@ -59,12 +59,12 @@ func TestTxFees(t *testing.T) { tests := []feeTests{ { description: "AddValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -78,12 +78,12 @@ func TestTxFees(t *testing.T) { }, { description: "AddSubnetValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -97,12 +97,12 @@ func TestTxFees(t *testing.T) { }, { description: "AddDelegatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -116,12 +116,12 @@ func TestTxFees(t *testing.T) { }, { description: "CreateChainTx pre ApricotPhase3", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { apricotPhase3Time := time.Now().Truncate(time.Second) chainTime := apricotPhase3Time.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ ApricotPhase3Time: apricotPhase3Time, DurangoTime: mockable.MaxTime, EUpgradeTime: mockable.MaxTime, @@ -136,12 +136,12 @@ func TestTxFees(t *testing.T) { }, { description: "CreateChainTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -155,12 +155,12 @@ func TestTxFees(t *testing.T) { }, { description: "CreateSubnetTx pre ApricotPhase3", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { apricotPhase3Time := time.Now().Truncate(time.Second) chainTime := apricotPhase3Time.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ ApricotPhase3Time: apricotPhase3Time, DurangoTime: mockable.MaxTime, EUpgradeTime: mockable.MaxTime, @@ -175,12 +175,12 @@ func TestTxFees(t *testing.T) { }, { description: "CreateSubnetTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -194,12 +194,12 @@ func TestTxFees(t *testing.T) { }, { description: "RemoveSubnetValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -213,12 +213,12 @@ func TestTxFees(t *testing.T) { }, { description: "TransformSubnetTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -232,12 +232,12 @@ func TestTxFees(t *testing.T) { }, { description: "TransferSubnetOwnershipTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -251,12 +251,12 @@ func TestTxFees(t *testing.T) { }, { description: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -272,12 +272,12 @@ func TestTxFees(t *testing.T) { }, { description: "AddPermissionlessValidatorTx Subnet pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -295,12 +295,12 @@ func TestTxFees(t *testing.T) { }, { description: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -316,12 +316,12 @@ func TestTxFees(t *testing.T) { }, { description: "AddPermissionlessDelegatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -339,12 +339,12 @@ func TestTxFees(t *testing.T) { }, { description: "BaseTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -358,12 +358,12 @@ func TestTxFees(t *testing.T) { }, { description: "ImportTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -377,12 +377,12 @@ func TestTxFees(t *testing.T) { }, { description: "ExportTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -396,12 +396,12 @@ func TestTxFees(t *testing.T) { }, { description: "RewardValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } @@ -419,12 +419,12 @@ func TestTxFees(t *testing.T) { }, { description: "AdvanceTimeTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { eUpgradeTime := time.Now().Truncate(time.Second) chainTime := eUpgradeTime.Add(-1 * time.Second) cfg := feeTestsDefaultCfg - upgrade := upgrade.Times{ + upgrade := upgrade.Config{ DurangoTime: durangoTime, EUpgradeTime: eUpgradeTime, } diff --git a/vms/platformvm/txs/fee/static_config.go b/vms/platformvm/txs/fee/static_config.go index f2abb6d4d569..00a4326526d7 100644 --- a/vms/platformvm/txs/fee/static_config.go +++ b/vms/platformvm/txs/fee/static_config.go @@ -50,14 +50,14 @@ type StaticConfig struct { MinDelegationFee uint32 } -func (c *StaticConfig) GetCreateBlockchainTxFee(upgrades upgrade.Times, timestamp time.Time) uint64 { +func (c *StaticConfig) GetCreateBlockchainTxFee(upgrades upgrade.Config, timestamp time.Time) uint64 { if upgrades.IsApricotPhase3Activated(timestamp) { return c.CreateBlockchainTxFee } return c.CreateAssetTxFee } -func (c *StaticConfig) GetCreateSubnetTxFee(upgrades upgrade.Times, timestamp time.Time) uint64 { +func (c *StaticConfig) GetCreateSubnetTxFee(upgrades upgrade.Config, timestamp time.Time) uint64 { if upgrades.IsApricotPhase3Activated(timestamp) { return c.CreateSubnetTxFee } diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index df6d6ed0e250..3253448f5a69 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -20,9 +20,9 @@ func newContext( NetworkID: ctx.NetworkID, AVAXAssetID: ctx.AVAXAssetID, BaseTxFee: cfg.TxFee, - CreateSubnetTxFee: cfg.GetCreateSubnetTxFee(cfg.Times, timestamp), + CreateSubnetTxFee: cfg.GetCreateSubnetTxFee(cfg.Config, timestamp), TransformSubnetTxFee: cfg.TransformSubnetTxFee, - CreateBlockchainTxFee: cfg.GetCreateBlockchainTxFee(cfg.Times, timestamp), + CreateBlockchainTxFee: cfg.GetCreateBlockchainTxFee(cfg.Config, timestamp), AddPrimaryNetworkValidatorFee: cfg.AddPrimaryNetworkValidatorFee, AddPrimaryNetworkDelegatorFee: cfg.AddPrimaryNetworkDelegatorFee, AddSubnetValidatorFee: cfg.AddSubnetValidatorFee, diff --git a/vms/platformvm/upgrade/config.go b/vms/platformvm/upgrade/config.go new file mode 100644 index 000000000000..1d92736a2ee3 --- /dev/null +++ b/vms/platformvm/upgrade/config.go @@ -0,0 +1,50 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package upgrade + +import "time" + +type Config struct { + // Time of the AP3 network upgrade + ApricotPhase3Time time.Time + + // Time of the AP5 network upgrade + ApricotPhase5Time time.Time + + // Time of the Banff network upgrade + BanffTime time.Time + + // Time of the Cortina network upgrade + CortinaTime time.Time + + // Time of the Durango network upgrade + DurangoTime time.Time + + // Time of the E network upgrade + EUpgradeTime time.Time +} + +func (c *Config) IsApricotPhase3Activated(timestamp time.Time) bool { + return !timestamp.Before(c.ApricotPhase3Time) +} + +func (c *Config) IsApricotPhase5Activated(timestamp time.Time) bool { + return !timestamp.Before(c.ApricotPhase5Time) +} + +func (c *Config) IsBanffActivated(timestamp time.Time) bool { + return !timestamp.Before(c.BanffTime) +} + +func (c *Config) IsCortinaActivated(timestamp time.Time) bool { + return !timestamp.Before(c.CortinaTime) +} + +func (c *Config) IsDurangoActivated(timestamp time.Time) bool { + return !timestamp.Before(c.DurangoTime) +} + +func (c *Config) IsEActivated(timestamp time.Time) bool { + return !timestamp.Before(c.EUpgradeTime) +} diff --git a/vms/platformvm/upgrade/times.go b/vms/platformvm/upgrade/times.go deleted file mode 100644 index f4c6bacecf9c..000000000000 --- a/vms/platformvm/upgrade/times.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package upgrade - -import "time" - -type Times struct { - // Time of the AP3 network upgrade - ApricotPhase3Time time.Time - - // Time of the AP5 network upgrade - ApricotPhase5Time time.Time - - // Time of the Banff network upgrade - BanffTime time.Time - - // Time of the Cortina network upgrade - CortinaTime time.Time - - // Time of the Durango network upgrade - DurangoTime time.Time - - // Time of the E network upgrade - EUpgradeTime time.Time -} - -func (t *Times) IsApricotPhase3Activated(timestamp time.Time) bool { - return !timestamp.Before(t.ApricotPhase3Time) -} - -func (t *Times) IsApricotPhase5Activated(timestamp time.Time) bool { - return !timestamp.Before(t.ApricotPhase5Time) -} - -func (t *Times) IsBanffActivated(timestamp time.Time) bool { - return !timestamp.Before(t.BanffTime) -} - -func (t *Times) IsCortinaActivated(timestamp time.Time) bool { - return !timestamp.Before(t.CortinaTime) -} - -func (t *Times) IsDurangoActivated(timestamp time.Time) bool { - return !timestamp.Before(t.DurangoTime) -} - -func (t *Times) IsEActivated(timestamp time.Time) bool { - return !timestamp.Before(t.EUpgradeTime) -} diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 5c7d3eb415ff..7c08a15bc043 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -665,7 +665,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Times: upgrade.Times{ + Config: upgrade.Config{ ApricotPhase3Time: forkTime, ApricotPhase5Time: forkTime, BanffTime: forkTime, diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index bbab930cbe96..53a115eed6d4 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -443,7 +443,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: mockable.MaxTime, DurangoTime: mockable.MaxTime, diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index c6c39f5c3f46..5cf17c039c24 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -258,7 +258,7 @@ func defaultVM(t *testing.T, f fork) (*VM, *txstest.Builder, database.Database, MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Times: upgrade.Times{ + Config: upgrade.Config{ ApricotPhase3Time: apricotPhase3Time, ApricotPhase5Time: apricotPhase5Time, BanffTime: banffTime, @@ -1184,7 +1184,7 @@ func TestRestartFullyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1274,7 +1274,7 @@ func TestRestartFullyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1325,7 +1325,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1675,7 +1675,7 @@ func TestUnverifiedParent(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1838,7 +1838,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { RewardConfig: defaultRewardConfig, Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1889,7 +1889,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { UptimePercentage: secondUptimePercentage / 100., Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1991,7 +1991,7 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { RewardConfig: defaultRewardConfig, Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - Times: upgrade.Times{ + Config: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, From 6bc3091849c9317b60cfd0924f84cce2c3f9afac Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 24 Apr 2024 10:33:34 +0200 Subject: [PATCH 027/100] simplified unit tests --- vms/platformvm/txs/fee/calculator.go | 6 +- vms/platformvm/txs/fee/calculator_test.go | 490 ++++++---------------- 2 files changed, 130 insertions(+), 366 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 741d3918b325..50f37ff448f0 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -56,11 +56,13 @@ func (fc *Calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { return nil } -func (*Calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { +func (fc *Calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + fc.Fee = 0 return nil // no fees } -func (*Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { +func (fc *Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { + fc.Fee = 0 return nil // no fees } diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 370088d67c56..0186e4efae5a 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -15,7 +15,6 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/reward" @@ -27,7 +26,22 @@ import ( ) var ( - feeTestsDefaultCfg = StaticConfig{ + preFundedKeys = secp256k1.TestKeys() + feeTestDefaultStakeWeight = uint64(2024) +) + +func TestTxFees(t *testing.T) { + r := require.New(t) + + type feeTests struct { + name string + chainTime time.Time + unsignedTx func(t *testing.T) txs.UnsignedTx + expectedError error + checksF func(*testing.T, *Calculator) + } + + feeTestsDefaultCfg := StaticConfig{ TxFee: 1 * units.Avax, CreateAssetTxFee: 2 * units.Avax, CreateSubnetTxFee: 3 * units.Avax, @@ -39,230 +53,111 @@ var ( AddSubnetDelegatorFee: 9 * units.Avax, } - preFundedKeys = secp256k1.TestKeys() - feeTestSigners = [][]*secp256k1.PrivateKey{preFundedKeys} - feeTestDefaultStakeWeight = uint64(2024) - durangoTime = time.Time{} // assume durango is active in these tests -) - -type feeTests struct { - description string - cfgAndChainTimeF func() (StaticConfig, upgrade.Config, time.Time) - unsignedAndSignedTx func(t *testing.T) (txs.UnsignedTx, *txs.Tx) - expectedError error - checksF func(*testing.T, *Calculator) -} - -func TestTxFees(t *testing.T) { - r := require.New(t) + latestForkTime := time.Unix(1713945427, 0) + upgrades := upgrade.Config{ + EUpgradeTime: latestForkTime, + DurangoTime: latestForkTime.Add(-1 * time.Hour), + CortinaTime: latestForkTime.Add(-2 * time.Hour), + BanffTime: latestForkTime.Add(-3 * time.Hour), + ApricotPhase5Time: latestForkTime.Add(-4 * time.Hour), + ApricotPhase3Time: latestForkTime.Add(-5 * time.Hour), + } tests := []feeTests{ { - description: "AddValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: addValidatorTx, - expectedError: nil, + name: "AddValidatorTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: addValidatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.AddPrimaryNetworkValidatorFee, fc.Fee) }, }, { - description: "AddSubnetValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: addSubnetValidatorTx, - expectedError: nil, + name: "AddSubnetValidatorTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: addSubnetValidatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.AddSubnetValidatorFee, fc.Fee) }, }, { - description: "AddDelegatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: addDelegatorTx, - expectedError: nil, + name: "AddDelegatorTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: addDelegatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.AddPrimaryNetworkDelegatorFee, fc.Fee) }, }, { - description: "CreateChainTx pre ApricotPhase3", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - apricotPhase3Time := time.Now().Truncate(time.Second) - chainTime := apricotPhase3Time.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - ApricotPhase3Time: apricotPhase3Time, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: createChainTx, - expectedError: nil, + name: "CreateChainTx pre ApricotPhase3", + chainTime: upgrades.ApricotPhase3Time.Add(-1 * time.Second), + unsignedTx: createChainTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.CreateAssetTxFee, fc.Fee) }, }, { - description: "CreateChainTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: createChainTx, - expectedError: nil, + name: "CreateChainTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: createChainTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.CreateBlockchainTxFee, fc.Fee) }, }, { - description: "CreateSubnetTx pre ApricotPhase3", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - apricotPhase3Time := time.Now().Truncate(time.Second) - chainTime := apricotPhase3Time.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - ApricotPhase3Time: apricotPhase3Time, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: createSubnetTx, - expectedError: nil, + name: "CreateSubnetTx pre ApricotPhase3", + chainTime: upgrades.ApricotPhase3Time.Add(-1 * time.Second), + unsignedTx: createSubnetTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.CreateAssetTxFee, fc.Fee) }, }, { - description: "CreateSubnetTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: createSubnetTx, - expectedError: nil, + name: "CreateSubnetTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: createSubnetTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.CreateSubnetTxFee, fc.Fee) }, }, { - description: "RemoveSubnetValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: removeSubnetValidatorTx, - expectedError: nil, + name: "RemoveSubnetValidatorTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: removeSubnetValidatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.TxFee, fc.Fee) }, }, { - description: "TransformSubnetTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: transformSubnetTx, - expectedError: nil, + name: "TransformSubnetTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: transformSubnetTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.TransformSubnetTxFee, fc.Fee) }, }, { - description: "TransferSubnetOwnershipTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: transferSubnetOwnershipTx, - expectedError: nil, + name: "TransferSubnetOwnershipTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: transferSubnetOwnershipTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.TxFee, fc.Fee) }, }, { - description: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + name: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func(t *testing.T) txs.UnsignedTx { return addPermissionlessValidatorTx(t, constants.PrimaryNetworkID) }, expectedError: nil, @@ -271,19 +166,9 @@ func TestTxFees(t *testing.T) { }, }, { - description: "AddPermissionlessValidatorTx Subnet pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + name: "AddPermissionlessValidatorTx Subnet pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func(t *testing.T) txs.UnsignedTx { subnetID := ids.GenerateTestID() require.NotEqual(t, constants.PrimaryNetworkID, subnetID) return addPermissionlessValidatorTx(t, subnetID) @@ -294,19 +179,9 @@ func TestTxFees(t *testing.T) { }, }, { - description: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + name: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func(t *testing.T) txs.UnsignedTx { return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) }, expectedError: nil, @@ -315,19 +190,9 @@ func TestTxFees(t *testing.T) { }, }, { - description: "AddPermissionlessDelegatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { + name: "AddPermissionlessDelegatorTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func(t *testing.T) txs.UnsignedTx { subnetID := ids.GenerateTestID() require.NotEqual(t, constants.PrimaryNetworkID, subnetID) return addPermissionlessDelegatorTx(t, subnetID) @@ -338,79 +203,39 @@ func TestTxFees(t *testing.T) { }, }, { - description: "BaseTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: baseTx, - expectedError: nil, + name: "BaseTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: baseTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.TxFee, fc.Fee) }, }, { - description: "ImportTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: importTx, - expectedError: nil, + name: "ImportTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: importTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.TxFee, fc.Fee) }, }, { - description: "ExportTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: exportTx, - expectedError: nil, + name: "ExportTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: exportTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.staticCfg.TxFee, fc.Fee) }, }, { - description: "RewardValidatorTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: func(_ *testing.T) (txs.UnsignedTx, *txs.Tx) { + name: "RewardValidatorTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func(_ *testing.T) txs.UnsignedTx { return &txs.RewardValidatorTx{ TxID: ids.GenerateTestID(), - }, nil + } }, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { @@ -418,22 +243,12 @@ func TestTxFees(t *testing.T) { }, }, { - description: "AdvanceTimeTx pre EUpgrade", - cfgAndChainTimeF: func() (StaticConfig, upgrade.Config, time.Time) { - eUpgradeTime := time.Now().Truncate(time.Second) - chainTime := eUpgradeTime.Add(-1 * time.Second) - - cfg := feeTestsDefaultCfg - upgrade := upgrade.Config{ - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, - } - return cfg, upgrade, chainTime - }, - unsignedAndSignedTx: func(_ *testing.T) (txs.UnsignedTx, *txs.Tx) { + name: "AdvanceTimeTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func(_ *testing.T) txs.UnsignedTx { return &txs.AdvanceTimeTx{ Time: uint64(time.Now().Unix()), - }, nil + } }, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { @@ -443,11 +258,9 @@ func TestTxFees(t *testing.T) { } for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, upgrades, chainTime := tt.cfgAndChainTimeF() - - uTx, _ := tt.unsignedAndSignedTx(t) - fc := NewStaticCalculator(cfg, upgrades, chainTime) + t.Run(tt.name, func(t *testing.T) { + uTx := tt.unsignedTx(t) + fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) err := uTx.Visit(fc) r.ErrorIs(err, tt.expectedError) @@ -456,9 +269,7 @@ func TestTxFees(t *testing.T) { } } -func addValidatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func addValidatorTx(t *testing.T) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) baseTx, stakes, _ := txsCreationHelpers(defaultCtx) @@ -478,15 +289,10 @@ func addValidatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { }, DelegationShares: reward.PercentDenominator, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - - return uTx, sTx + return uTx } -func addSubnetValidatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func addSubnetValidatorTx(t *testing.T) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) subnetID := ids.GenerateTestID() @@ -504,14 +310,10 @@ func addSubnetValidatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { }, SubnetAuth: subnetAuth, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } -func addDelegatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func addDelegatorTx(t *testing.T) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) baseTx, stakes, _ := txsCreationHelpers(defaultCtx) @@ -530,14 +332,10 @@ func addDelegatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, }, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } -func createChainTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func createChainTx(t *testing.T) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) baseTx, _, subnetAuth := txsCreationHelpers(defaultCtx) @@ -550,14 +348,10 @@ func createChainTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { GenesisData: []byte{0xff}, SubnetAuth: subnetAuth, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } -func createSubnetTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func createSubnetTx(t *testing.T) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) baseTx, _, _ := txsCreationHelpers(defaultCtx) @@ -568,14 +362,10 @@ func createSubnetTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, }, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } -func removeSubnetValidatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func removeSubnetValidatorTx(t *testing.T) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) baseTx, _, auth := txsCreationHelpers(defaultCtx) @@ -585,14 +375,10 @@ func removeSubnetValidatorTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { Subnet: ids.GenerateTestID(), SubnetAuth: auth, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } -func transformSubnetTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func transformSubnetTx(t *testing.T) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) baseTx, _, auth := txsCreationHelpers(defaultCtx) @@ -614,14 +400,10 @@ func transformSubnetTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { UptimeRequirement: 0, SubnetAuth: auth, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } -func transferSubnetOwnershipTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func transferSubnetOwnershipTx(t *testing.T) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) baseTx, _, _ := txsCreationHelpers(defaultCtx) @@ -639,12 +421,10 @@ func transferSubnetOwnershipTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { }, }, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } -func addPermissionlessValidatorTx(t *testing.T, subnetID ids.ID) (txs.UnsignedTx, *txs.Tx) { +func addPermissionlessValidatorTx(t *testing.T, subnetID ids.ID) txs.UnsignedTx { r := require.New(t) defaultCtx := snowtest.Context(t, snowtest.PChainID) @@ -673,14 +453,10 @@ func addPermissionlessValidatorTx(t *testing.T, subnetID ids.ID) (txs.UnsignedTx }, DelegationShares: reward.PercentDenominator, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } -func addPermissionlessDelegatorTx(t *testing.T, subnetID ids.ID) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func addPermissionlessDelegatorTx(t *testing.T, subnetID ids.ID) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) baseTx, stakes, _ := txsCreationHelpers(defaultCtx) @@ -702,26 +478,18 @@ func addPermissionlessDelegatorTx(t *testing.T, subnetID ids.ID) (txs.UnsignedTx }, }, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } -func baseTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func baseTx(t *testing.T) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) baseTx, _, _ := txsCreationHelpers(defaultCtx) uTx := &baseTx - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } -func importTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func importTx(t *testing.T) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) baseTx, _, _ := txsCreationHelpers(defaultCtx) @@ -740,14 +508,10 @@ func importTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { }, }}, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } -func exportTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { - r := require.New(t) - +func exportTx(t *testing.T) txs.UnsignedTx { defaultCtx := snowtest.Context(t, snowtest.PChainID) baseTx, outputs, _ := txsCreationHelpers(defaultCtx) @@ -756,9 +520,7 @@ func exportTx(t *testing.T) (txs.UnsignedTx, *txs.Tx) { DestinationChain: ids.GenerateTestID(), ExportedOutputs: outputs, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return uTx, sTx + return uTx } func txsCreationHelpers(defaultCtx *snow.Context) ( From 73cc339ea1aa9b9af5d236e6a890cede9fbd6e63 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:30:28 -0400 Subject: [PATCH 028/100] Fee Calculator Refactor (#2964) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Alberto Benegiamo --- .../txs/executor/staker_tx_verification.go | 62 ++---- .../txs/executor/standard_tx_executor.go | 49 ++--- vms/platformvm/txs/fee/calculator.go | 104 ++++++---- vms/platformvm/txs/fee/calculator_test.go | 191 ++++++------------ 4 files changed, 165 insertions(+), 241 deletions(-) diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 562bbcbcfa82..d013e6af8e47 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -164,11 +164,8 @@ func verifyAddValidatorTx( } // Verify the flowcheck - - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return nil, err - } + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -177,7 +174,7 @@ func verifyAddValidatorTx( outs, sTx.Creds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: feeCalculator.Fee, + backend.Ctx.AVAXAssetID: fee, }, ); err != nil { return nil, fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -258,11 +255,8 @@ func verifyAddSubnetValidatorTx( } // Verify the flowcheck - - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -271,7 +265,7 @@ func verifyAddSubnetValidatorTx( tx.Outs, baseTxCreds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: feeCalculator.Fee, + backend.Ctx.AVAXAssetID: fee, }, ); err != nil { return fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -339,11 +333,8 @@ func verifyRemoveSubnetValidatorTx( } // Verify the flowcheck - - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return nil, false, err - } + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -352,7 +343,7 @@ func verifyRemoveSubnetValidatorTx( tx.Outs, baseTxCreds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: feeCalculator.Fee, + backend.Ctx.AVAXAssetID: fee, }, ); err != nil { return nil, false, fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -460,11 +451,8 @@ func verifyAddDelegatorTx( } // Verify the flowcheck - - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return nil, err - } + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -473,7 +461,7 @@ func verifyAddDelegatorTx( outs, sTx.Creds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: feeCalculator.Fee, + backend.Ctx.AVAXAssetID: fee, }, ); err != nil { return nil, fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -583,11 +571,8 @@ func verifyAddPermissionlessValidatorTx( copy(outs[len(tx.Outs):], tx.StakeOuts) // Verify the flowcheck - - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -596,7 +581,7 @@ func verifyAddPermissionlessValidatorTx( outs, sTx.Creds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: feeCalculator.Fee, + backend.Ctx.AVAXAssetID: fee, }, ); err != nil { return fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -731,11 +716,8 @@ func verifyAddPermissionlessDelegatorTx( } // Verify the flowcheck - - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) // Verify the flowcheck if err := backend.FlowChecker.VerifySpend( @@ -745,7 +727,7 @@ func verifyAddPermissionlessDelegatorTx( outs, sTx.Creds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: feeCalculator.Fee, + backend.Ctx.AVAXAssetID: fee, }, ); err != nil { return fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) @@ -790,10 +772,8 @@ func verifyTransferSubnetOwnershipTx( // Verify the flowcheck currentTimestamp := chainState.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -802,7 +782,7 @@ func verifyTransferSubnetOwnershipTx( tx.Outs, baseTxCreds, map[ids.ID]uint64{ - backend.Ctx.AVAXAssetID: feeCalculator.Fee, + backend.Ctx.AVAXAssetID: fee, }, ); err != nil { return fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 6635540344bb..935b889d856a 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -69,10 +69,8 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, @@ -81,7 +79,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { tx.Outs, baseTxCreds, map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: feeCalculator.Fee, + e.Ctx.AVAXAssetID: fee, }, ); err != nil { return err @@ -119,10 +117,8 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, @@ -131,7 +127,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { tx.Outs, e.Tx.Creds, map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: feeCalculator.Fee, + e.Ctx.AVAXAssetID: fee, }, ); err != nil { return err @@ -204,10 +200,8 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpendUTXOs( tx, @@ -216,7 +210,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { tx.Outs, e.Tx.Creds, map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: feeCalculator.Fee, + e.Ctx.AVAXAssetID: fee, }, ); err != nil { return err @@ -265,10 +259,8 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, @@ -277,7 +269,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { outs, e.Tx.Creds, map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: feeCalculator.Fee, + e.Ctx.AVAXAssetID: fee, }, ); err != nil { return fmt.Errorf("failed verifySpend: %w", err) @@ -455,10 +447,9 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error return err } - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + // Verify the flowcheck + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) totalRewardAmount := tx.MaximumSupply - tx.InitialSupply if err := e.Backend.FlowChecker.VerifySpend( @@ -471,7 +462,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error // entry in this map literal from being overwritten by the // second entry. map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: feeCalculator.Fee, + e.Ctx.AVAXAssetID: fee, tx.AssetID: totalRewardAmount, }, ); err != nil { @@ -581,10 +572,8 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { // Verify the flowcheck currentTimestamp := e.State.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config) + fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, @@ -593,7 +582,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { tx.Outs, e.Tx.Creds, map[ids.ID]uint64{ - e.Ctx.AVAXAssetID: feeCalculator.Fee, + e.Ctx.AVAXAssetID: fee, }, ); err != nil { return err diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 50f37ff448f0..73cd1141ece7 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -11,105 +11,123 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" ) -var _ txs.Visitor = (*Calculator)(nil) +var _ txs.Visitor = (*calculator)(nil) + +func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config) Calculator { + return Calculator{ + config: config, + upgradeTimes: upgradeTimes, + } +} type Calculator struct { + config StaticConfig + upgradeTimes upgrade.Config +} + +func (c Calculator) CalculateFee(tx txs.UnsignedTx, time time.Time) uint64 { + tmp := &calculator{ + upgrades: c.upgradeTimes, + staticCfg: c.config, + time: time, + } + + // this is guaranteed to never return an error + _ = tx.Visit(tmp) + return tmp.fee +} + +// calculator is intentionally unexported and used through Calculator to provide +// a more convenient API +type calculator struct { // Pre E-fork inputs upgrades upgrade.Config staticCfg StaticConfig - chainTime time.Time + time time.Time // outputs of visitor execution - Fee uint64 -} - -func NewStaticCalculator(cfg StaticConfig, ut upgrade.Config, chainTime time.Time) *Calculator { - return &Calculator{ - upgrades: ut, - staticCfg: cfg, - chainTime: chainTime, - } + fee uint64 } -func (fc *Calculator) AddValidatorTx(*txs.AddValidatorTx) error { - fc.Fee = fc.staticCfg.AddPrimaryNetworkValidatorFee +func (c *calculator) AddValidatorTx(*txs.AddValidatorTx) error { + c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee return nil } -func (fc *Calculator) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { - fc.Fee = fc.staticCfg.AddSubnetValidatorFee +func (c *calculator) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { + c.fee = c.staticCfg.AddSubnetValidatorFee return nil } -func (fc *Calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { - fc.Fee = fc.staticCfg.AddPrimaryNetworkDelegatorFee +func (c *calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { + c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee return nil } -func (fc *Calculator) CreateChainTx(*txs.CreateChainTx) error { - fc.Fee = fc.staticCfg.GetCreateBlockchainTxFee(fc.upgrades, fc.chainTime) +func (c *calculator) CreateChainTx(*txs.CreateChainTx) error { + c.fee = c.staticCfg.GetCreateBlockchainTxFee(c.upgrades, c.time) return nil } -func (fc *Calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { - fc.Fee = fc.staticCfg.GetCreateSubnetTxFee(fc.upgrades, fc.chainTime) +func (c *calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { + c.fee = c.staticCfg.GetCreateSubnetTxFee(c.upgrades, c.time) return nil } -func (fc *Calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - fc.Fee = 0 +func (c *calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + c.fee = 0 return nil // no fees } -func (fc *Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { - fc.Fee = 0 +func (c *calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { + c.fee = 0 return nil // no fees } -func (fc *Calculator) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { - fc.Fee = fc.staticCfg.TxFee +func (c *calculator) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { + c.fee = c.staticCfg.TxFee return nil } -func (fc *Calculator) TransformSubnetTx(*txs.TransformSubnetTx) error { - fc.Fee = fc.staticCfg.TransformSubnetTxFee +func (c *calculator) TransformSubnetTx(*txs.TransformSubnetTx) error { + c.fee = c.staticCfg.TransformSubnetTxFee return nil } -func (fc *Calculator) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { - fc.Fee = fc.staticCfg.TxFee +func (c *calculator) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { + c.fee = c.staticCfg.TxFee return nil } -func (fc *Calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { +func (c *calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { if tx.Subnet != constants.PrimaryNetworkID { - fc.Fee = fc.staticCfg.AddSubnetValidatorFee + c.fee = c.staticCfg.AddSubnetValidatorFee } else { - fc.Fee = fc.staticCfg.AddPrimaryNetworkValidatorFee + c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee } return nil } -func (fc *Calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { +func (c *calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { if tx.Subnet != constants.PrimaryNetworkID { - fc.Fee = fc.staticCfg.AddSubnetDelegatorFee + c.fee = c.staticCfg.AddSubnetDelegatorFee } else { - fc.Fee = fc.staticCfg.AddPrimaryNetworkDelegatorFee + c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee } return nil } -func (fc *Calculator) BaseTx(*txs.BaseTx) error { - fc.Fee = fc.staticCfg.TxFee +func (c *calculator) BaseTx(*txs.BaseTx) error { + c.fee = c.staticCfg.TxFee return nil } -func (fc *Calculator) ImportTx(*txs.ImportTx) error { - fc.Fee = fc.staticCfg.TxFee +func (c *calculator) ImportTx(*txs.ImportTx) error { + c.fee = c.staticCfg.TxFee return nil } -func (fc *Calculator) ExportTx(*txs.ExportTx) error { - fc.Fee = fc.staticCfg.TxFee +func (c *calculator) ExportTx(*txs.ExportTx) error { + c.fee = c.staticCfg.TxFee return nil } diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 0186e4efae5a..f684b0dd8c23 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -31,14 +31,11 @@ var ( ) func TestTxFees(t *testing.T) { - r := require.New(t) - type feeTests struct { - name string - chainTime time.Time - unsignedTx func(t *testing.T) txs.UnsignedTx - expectedError error - checksF func(*testing.T, *Calculator) + name string + chainTime time.Time + unsignedTx func(t *testing.T) txs.UnsignedTx + expected uint64 } feeTestsDefaultCfg := StaticConfig{ @@ -65,94 +62,64 @@ func TestTxFees(t *testing.T) { tests := []feeTests{ { - name: "AddValidatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: addValidatorTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.AddPrimaryNetworkValidatorFee, fc.Fee) - }, + name: "AddValidatorTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: addValidatorTx, + expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, }, { - name: "AddSubnetValidatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: addSubnetValidatorTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.AddSubnetValidatorFee, fc.Fee) - }, + name: "AddSubnetValidatorTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: addSubnetValidatorTx, + expected: feeTestsDefaultCfg.AddSubnetValidatorFee, }, { - name: "AddDelegatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: addDelegatorTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.AddPrimaryNetworkDelegatorFee, fc.Fee) - }, + name: "AddDelegatorTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: addDelegatorTx, + expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, }, { - name: "CreateChainTx pre ApricotPhase3", - chainTime: upgrades.ApricotPhase3Time.Add(-1 * time.Second), - unsignedTx: createChainTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.CreateAssetTxFee, fc.Fee) - }, + name: "CreateChainTx pre ApricotPhase3", + chainTime: upgrades.ApricotPhase3Time.Add(-1 * time.Second), + unsignedTx: createChainTx, + expected: feeTestsDefaultCfg.CreateAssetTxFee, }, { - name: "CreateChainTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: createChainTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.CreateBlockchainTxFee, fc.Fee) - }, + name: "CreateChainTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: createChainTx, + expected: feeTestsDefaultCfg.CreateBlockchainTxFee, }, { - name: "CreateSubnetTx pre ApricotPhase3", - chainTime: upgrades.ApricotPhase3Time.Add(-1 * time.Second), - unsignedTx: createSubnetTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.CreateAssetTxFee, fc.Fee) - }, + name: "CreateSubnetTx pre ApricotPhase3", + chainTime: upgrades.ApricotPhase3Time.Add(-1 * time.Second), + unsignedTx: createSubnetTx, + expected: feeTestsDefaultCfg.CreateAssetTxFee, }, { - name: "CreateSubnetTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: createSubnetTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.CreateSubnetTxFee, fc.Fee) - }, + name: "CreateSubnetTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: createSubnetTx, + expected: feeTestsDefaultCfg.CreateSubnetTxFee, }, { - name: "RemoveSubnetValidatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: removeSubnetValidatorTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.Fee) - }, + name: "RemoveSubnetValidatorTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: removeSubnetValidatorTx, + expected: feeTestsDefaultCfg.TxFee, }, { - name: "TransformSubnetTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: transformSubnetTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TransformSubnetTxFee, fc.Fee) - }, + name: "TransformSubnetTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: transformSubnetTx, + expected: feeTestsDefaultCfg.TransformSubnetTxFee, }, { - name: "TransferSubnetOwnershipTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: transferSubnetOwnershipTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.Fee) - }, + name: "TransferSubnetOwnershipTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: transferSubnetOwnershipTx, + expected: feeTestsDefaultCfg.TxFee, }, { name: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", @@ -160,10 +127,7 @@ func TestTxFees(t *testing.T) { unsignedTx: func(t *testing.T) txs.UnsignedTx { return addPermissionlessValidatorTx(t, constants.PrimaryNetworkID) }, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.AddPrimaryNetworkValidatorFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, }, { name: "AddPermissionlessValidatorTx Subnet pre EUpgrade", @@ -173,10 +137,7 @@ func TestTxFees(t *testing.T) { require.NotEqual(t, constants.PrimaryNetworkID, subnetID) return addPermissionlessValidatorTx(t, subnetID) }, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.AddSubnetValidatorFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.AddSubnetValidatorFee, }, { name: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", @@ -184,10 +145,7 @@ func TestTxFees(t *testing.T) { unsignedTx: func(t *testing.T) txs.UnsignedTx { return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) }, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.AddPrimaryNetworkDelegatorFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, }, { name: "AddPermissionlessDelegatorTx pre EUpgrade", @@ -197,37 +155,25 @@ func TestTxFees(t *testing.T) { require.NotEqual(t, constants.PrimaryNetworkID, subnetID) return addPermissionlessDelegatorTx(t, subnetID) }, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.AddSubnetDelegatorFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.AddSubnetDelegatorFee, }, { - name: "BaseTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: baseTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.Fee) - }, + name: "BaseTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: baseTx, + expected: feeTestsDefaultCfg.TxFee, }, { - name: "ImportTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: importTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.Fee) - }, + name: "ImportTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: importTx, + expected: feeTestsDefaultCfg.TxFee, }, { - name: "ExportTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: exportTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.Fee) - }, + name: "ExportTx pre EUpgrade", + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: exportTx, + expected: feeTestsDefaultCfg.TxFee, }, { name: "RewardValidatorTx pre EUpgrade", @@ -237,10 +183,7 @@ func TestTxFees(t *testing.T) { TxID: ids.GenerateTestID(), } }, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, uint64(0), fc.Fee) - }, + expected: 0, }, { name: "AdvanceTimeTx pre EUpgrade", @@ -250,21 +193,15 @@ func TestTxFees(t *testing.T) { Time: uint64(time.Now().Unix()), } }, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, uint64(0), fc.Fee) - }, + expected: 0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { uTx := tt.unsignedTx(t) - fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) - - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) + fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades) + require.Equal(t, tt.expected, fc.CalculateFee(uTx, tt.chainTime)) }) } } From f008446aeaa01f7c067efb22961a0bec85038f83 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 25 Apr 2024 19:24:04 +0200 Subject: [PATCH 029/100] nit --- node/node.go | 4 +-- vms/platformvm/block/builder/builder_test.go | 2 +- vms/platformvm/block/builder/helpers_test.go | 16 +++++----- vms/platformvm/block/executor/helpers_test.go | 16 +++++----- .../block/executor/standard_block_test.go | 4 +-- vms/platformvm/block/executor/verifier.go | 6 ++-- .../block/executor/verifier_test.go | 30 +++++++++---------- vms/platformvm/config/config.go | 12 ++++---- vms/platformvm/service_test.go | 7 +++-- vms/platformvm/state/state.go | 2 +- .../txs/executor/advance_time_test.go | 6 ++-- .../txs/executor/create_chain_test.go | 4 +-- .../txs/executor/create_subnet_test.go | 4 +-- vms/platformvm/txs/executor/export_test.go | 2 +- vms/platformvm/txs/executor/helpers_test.go | 16 +++++----- vms/platformvm/txs/executor/import_test.go | 14 ++++----- .../txs/executor/proposal_tx_executor.go | 18 +++++------ .../txs/executor/proposal_tx_executor_test.go | 2 +- .../txs/executor/staker_tx_verification.go | 30 +++++++++---------- .../executor/staker_tx_verification_test.go | 4 +-- .../txs/executor/standard_tx_executor.go | 26 ++++++++-------- .../txs/executor/standard_tx_executor_test.go | 20 ++++++------- vms/platformvm/txs/txstest/context.go | 16 +++++----- vms/platformvm/validator_set_property_test.go | 4 +-- vms/platformvm/vm_regression_test.go | 12 ++++---- vms/platformvm/vm_test.go | 22 +++++++------- 26 files changed, 151 insertions(+), 148 deletions(-) diff --git a/node/node.go b/node/node.go index 64daf9fc0685..6ecac252b1c3 100644 --- a/node/node.go +++ b/node/node.go @@ -1134,7 +1134,7 @@ func (n *Node) initVMs() error { SybilProtectionEnabled: n.Config.SybilProtectionEnabled, PartialSyncPrimaryNetwork: n.Config.PartialSyncPrimaryNetwork, TrackedSubnets: n.Config.TrackedSubnets, - StaticConfig: fee.StaticConfig{ + StaticFeeConfig: fee.StaticConfig{ TxFee: n.Config.TxFee, CreateAssetTxFee: n.Config.CreateAssetTxFee, CreateSubnetTxFee: n.Config.CreateSubnetTxFee, @@ -1153,7 +1153,7 @@ func (n *Node) initVMs() error { MinStakeDuration: n.Config.MinStakeDuration, MaxStakeDuration: n.Config.MaxStakeDuration, RewardConfig: n.Config.RewardConfig, - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ ApricotPhase3Time: version.GetApricotPhase3Time(n.Config.NetworkID), ApricotPhase5Time: version.GetApricotPhase5Time(n.Config.NetworkID), BanffTime: version.GetBanffTime(n.Config.NetworkID), diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 64abd8a46857..4088ccaee7a1 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -301,7 +301,7 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { // Post-Durango, [StartTime] is no longer validated. Staking durations are // based on the current chain timestamp and must be validated. - env.config.DurangoTime = time.Time{} + env.config.UpgradeConfig.DurangoTime = time.Time{} var ( now = env.backend.Clk.Time() diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 3d3fd1958773..0108162649d6 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -309,7 +309,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { Chains: chains.TestManager, UptimeLockedCalculator: uptime.NewLockedCalculator(), Validators: validators.NewManager(), - StaticConfig: fee.StaticConfig{ + StaticFeeConfig: fee.StaticConfig{ TxFee: defaultTxFee, CreateSubnetTxFee: 100 * defaultTxFee, CreateBlockchainTxFee: 100 * defaultTxFee, @@ -325,7 +325,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ ApricotPhase3Time: mockable.MaxTime, ApricotPhase5Time: mockable.MaxTime, BanffTime: mockable.MaxTime, @@ -337,22 +337,22 @@ func defaultConfig(t *testing.T, f fork) *config.Config { switch f { case eUpgrade: - c.EUpgradeTime = time.Time{} // neglecting fork ordering this for package tests + c.UpgradeConfig.EUpgradeTime = time.Time{} // neglecting fork ordering this for package tests fallthrough case durango: - c.DurangoTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.DurangoTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case cortina: - c.CortinaTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.CortinaTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case banff: - c.BanffTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.BanffTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case apricotPhase5: - c.ApricotPhase5Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase5Time = defaultValidateEndTime fallthrough case apricotPhase3: - c.ApricotPhase3Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase3Time = defaultValidateEndTime default: require.FailNow(t, "unhandled fork", f) } diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 885276c04ff6..d87b67c76d25 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -331,7 +331,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { Chains: chains.TestManager, UptimeLockedCalculator: uptime.NewLockedCalculator(), Validators: validators.NewManager(), - StaticConfig: fee.StaticConfig{ + StaticFeeConfig: fee.StaticConfig{ TxFee: defaultTxFee, CreateSubnetTxFee: 100 * defaultTxFee, CreateBlockchainTxFee: 100 * defaultTxFee, @@ -347,7 +347,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ ApricotPhase3Time: mockable.MaxTime, ApricotPhase5Time: mockable.MaxTime, BanffTime: mockable.MaxTime, @@ -359,22 +359,22 @@ func defaultConfig(t *testing.T, f fork) *config.Config { switch f { case eUpgrade: - c.EUpgradeTime = time.Time{} // neglecting fork ordering this for package tests + c.UpgradeConfig.EUpgradeTime = time.Time{} // neglecting fork ordering this for package tests fallthrough case durango: - c.DurangoTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.DurangoTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case cortina: - c.CortinaTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.CortinaTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case banff: - c.BanffTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.BanffTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case apricotPhase5: - c.ApricotPhase5Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase5Time = defaultValidateEndTime fallthrough case apricotPhase3: - c.ApricotPhase3Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase3Time = defaultValidateEndTime default: require.FailNow(t, "unhandled fork", f) } diff --git a/vms/platformvm/block/executor/standard_block_test.go b/vms/platformvm/block/executor/standard_block_test.go index 880b706884e1..b8c9257a2915 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -143,7 +143,7 @@ func TestBanffStandardBlockTimeVerification(t *testing.T) { ID: avaxAssetID, }, Out: &secp256k1fx.TransferOutput{ - Amt: env.config.CreateSubnetTxFee, + Amt: env.config.StaticFeeConfig.CreateSubnetTxFee, }, } utxoID := utxo.InputID() @@ -158,7 +158,7 @@ func TestBanffStandardBlockTimeVerification(t *testing.T) { UTXOID: utxo.UTXOID, Asset: utxo.Asset, In: &secp256k1fx.TransferInput{ - Amt: env.config.CreateSubnetTxFee, + Amt: env.config.StaticFeeConfig.CreateSubnetTxFee, }, }}, }}, diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 926a7acf4fa0..c56abc45e3c1 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -179,11 +179,11 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { parentID := b.Parent() currentTimestamp := v.getTimestamp(parentID) cfg := v.txExecutorBackend.Config - if cfg.IsApricotPhase5Activated(currentTimestamp) { + if cfg.UpgradeConfig.IsApricotPhase5Activated(currentTimestamp) { return fmt.Errorf( "the chain timestamp (%d) is after the apricot phase 5 time (%d), hence atomic transactions should go through the standard block", currentTimestamp.Unix(), - cfg.ApricotPhase5Time.Unix(), + cfg.UpgradeConfig.ApricotPhase5Time.Unix(), ) } @@ -290,7 +290,7 @@ func (v *verifier) apricotCommonBlock(b block.Block) error { // during the verification of the ProposalBlock. parentID := b.Parent() timestamp := v.getTimestamp(parentID) - if v.txExecutorBackend.Config.IsBanffActivated(timestamp) { + if v.txExecutorBackend.Config.UpgradeConfig.IsBanffActivated(timestamp) { return fmt.Errorf("%w: timestamp = %s", errApricotBlockIssuedAfterFork, timestamp) } return v.commonBlock(b) diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index 1e55aa9f52a9..34d8a0d7432e 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -59,7 +59,7 @@ func TestVerifierVisitProposalBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -145,7 +145,7 @@ func TestVerifierVisitAtomicBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ ApricotPhase5Time: time.Now().Add(time.Hour), BanffTime: mockable.MaxTime, // banff is not activated }, @@ -234,7 +234,7 @@ func TestVerifierVisitStandardBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ ApricotPhase5Time: time.Now().Add(time.Hour), BanffTime: mockable.MaxTime, // banff is not activated }, @@ -341,7 +341,7 @@ func TestVerifierVisitCommitBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -414,7 +414,7 @@ func TestVerifierVisitAbortBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -475,7 +475,7 @@ func TestVerifyUnverifiedParent(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -549,7 +549,7 @@ func TestBanffAbortBlockTimestampChecks(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: time.Time{}, // banff is activated }, }, @@ -647,7 +647,7 @@ func TestBanffCommitBlockTimestampChecks(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: time.Time{}, // banff is activated }, }, @@ -728,7 +728,7 @@ func TestVerifierVisitStandardBlockWithDuplicateInputs(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ ApricotPhase5Time: time.Now().Add(time.Hour), BanffTime: mockable.MaxTime, // banff is not activated }, @@ -819,7 +819,7 @@ func TestVerifierVisitApricotStandardBlockWithProposalBlockParent(t *testing.T) verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -878,7 +878,7 @@ func TestVerifierVisitBanffStandardBlockWithProposalBlockParent(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: time.Time{}, // banff is activated }, }, @@ -917,7 +917,7 @@ func TestVerifierVisitApricotCommitBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -962,7 +962,7 @@ func TestVerifierVisitBanffCommitBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: time.Time{}, // banff is activated }, }, @@ -1008,7 +1008,7 @@ func TestVerifierVisitApricotAbortBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: mockable.MaxTime, // banff is not activated }, }, @@ -1053,7 +1053,7 @@ func TestVerifierVisitBanffAbortBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: time.Time{}, // banff is activated }, }, diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 745a2713d431..731b079ca425 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -20,12 +20,6 @@ import ( // Struct collecting all foundational parameters of PlatformVM type Config struct { - // All network upgrade timestamps - upgrade.Config - - // All static fees config active before E-upgrade - fee.StaticConfig - // The node's chain manager Chains chains.Manager @@ -37,6 +31,9 @@ type Config struct { // calling VM.Initialize. Validators validators.Manager + // All static fees config active before E-upgrade + StaticFeeConfig fee.StaticConfig + // Provides access to the uptime manager as a thread safe data structure UptimeLockedCalculator uptime.LockedCalculator @@ -73,6 +70,9 @@ type Config struct { // Config for the minting function RewardConfig reward.Config + // All network upgrade timestamps + UpgradeConfig upgrade.Config + // UseCurrentHeight forces [GetMinimumHeight] to return the current height // of the P-Chain instead of the oldest block in the [recentlyAccepted] // window. diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index db1132fc0451..5a3f8eb7cc5c 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -365,7 +365,10 @@ func TestGetBalance(t *testing.T) { require := require.New(t) service, _, _ := defaultService(t) - createSubnetFee := service.vm.Config.GetCreateSubnetTxFee(service.vm.Config.Config, service.vm.clock.Time()) + createSubnetFee := service.vm.Config.StaticFeeConfig.GetCreateSubnetTxFee( + service.vm.Config.UpgradeConfig, + service.vm.clock.Time(), + ) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) @@ -751,7 +754,7 @@ func TestGetBlock(t *testing.T) { service, _, txBuilder := defaultService(t) service.vm.ctx.Lock.Lock() - service.vm.CreateAssetTxFee = 100 * defaultTxFee + service.vm.StaticFeeConfig.CreateAssetTxFee = 100 * defaultTxFee // Make a block an accept it, then check we can get it. tx, err := txBuilder.NewCreateChainTx( // Test GetTx works for standard blocks diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index ccfd6d824159..7f06f02e86d6 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1628,7 +1628,7 @@ func (s *state) initValidatorSets() error { func (s *state) write(updateValidators bool, height uint64) error { codecVersion := CodecVersion1 - if !s.cfg.IsDurangoActivated(s.GetTimestamp()) { + if !s.cfg.UpgradeConfig.IsDurangoActivated(s.GetTimestamp()) { codecVersion = CodecVersion0 } diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index ea36af13e939..755cbb3b2beb 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -852,9 +852,9 @@ func TestAdvanceTimeTxAfterBanff(t *testing.T) { defer env.ctx.Lock.Unlock() env.clk.Set(defaultGenesisTime) // VM's clock reads the genesis time upgradeTime := env.clk.Time().Add(SyncBound) - env.config.BanffTime = upgradeTime - env.config.CortinaTime = upgradeTime - env.config.DurangoTime = upgradeTime + env.config.UpgradeConfig.BanffTime = upgradeTime + env.config.UpgradeConfig.CortinaTime = upgradeTime + env.config.UpgradeConfig.DurangoTime = upgradeTime // Proposed advancing timestamp to the banff timestamp tx, err := newAdvanceTimeTx(t, upgradeTime) diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 5b714909b942..346c8ab1468a 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -185,7 +185,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { require := require.New(t) env := newEnvironment(t, banff) - env.config.ApricotPhase3Time = ap3Time + env.config.UpgradeConfig.ApricotPhase3Time = ap3Time addrs := set.NewSet[ids.ShortID](len(preFundedKeys)) for _, key := range preFundedKeys { @@ -195,7 +195,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { env.state.SetTimestamp(test.time) // to duly set fee cfg := *env.config - cfg.CreateBlockchainTxFee = test.fee + cfg.StaticFeeConfig.CreateBlockchainTxFee = test.fee builder := txstest.NewBuilder(env.ctx, &cfg, env.state) tx, err := builder.NewCreateChainTx( testSubnet1.ID(), diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index f4358e1d8bce..c1902dd56625 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -50,7 +50,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { require := require.New(t) env := newEnvironment(t, apricotPhase3) - env.config.ApricotPhase3Time = ap3Time + env.config.UpgradeConfig.ApricotPhase3Time = ap3Time env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -62,7 +62,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { } cfg := *env.config - cfg.CreateSubnetTxFee = test.fee + cfg.StaticFeeConfig.CreateSubnetTxFee = test.fee builder := txstest.NewBuilder(env.ctx, &cfg, env.state) tx, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{}, diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index d45a52b486d5..7959791187db 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -41,7 +41,7 @@ func TestNewExportTx(t *testing.T) { description: "P->C export", destinationChainID: env.ctx.CChainID, sourceKeys: []*secp256k1.PrivateKey{sourceKey}, - timestamp: env.config.ApricotPhase5Time, + timestamp: env.config.UpgradeConfig.ApricotPhase5Time, }, } diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index a98475d6dc90..74c706227fea 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -280,7 +280,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { Chains: chains.TestManager, UptimeLockedCalculator: uptime.NewLockedCalculator(), Validators: validators.NewManager(), - StaticConfig: fee.StaticConfig{ + StaticFeeConfig: fee.StaticConfig{ TxFee: defaultTxFee, CreateSubnetTxFee: 100 * defaultTxFee, CreateBlockchainTxFee: 100 * defaultTxFee, @@ -296,7 +296,7 @@ func defaultConfig(t *testing.T, f fork) *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ ApricotPhase3Time: mockable.MaxTime, ApricotPhase5Time: mockable.MaxTime, BanffTime: mockable.MaxTime, @@ -308,22 +308,22 @@ func defaultConfig(t *testing.T, f fork) *config.Config { switch f { case eUpgrade: - c.EUpgradeTime = defaultValidateStartTime.Add(-2 * time.Second) + c.UpgradeConfig.EUpgradeTime = defaultValidateStartTime.Add(-2 * time.Second) fallthrough case durango: - c.DurangoTime = defaultValidateStartTime.Add(-2 * time.Second) + c.UpgradeConfig.DurangoTime = defaultValidateStartTime.Add(-2 * time.Second) fallthrough case cortina: - c.CortinaTime = defaultValidateStartTime.Add(-2 * time.Second) + c.UpgradeConfig.CortinaTime = defaultValidateStartTime.Add(-2 * time.Second) fallthrough case banff: - c.BanffTime = defaultValidateStartTime.Add(-2 * time.Second) + c.UpgradeConfig.BanffTime = defaultValidateStartTime.Add(-2 * time.Second) fallthrough case apricotPhase5: - c.ApricotPhase5Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase5Time = defaultValidateEndTime fallthrough case apricotPhase3: - c.ApricotPhase3Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase3Time = defaultValidateEndTime default: require.FailNow(t, "unhandled fork", f) } diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index 4ae35d80ae03..038e2ec26d68 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -50,7 +50,7 @@ func TestNewImportTx(t *testing.T) { sourceKey, env.ctx.XChainID, map[ids.ID]uint64{ - env.ctx.AVAXAssetID: env.config.TxFee - 1, + env.ctx.AVAXAssetID: env.config.StaticFeeConfig.TxFee - 1, }, ), sourceKeys: []*secp256k1.PrivateKey{sourceKey}, @@ -65,7 +65,7 @@ func TestNewImportTx(t *testing.T) { sourceKey, env.ctx.XChainID, map[ids.ID]uint64{ - env.ctx.AVAXAssetID: env.config.TxFee, + env.ctx.AVAXAssetID: env.config.StaticFeeConfig.TxFee, }, ), sourceKeys: []*secp256k1.PrivateKey{sourceKey}, @@ -80,11 +80,11 @@ func TestNewImportTx(t *testing.T) { sourceKey, env.ctx.CChainID, map[ids.ID]uint64{ - env.ctx.AVAXAssetID: env.config.TxFee, + env.ctx.AVAXAssetID: env.config.StaticFeeConfig.TxFee, }, ), sourceKeys: []*secp256k1.PrivateKey{sourceKey}, - timestamp: env.config.ApricotPhase5Time, + timestamp: env.config.UpgradeConfig.ApricotPhase5Time, expectedErr: nil, }, { @@ -96,12 +96,12 @@ func TestNewImportTx(t *testing.T) { sourceKey, env.ctx.XChainID, map[ids.ID]uint64{ - env.ctx.AVAXAssetID: env.config.TxFee, + env.ctx.AVAXAssetID: env.config.StaticFeeConfig.TxFee, customAssetID: 1, }, ), sourceKeys: []*secp256k1.PrivateKey{sourceKey}, - timestamp: env.config.ApricotPhase5Time, + timestamp: env.config.UpgradeConfig.ApricotPhase5Time, expectedErr: nil, }, } @@ -143,7 +143,7 @@ func TestNewImportTx(t *testing.T) { totalOut += out.Out.Amount() } - require.Equal(env.config.TxFee, totalIn-totalOut) + require.Equal(env.config.StaticFeeConfig.TxFee, totalIn-totalOut) stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) diff --git a/vms/platformvm/txs/executor/proposal_tx_executor.go b/vms/platformvm/txs/executor/proposal_tx_executor.go index 0f082cb8b296..294e01486a17 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor.go @@ -103,12 +103,12 @@ func (e *ProposalTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error { // activation. Following the activation, AddValidatorTxs must be issued into // StandardBlocks. currentTimestamp := e.OnCommitState.GetTimestamp() - if e.Config.IsBanffActivated(currentTimestamp) { + if e.Config.UpgradeConfig.IsBanffActivated(currentTimestamp) { return fmt.Errorf( "%w: timestamp (%s) >= Banff fork time (%s)", ErrProposedAddStakerTxAfterBanff, currentTimestamp, - e.Config.BanffTime, + e.Config.UpgradeConfig.BanffTime, ) } @@ -150,12 +150,12 @@ func (e *ProposalTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) // activation. Following the activation, AddSubnetValidatorTxs must be // issued into StandardBlocks. currentTimestamp := e.OnCommitState.GetTimestamp() - if e.Config.IsBanffActivated(currentTimestamp) { + if e.Config.UpgradeConfig.IsBanffActivated(currentTimestamp) { return fmt.Errorf( "%w: timestamp (%s) >= Banff fork time (%s)", ErrProposedAddStakerTxAfterBanff, currentTimestamp, - e.Config.BanffTime, + e.Config.UpgradeConfig.BanffTime, ) } @@ -196,12 +196,12 @@ func (e *ProposalTxExecutor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { // activation. Following the activation, AddDelegatorTxs must be issued into // StandardBlocks. currentTimestamp := e.OnCommitState.GetTimestamp() - if e.Config.IsBanffActivated(currentTimestamp) { + if e.Config.UpgradeConfig.IsBanffActivated(currentTimestamp) { return fmt.Errorf( "%w: timestamp (%s) >= Banff fork time (%s)", ErrProposedAddStakerTxAfterBanff, currentTimestamp, - e.Config.BanffTime, + e.Config.UpgradeConfig.BanffTime, ) } @@ -248,12 +248,12 @@ func (e *ProposalTxExecutor) AdvanceTimeTx(tx *txs.AdvanceTimeTx) error { // Validate [newChainTime] newChainTime := tx.Timestamp() - if e.Config.IsBanffActivated(newChainTime) { + if e.Config.UpgradeConfig.IsBanffActivated(newChainTime) { return fmt.Errorf( "%w: proposed timestamp (%s) >= Banff fork time (%s)", ErrAdvanceTimeTxIssuedAfterBanff, newChainTime, - e.Config.BanffTime, + e.Config.UpgradeConfig.BanffTime, ) } @@ -558,7 +558,7 @@ func (e *ProposalTxExecutor) rewardDelegatorTx(uDelegatorTx txs.DelegatorTx, del } // Reward the delegatee here - if e.Config.IsCortinaActivated(validator.StartTime) { + if e.Config.UpgradeConfig.IsCortinaActivated(validator.StartTime) { previousDelegateeReward, err := e.OnCommitState.GetDelegateeReward( validator.SubnetID, validator.NodeID, diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index 6fe0f7831235..87caaca7d7c1 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -235,7 +235,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { t.Run(tt.description, func(t *testing.T) { require := require.New(t) env := newEnvironment(t, apricotPhase5) - env.config.ApricotPhase3Time = tt.AP3Time + env.config.UpgradeConfig.ApricotPhase3Time = tt.AP3Time tx, err := env.txBuilder.NewAddDelegatorTx( &txs.Validator{ diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 562bbcbcfa82..8076949cefe1 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -98,7 +98,7 @@ func verifyAddValidatorTx( error, ) { currentTimestamp := chainState.GetTimestamp() - if backend.Config.IsDurangoActivated(currentTimestamp) { + if backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { return nil, ErrAddValidatorTxPostDurango } @@ -165,7 +165,7 @@ func verifyAddValidatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -201,7 +201,7 @@ func verifyAddSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -259,7 +259,7 @@ func verifyAddSubnetValidatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -301,7 +301,7 @@ func verifyRemoveSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return nil, false, err @@ -340,7 +340,7 @@ func verifyRemoveSubnetValidatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, false, err } @@ -374,7 +374,7 @@ func verifyAddDelegatorTx( error, ) { currentTimestamp := chainState.GetTimestamp() - if backend.Config.IsDurangoActivated(currentTimestamp) { + if backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { return nil, ErrAddDelegatorTxPostDurango } @@ -432,7 +432,7 @@ func verifyAddDelegatorTx( return nil, ErrStakeOverflow } - if backend.Config.IsApricotPhase3Activated(currentTimestamp) { + if backend.Config.UpgradeConfig.IsApricotPhase3Activated(currentTimestamp) { maximumWeight = min(maximumWeight, backend.Config.MaxValidatorStake) } @@ -461,7 +461,7 @@ func verifyAddDelegatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -497,7 +497,7 @@ func verifyAddPermissionlessValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -584,7 +584,7 @@ func verifyAddPermissionlessValidatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -620,7 +620,7 @@ func verifyAddPermissionlessDelegatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -732,7 +732,7 @@ func verifyAddPermissionlessDelegatorTx( // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -765,7 +765,7 @@ func verifyTransferSubnetOwnershipTx( sTx *txs.Tx, tx *txs.TransferSubnetOwnershipTx, ) error { - if !backend.Config.IsDurangoActivated(chainState.GetTimestamp()) { + if !backend.Config.UpgradeConfig.IsDurangoActivated(chainState.GetTimestamp()) { return ErrDurangoUpgradeNotActive } @@ -790,7 +790,7 @@ func verifyTransferSubnetOwnershipTx( // Verify the flowcheck currentTimestamp := chainState.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticConfig, backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index 24e1df2a0db6..bde3da64ad7a 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -423,7 +423,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { ).Return(ErrFlowCheckFailed) cfg := defaultTestConfig(t, durango, activeForkTime) - cfg.AddSubnetValidatorFee = 1 + cfg.StaticFeeConfig.AddSubnetValidatorFee = 1 return &Backend{ FlowChecker: flowChecker, @@ -469,7 +469,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { ).Return(nil) cfg := defaultTestConfig(t, durango, activeForkTime) - cfg.AddSubnetValidatorFee = 1 + cfg.StaticFeeConfig.AddSubnetValidatorFee = 1 return &Backend{ FlowChecker: flowChecker, diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 6635540344bb..5d519c1fb32b 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -57,7 +57,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -69,7 +69,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -112,14 +112,14 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -156,7 +156,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -204,7 +204,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -248,7 +248,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -265,7 +265,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -438,7 +438,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -455,7 +455,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error return err } - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -566,7 +566,7 @@ func (e *StandardTxExecutor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwn } func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { - if !e.Backend.Config.IsDurangoActivated(e.State.GetTimestamp()) { + if !e.Backend.Config.UpgradeConfig.IsDurangoActivated(e.State.GetTimestamp()) { return ErrDurangoUpgradeNotActive } @@ -581,7 +581,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { // Verify the flowcheck currentTimestamp := e.State.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticConfig, e.Backend.Config.Config, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return err } @@ -616,7 +616,7 @@ func (e *StandardTxExecutor) putStaker(stakerTx txs.Staker) error { err error ) - if !e.Config.IsDurangoActivated(chainTime) { + if !e.Config.UpgradeConfig.IsDurangoActivated(chainTime) { // Pre-Durango, stakers set a future [StartTime] and are added to the // pending staker set. They are promoted to the current staker set once // the chain time reaches [StartTime]. diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 3c16f333c330..ced62075e5ee 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -71,7 +71,7 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { } for _, test := range tests { // Case: Empty validator node ID after banff - env.config.BanffTime = test.banffTime + env.config.UpgradeConfig.BanffTime = test.banffTime tx, err := env.txBuilder.NewAddValidatorTx( // create the tx &txs.Validator{ @@ -316,7 +316,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { t.Run(tt.description, func(t *testing.T) { require := require.New(t) env := newEnvironment(t, apricotPhase5) - env.config.ApricotPhase3Time = tt.AP3Time + env.config.UpgradeConfig.ApricotPhase3Time = tt.AP3Time tx, err := env.txBuilder.NewAddDelegatorTx( &txs.Validator{ @@ -340,7 +340,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - env.config.BanffTime = onAcceptState.GetTimestamp() + env.config.UpgradeConfig.BanffTime = onAcceptState.GetTimestamp() executor := StandardTxExecutor{ Backend: &env.backend, @@ -2081,7 +2081,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { func defaultTestConfig(t *testing.T, f fork, tm time.Time) *config.Config { c := &config.Config{ - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ ApricotPhase3Time: mockable.MaxTime, ApricotPhase5Time: mockable.MaxTime, BanffTime: mockable.MaxTime, @@ -2093,22 +2093,22 @@ func defaultTestConfig(t *testing.T, f fork, tm time.Time) *config.Config { switch f { case eUpgrade: - c.EUpgradeTime = tm + c.UpgradeConfig.EUpgradeTime = tm fallthrough case durango: - c.DurangoTime = tm + c.UpgradeConfig.DurangoTime = tm fallthrough case cortina: - c.CortinaTime = tm + c.UpgradeConfig.CortinaTime = tm fallthrough case banff: - c.BanffTime = tm + c.UpgradeConfig.BanffTime = tm fallthrough case apricotPhase5: - c.ApricotPhase5Time = tm + c.UpgradeConfig.ApricotPhase5Time = tm fallthrough case apricotPhase3: - c.ApricotPhase3Time = tm + c.UpgradeConfig.ApricotPhase3Time = tm default: require.FailNow(t, "unhandled fork", f) } diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index 3253448f5a69..460b6a28cfed 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -19,13 +19,13 @@ func newContext( return &builder.Context{ NetworkID: ctx.NetworkID, AVAXAssetID: ctx.AVAXAssetID, - BaseTxFee: cfg.TxFee, - CreateSubnetTxFee: cfg.GetCreateSubnetTxFee(cfg.Config, timestamp), - TransformSubnetTxFee: cfg.TransformSubnetTxFee, - CreateBlockchainTxFee: cfg.GetCreateBlockchainTxFee(cfg.Config, timestamp), - AddPrimaryNetworkValidatorFee: cfg.AddPrimaryNetworkValidatorFee, - AddPrimaryNetworkDelegatorFee: cfg.AddPrimaryNetworkDelegatorFee, - AddSubnetValidatorFee: cfg.AddSubnetValidatorFee, - AddSubnetDelegatorFee: cfg.AddSubnetDelegatorFee, + BaseTxFee: cfg.StaticFeeConfig.TxFee, + CreateSubnetTxFee: cfg.StaticFeeConfig.GetCreateSubnetTxFee(cfg.UpgradeConfig, timestamp), + TransformSubnetTxFee: cfg.StaticFeeConfig.TransformSubnetTxFee, + CreateBlockchainTxFee: cfg.StaticFeeConfig.GetCreateBlockchainTxFee(cfg.UpgradeConfig, timestamp), + AddPrimaryNetworkValidatorFee: cfg.StaticFeeConfig.AddPrimaryNetworkValidatorFee, + AddPrimaryNetworkDelegatorFee: cfg.StaticFeeConfig.AddPrimaryNetworkDelegatorFee, + AddSubnetValidatorFee: cfg.StaticFeeConfig.AddSubnetValidatorFee, + AddSubnetDelegatorFee: cfg.StaticFeeConfig.AddSubnetDelegatorFee, } } diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 7c08a15bc043..faf5eb810d51 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -653,7 +653,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { UptimeLockedCalculator: uptime.NewLockedCalculator(), SybilProtectionEnabled: true, Validators: validators.NewManager(), - StaticConfig: fee.StaticConfig{ + StaticFeeConfig: fee.StaticConfig{ TxFee: defaultTxFee, CreateSubnetTxFee: 100 * defaultTxFee, TransformSubnetTxFee: 100 * defaultTxFee, @@ -665,7 +665,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ ApricotPhase3Time: forkTime, ApricotPhase5Time: forkTime, BanffTime: forkTime, diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 53a115eed6d4..d29b2b0af1fa 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -252,7 +252,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require := require.New(t) vm, txBuilder, _, _ := defaultVM(t, apricotPhase3) - vm.ApricotPhase3Time = test.ap3Time + vm.UpgradeConfig.ApricotPhase3Time = test.ap3Time vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -443,7 +443,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: mockable.MaxTime, DurangoTime: mockable.MaxTime, @@ -643,7 +643,7 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { ID: vm.ctx.AVAXAssetID, }, Out: &secp256k1fx.TransferOutput{ - Amt: vm.TxFee, + Amt: vm.StaticFeeConfig.TxFee, OutputOwners: secp256k1fx.OutputOwners{}, }, } @@ -660,7 +660,7 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { UTXOID: utxo.UTXOID, Asset: utxo.Asset, In: &secp256k1fx.TransferInput{ - Amt: vm.TxFee, + Amt: vm.StaticFeeConfig.TxFee, }, }, }, @@ -890,7 +890,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { ID: vm.ctx.AVAXAssetID, }, Out: &secp256k1fx.TransferOutput{ - Amt: vm.TxFee, + Amt: vm.StaticFeeConfig.TxFee, OutputOwners: secp256k1fx.OutputOwners{}, }, } @@ -907,7 +907,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { UTXOID: utxo.UTXOID, Asset: utxo.Asset, In: &secp256k1fx.TransferInput{ - Amt: vm.TxFee, + Amt: vm.StaticFeeConfig.TxFee, }, }, }, diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 5cf17c039c24..b2a03aacd9ee 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -246,7 +246,7 @@ func defaultVM(t *testing.T, f fork) (*VM, *txstest.Builder, database.Database, UptimeLockedCalculator: uptime.NewLockedCalculator(), SybilProtectionEnabled: true, Validators: validators.NewManager(), - StaticConfig: fee.StaticConfig{ + StaticFeeConfig: fee.StaticConfig{ TxFee: defaultTxFee, CreateSubnetTxFee: 100 * defaultTxFee, TransformSubnetTxFee: 100 * defaultTxFee, @@ -258,7 +258,7 @@ func defaultVM(t *testing.T, f fork) (*VM, *txstest.Builder, database.Database, MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ ApricotPhase3Time: apricotPhase3Time, ApricotPhase5Time: apricotPhase5Time, BanffTime: banffTime, @@ -390,7 +390,7 @@ func TestGenesis(t *testing.T) { require.NoError(err) require.Equal(utxo.Address, addr) - require.Equal(uint64(utxo.Amount)-vm.CreateSubnetTxFee, out.Amount()) + require.Equal(uint64(utxo.Amount)-vm.StaticFeeConfig.CreateSubnetTxFee, out.Amount()) } } @@ -1184,7 +1184,7 @@ func TestRestartFullyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1274,7 +1274,7 @@ func TestRestartFullyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1325,7 +1325,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1675,7 +1675,7 @@ func TestUnverifiedParent(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1838,7 +1838,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { RewardConfig: defaultRewardConfig, Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1889,7 +1889,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { UptimePercentage: secondUptimePercentage / 100., Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -1991,7 +1991,7 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { RewardConfig: defaultRewardConfig, Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - Config: upgrade.Config{ + UpgradeConfig: upgrade.Config{ BanffTime: latestForkTime, CortinaTime: latestForkTime, DurangoTime: latestForkTime, @@ -2371,7 +2371,7 @@ func TestBaseTx(t *testing.T) { } require.Equal(totalOutputAmt, key0OutputAmt+key1OutputAmt+changeAddrOutputAmt) - require.Equal(vm.TxFee, totalInputAmt-totalOutputAmt) + require.Equal(vm.StaticFeeConfig.TxFee, totalInputAmt-totalOutputAmt) require.Equal(sendAmt, key1OutputAmt) vm.ctx.Lock.Unlock() From 2776ea70b3bb4d8e38a1c80194660a8aa2e8291b Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 26 Apr 2024 08:10:29 +0200 Subject: [PATCH 030/100] nit --- vms/platformvm/service_test.go | 7 ++++--- vms/platformvm/txs/fee/calculator.go | 12 ++++++++++-- vms/platformvm/txs/fee/static_config.go | 20 -------------------- vms/platformvm/txs/txstest/context.go | 12 ++++++++++-- 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 5a3f8eb7cc5c..c04fdea3ba8b 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -39,6 +39,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -365,9 +366,9 @@ func TestGetBalance(t *testing.T) { require := require.New(t) service, _, _ := defaultService(t) - createSubnetFee := service.vm.Config.StaticFeeConfig.GetCreateSubnetTxFee( - service.vm.Config.UpgradeConfig, - service.vm.clock.Time(), + var ( + feeStaticCalc = fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig) + createSubnetFee = feeStaticCalc.CalculateFee(&txs.CreateSubnetTx{}, service.vm.clock.Time()) ) // Ensure GetStake is correct for each of the genesis validators diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 73cd1141ece7..b7ac9b99f05c 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -65,12 +65,20 @@ func (c *calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { } func (c *calculator) CreateChainTx(*txs.CreateChainTx) error { - c.fee = c.staticCfg.GetCreateBlockchainTxFee(c.upgrades, c.time) + if c.upgrades.IsApricotPhase3Activated(c.time) { + c.fee = c.staticCfg.CreateBlockchainTxFee + } else { + c.fee = c.staticCfg.CreateAssetTxFee + } return nil } func (c *calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { - c.fee = c.staticCfg.GetCreateSubnetTxFee(c.upgrades, c.time) + if c.upgrades.IsApricotPhase3Activated(c.time) { + c.fee = c.staticCfg.CreateSubnetTxFee + } else { + c.fee = c.staticCfg.CreateAssetTxFee + } return nil } diff --git a/vms/platformvm/txs/fee/static_config.go b/vms/platformvm/txs/fee/static_config.go index 00a4326526d7..12899b315b32 100644 --- a/vms/platformvm/txs/fee/static_config.go +++ b/vms/platformvm/txs/fee/static_config.go @@ -3,12 +3,6 @@ package fee -import ( - "time" - - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" -) - type StaticConfig struct { // Fee that is burned by every non-state creating transaction TxFee uint64 @@ -49,17 +43,3 @@ type StaticConfig struct { // Minimum fee that can be charged for delegation MinDelegationFee uint32 } - -func (c *StaticConfig) GetCreateBlockchainTxFee(upgrades upgrade.Config, timestamp time.Time) uint64 { - if upgrades.IsApricotPhase3Activated(timestamp) { - return c.CreateBlockchainTxFee - } - return c.CreateAssetTxFee -} - -func (c *StaticConfig) GetCreateSubnetTxFee(upgrades upgrade.Config, timestamp time.Time) uint64 { - if upgrades.IsApricotPhase3Activated(timestamp) { - return c.CreateSubnetTxFee - } - return c.CreateAssetTxFee -} diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index 460b6a28cfed..330af65a92a8 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -8,6 +8,8 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/vms/platformvm/config" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) @@ -16,13 +18,19 @@ func newContext( cfg *config.Config, timestamp time.Time, ) *builder.Context { + var ( + feeStaticCalc = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + createSubnetFee = feeStaticCalc.CalculateFee(&txs.CreateSubnetTx{}, timestamp) + createChainFee = feeStaticCalc.CalculateFee(&txs.CreateChainTx{}, timestamp) + ) + return &builder.Context{ NetworkID: ctx.NetworkID, AVAXAssetID: ctx.AVAXAssetID, BaseTxFee: cfg.StaticFeeConfig.TxFee, - CreateSubnetTxFee: cfg.StaticFeeConfig.GetCreateSubnetTxFee(cfg.UpgradeConfig, timestamp), + CreateSubnetTxFee: createSubnetFee, TransformSubnetTxFee: cfg.StaticFeeConfig.TransformSubnetTxFee, - CreateBlockchainTxFee: cfg.StaticFeeConfig.GetCreateBlockchainTxFee(cfg.UpgradeConfig, timestamp), + CreateBlockchainTxFee: createChainFee, AddPrimaryNetworkValidatorFee: cfg.StaticFeeConfig.AddPrimaryNetworkValidatorFee, AddPrimaryNetworkDelegatorFee: cfg.StaticFeeConfig.AddPrimaryNetworkDelegatorFee, AddSubnetValidatorFee: cfg.StaticFeeConfig.AddSubnetValidatorFee, From a10435844fa39244ec569ab21140c35bf779f4d5 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 26 Apr 2024 08:18:19 +0200 Subject: [PATCH 031/100] nit --- vms/platformvm/txs/fee/calculator.go | 1 + 1 file changed, 1 insertion(+) diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index b7ac9b99f05c..fbb996c3a50c 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -25,6 +25,7 @@ type Calculator struct { upgradeTimes upgrade.Config } +// [CalculateFee] returns the minimal fee needed to accept [tx], at chain time [time] func (c Calculator) CalculateFee(tx txs.UnsignedTx, time time.Time) uint64 { tmp := &calculator{ upgrades: c.upgradeTimes, From 2b4cdbce5cd062e3de9b3b98a037f7b6dbd9dda7 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 29 Apr 2024 09:10:08 +0200 Subject: [PATCH 032/100] nits --- vms/platformvm/service_test.go | 4 ++-- vms/platformvm/txs/txstest/context.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index c04fdea3ba8b..4d4e79de11e8 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -367,8 +367,8 @@ func TestGetBalance(t *testing.T) { service, _, _ := defaultService(t) var ( - feeStaticCalc = fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig) - createSubnetFee = feeStaticCalc.CalculateFee(&txs.CreateSubnetTx{}, service.vm.clock.Time()) + feeCalc = fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig) + createSubnetFee = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, service.vm.clock.Time()) ) // Ensure GetStake is correct for each of the genesis validators diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index 330af65a92a8..ec2252a632e1 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -19,9 +19,9 @@ func newContext( timestamp time.Time, ) *builder.Context { var ( - feeStaticCalc = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) - createSubnetFee = feeStaticCalc.CalculateFee(&txs.CreateSubnetTx{}, timestamp) - createChainFee = feeStaticCalc.CalculateFee(&txs.CreateChainTx{}, timestamp) + feeCalc = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + createSubnetFee = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, timestamp) + createChainFee = feeCalc.CalculateFee(&txs.CreateChainTx{}, timestamp) ) return &builder.Context{ From 1747485b8079f404b1512045bcb8c48da0a9a750 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 14 May 2024 10:01:33 +0200 Subject: [PATCH 033/100] repackaged upgrades times into upgrade package --- node/node.go | 17 ++-- vms/platformvm/block/builder/builder_test.go | 2 +- vms/platformvm/block/builder/helpers_test.go | 27 +++--- vms/platformvm/block/executor/helpers_test.go | 27 +++--- vms/platformvm/block/executor/verifier.go | 6 +- .../block/executor/verifier_test.go | 67 +++++++++++---- vms/platformvm/config/config.go | 48 ++--------- vms/platformvm/state/state.go | 2 +- .../txs/executor/advance_time_test.go | 6 +- .../txs/executor/create_chain_test.go | 2 +- .../txs/executor/create_subnet_test.go | 2 +- vms/platformvm/txs/executor/export_test.go | 2 +- vms/platformvm/txs/executor/helpers_test.go | 27 +++--- vms/platformvm/txs/executor/import_test.go | 4 +- .../txs/executor/proposal_tx_executor.go | 18 ++-- .../txs/executor/proposal_tx_executor_test.go | 2 +- .../txs/executor/staker_tx_verification.go | 16 ++-- .../txs/executor/standard_tx_executor.go | 14 +-- .../txs/executor/standard_tx_executor_test.go | 33 +++---- vms/platformvm/upgrade/config.go | 50 +++++++++++ vms/platformvm/validator_set_property_test.go | 13 +-- vms/platformvm/vm_regression_test.go | 13 +-- vms/platformvm/vm_test.go | 85 +++++++++++-------- 23 files changed, 282 insertions(+), 201 deletions(-) create mode 100644 vms/platformvm/upgrade/config.go diff --git a/node/node.go b/node/node.go index 58e903404470..d225667ccf13 100644 --- a/node/node.go +++ b/node/node.go @@ -75,6 +75,7 @@ import ( "github.com/ava-labs/avalanchego/vms/avm" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/registry" "github.com/ava-labs/avalanchego/vms/rpcchainvm/runtime" @@ -1149,13 +1150,15 @@ func (n *Node) initVMs() error { MinStakeDuration: n.Config.MinStakeDuration, MaxStakeDuration: n.Config.MaxStakeDuration, RewardConfig: n.Config.RewardConfig, - ApricotPhase3Time: version.GetApricotPhase3Time(n.Config.NetworkID), - ApricotPhase5Time: version.GetApricotPhase5Time(n.Config.NetworkID), - BanffTime: version.GetBanffTime(n.Config.NetworkID), - CortinaTime: version.GetCortinaTime(n.Config.NetworkID), - DurangoTime: version.GetDurangoTime(n.Config.NetworkID), - EUpgradeTime: eUpgradeTime, - UseCurrentHeight: n.Config.UseCurrentHeight, + UpgradeConfig: upgrade.Config{ + ApricotPhase3Time: version.GetApricotPhase3Time(n.Config.NetworkID), + ApricotPhase5Time: version.GetApricotPhase5Time(n.Config.NetworkID), + BanffTime: version.GetBanffTime(n.Config.NetworkID), + CortinaTime: version.GetCortinaTime(n.Config.NetworkID), + DurangoTime: version.GetDurangoTime(n.Config.NetworkID), + EUpgradeTime: eUpgradeTime, + }, + UseCurrentHeight: n.Config.UseCurrentHeight, }, }), n.VMManager.RegisterFactory(context.TODO(), constants.AVMID, &avm.Factory{ diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 64abd8a46857..4088ccaee7a1 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -301,7 +301,7 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { // Post-Durango, [StartTime] is no longer validated. Staking durations are // based on the current chain timestamp and must be validated. - env.config.DurangoTime = time.Time{} + env.config.UpgradeConfig.DurangoTime = time.Time{} var ( now = env.backend.Clk.Time() diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 958ef92ae5c2..e9310ac05b4f 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -45,6 +45,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -321,32 +322,34 @@ func defaultConfig(t *testing.T, f fork) *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - ApricotPhase3Time: mockable.MaxTime, - ApricotPhase5Time: mockable.MaxTime, - BanffTime: mockable.MaxTime, - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + ApricotPhase3Time: mockable.MaxTime, + ApricotPhase5Time: mockable.MaxTime, + BanffTime: mockable.MaxTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, } switch f { case eUpgrade: - c.EUpgradeTime = time.Time{} // neglecting fork ordering this for package tests + c.UpgradeConfig.EUpgradeTime = time.Time{} // neglecting fork ordering this for package tests fallthrough case durango: - c.DurangoTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.DurangoTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case cortina: - c.CortinaTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.CortinaTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case banff: - c.BanffTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.BanffTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case apricotPhase5: - c.ApricotPhase5Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase5Time = defaultValidateEndTime fallthrough case apricotPhase3: - c.ApricotPhase3Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase3Time = defaultValidateEndTime default: require.FailNow(t, "unhandled fork", f) } diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 0849146afcf6..c1295f862a6c 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -46,6 +46,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -343,32 +344,34 @@ func defaultConfig(t *testing.T, f fork) *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - ApricotPhase3Time: mockable.MaxTime, - ApricotPhase5Time: mockable.MaxTime, - BanffTime: mockable.MaxTime, - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + ApricotPhase3Time: mockable.MaxTime, + ApricotPhase5Time: mockable.MaxTime, + BanffTime: mockable.MaxTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, } switch f { case eUpgrade: - c.EUpgradeTime = time.Time{} // neglecting fork ordering this for package tests + c.UpgradeConfig.EUpgradeTime = time.Time{} // neglecting fork ordering this for package tests fallthrough case durango: - c.DurangoTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.DurangoTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case cortina: - c.CortinaTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.CortinaTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case banff: - c.BanffTime = time.Time{} // neglecting fork ordering for this package's tests + c.UpgradeConfig.BanffTime = time.Time{} // neglecting fork ordering for this package's tests fallthrough case apricotPhase5: - c.ApricotPhase5Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase5Time = defaultValidateEndTime fallthrough case apricotPhase3: - c.ApricotPhase3Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase3Time = defaultValidateEndTime default: require.FailNow(t, "unhandled fork", f) } diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 926a7acf4fa0..c56abc45e3c1 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -179,11 +179,11 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { parentID := b.Parent() currentTimestamp := v.getTimestamp(parentID) cfg := v.txExecutorBackend.Config - if cfg.IsApricotPhase5Activated(currentTimestamp) { + if cfg.UpgradeConfig.IsApricotPhase5Activated(currentTimestamp) { return fmt.Errorf( "the chain timestamp (%d) is after the apricot phase 5 time (%d), hence atomic transactions should go through the standard block", currentTimestamp.Unix(), - cfg.ApricotPhase5Time.Unix(), + cfg.UpgradeConfig.ApricotPhase5Time.Unix(), ) } @@ -290,7 +290,7 @@ func (v *verifier) apricotCommonBlock(b block.Block) error { // during the verification of the ProposalBlock. parentID := b.Parent() timestamp := v.getTimestamp(parentID) - if v.txExecutorBackend.Config.IsBanffActivated(timestamp) { + if v.txExecutorBackend.Config.UpgradeConfig.IsBanffActivated(timestamp) { return fmt.Errorf("%w: timestamp = %s", errApricotBlockIssuedAfterFork, timestamp) } return v.commonBlock(b) diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index ba24fb2f1298..34d8a0d7432e 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" ) func TestVerifierVisitProposalBlock(t *testing.T) { @@ -58,7 +59,9 @@ func TestVerifierVisitProposalBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + UpgradeConfig: upgrade.Config{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -142,8 +145,10 @@ func TestVerifierVisitAtomicBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - ApricotPhase5Time: time.Now().Add(time.Hour), - BanffTime: mockable.MaxTime, // banff is not activated + UpgradeConfig: upgrade.Config{ + ApricotPhase5Time: time.Now().Add(time.Hour), + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -229,8 +234,10 @@ func TestVerifierVisitStandardBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - ApricotPhase5Time: time.Now().Add(time.Hour), - BanffTime: mockable.MaxTime, // banff is not activated + UpgradeConfig: upgrade.Config{ + ApricotPhase5Time: time.Now().Add(time.Hour), + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -334,7 +341,9 @@ func TestVerifierVisitCommitBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + UpgradeConfig: upgrade.Config{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -405,7 +414,9 @@ func TestVerifierVisitAbortBlock(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + UpgradeConfig: upgrade.Config{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -464,7 +475,9 @@ func TestVerifyUnverifiedParent(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + UpgradeConfig: upgrade.Config{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -536,7 +549,9 @@ func TestBanffAbortBlockTimestampChecks(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: time.Time{}, // banff is activated + UpgradeConfig: upgrade.Config{ + BanffTime: time.Time{}, // banff is activated + }, }, Clk: &mockable.Clock{}, }, @@ -632,7 +647,9 @@ func TestBanffCommitBlockTimestampChecks(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: time.Time{}, // banff is activated + UpgradeConfig: upgrade.Config{ + BanffTime: time.Time{}, // banff is activated + }, }, Clk: &mockable.Clock{}, }, @@ -711,8 +728,10 @@ func TestVerifierVisitStandardBlockWithDuplicateInputs(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - ApricotPhase5Time: time.Now().Add(time.Hour), - BanffTime: mockable.MaxTime, // banff is not activated + UpgradeConfig: upgrade.Config{ + ApricotPhase5Time: time.Now().Add(time.Hour), + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -800,7 +819,9 @@ func TestVerifierVisitApricotStandardBlockWithProposalBlockParent(t *testing.T) verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + UpgradeConfig: upgrade.Config{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -857,7 +878,9 @@ func TestVerifierVisitBanffStandardBlockWithProposalBlockParent(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: time.Time{}, // banff is activated + UpgradeConfig: upgrade.Config{ + BanffTime: time.Time{}, // banff is activated + }, }, Clk: &mockable.Clock{}, }, @@ -894,7 +917,9 @@ func TestVerifierVisitApricotCommitBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + UpgradeConfig: upgrade.Config{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -937,7 +962,9 @@ func TestVerifierVisitBanffCommitBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: time.Time{}, // banff is activated + UpgradeConfig: upgrade.Config{ + BanffTime: time.Time{}, // banff is activated + }, }, Clk: &mockable.Clock{}, }, @@ -981,7 +1008,9 @@ func TestVerifierVisitApricotAbortBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: mockable.MaxTime, // banff is not activated + UpgradeConfig: upgrade.Config{ + BanffTime: mockable.MaxTime, // banff is not activated + }, }, Clk: &mockable.Clock{}, }, @@ -1024,7 +1053,9 @@ func TestVerifierVisitBanffAbortBlockUnexpectedParentState(t *testing.T) { verifier := &verifier{ txExecutorBackend: &executor.Backend{ Config: &config.Config{ - BanffTime: time.Time{}, // banff is activated + UpgradeConfig: upgrade.Config{ + BanffTime: time.Time{}, // banff is activated + }, }, Clk: &mockable.Clock{}, }, diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 0c5fcf15a475..8b8a0c717aed 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -14,6 +14,7 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" ) // Struct collecting all foundational parameters of PlatformVM @@ -92,23 +93,8 @@ type Config struct { // Config for the minting function RewardConfig reward.Config - // Time of the AP3 network upgrade - ApricotPhase3Time time.Time - - // Time of the AP5 network upgrade - ApricotPhase5Time time.Time - - // Time of the Banff network upgrade - BanffTime time.Time - - // Time of the Cortina network upgrade - CortinaTime time.Time - - // Time of the Durango network upgrade - DurangoTime time.Time - - // Time of the E network upgrade - EUpgradeTime time.Time + // All network upgrade timestamps + UpgradeConfig upgrade.Config // UseCurrentHeight forces [GetMinimumHeight] to return the current height // of the P-Chain instead of the oldest block in the [recentlyAccepted] @@ -120,39 +106,15 @@ type Config struct { UseCurrentHeight bool } -func (c *Config) IsApricotPhase3Activated(timestamp time.Time) bool { - return !timestamp.Before(c.ApricotPhase3Time) -} - -func (c *Config) IsApricotPhase5Activated(timestamp time.Time) bool { - return !timestamp.Before(c.ApricotPhase5Time) -} - -func (c *Config) IsBanffActivated(timestamp time.Time) bool { - return !timestamp.Before(c.BanffTime) -} - -func (c *Config) IsCortinaActivated(timestamp time.Time) bool { - return !timestamp.Before(c.CortinaTime) -} - -func (c *Config) IsDurangoActivated(timestamp time.Time) bool { - return !timestamp.Before(c.DurangoTime) -} - -func (c *Config) IsEActivated(timestamp time.Time) bool { - return !timestamp.Before(c.EUpgradeTime) -} - func (c *Config) GetCreateBlockchainTxFee(timestamp time.Time) uint64 { - if c.IsApricotPhase3Activated(timestamp) { + if c.UpgradeConfig.IsApricotPhase3Activated(timestamp) { return c.CreateBlockchainTxFee } return c.CreateAssetTxFee } func (c *Config) GetCreateSubnetTxFee(timestamp time.Time) uint64 { - if c.IsApricotPhase3Activated(timestamp) { + if c.UpgradeConfig.IsApricotPhase3Activated(timestamp) { return c.CreateSubnetTxFee } return c.CreateAssetTxFee diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index ccfd6d824159..7f06f02e86d6 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1628,7 +1628,7 @@ func (s *state) initValidatorSets() error { func (s *state) write(updateValidators bool, height uint64) error { codecVersion := CodecVersion1 - if !s.cfg.IsDurangoActivated(s.GetTimestamp()) { + if !s.cfg.UpgradeConfig.IsDurangoActivated(s.GetTimestamp()) { codecVersion = CodecVersion0 } diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index ea36af13e939..755cbb3b2beb 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -852,9 +852,9 @@ func TestAdvanceTimeTxAfterBanff(t *testing.T) { defer env.ctx.Lock.Unlock() env.clk.Set(defaultGenesisTime) // VM's clock reads the genesis time upgradeTime := env.clk.Time().Add(SyncBound) - env.config.BanffTime = upgradeTime - env.config.CortinaTime = upgradeTime - env.config.DurangoTime = upgradeTime + env.config.UpgradeConfig.BanffTime = upgradeTime + env.config.UpgradeConfig.CortinaTime = upgradeTime + env.config.UpgradeConfig.DurangoTime = upgradeTime // Proposed advancing timestamp to the banff timestamp tx, err := newAdvanceTimeTx(t, upgradeTime) diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 5b714909b942..288a294e493b 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -185,7 +185,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { require := require.New(t) env := newEnvironment(t, banff) - env.config.ApricotPhase3Time = ap3Time + env.config.UpgradeConfig.ApricotPhase3Time = ap3Time addrs := set.NewSet[ids.ShortID](len(preFundedKeys)) for _, key := range preFundedKeys { diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index f4358e1d8bce..77b37773107b 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -50,7 +50,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { require := require.New(t) env := newEnvironment(t, apricotPhase3) - env.config.ApricotPhase3Time = ap3Time + env.config.UpgradeConfig.ApricotPhase3Time = ap3Time env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index d45a52b486d5..7959791187db 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -41,7 +41,7 @@ func TestNewExportTx(t *testing.T) { description: "P->C export", destinationChainID: env.ctx.CChainID, sourceKeys: []*secp256k1.PrivateKey{sourceKey}, - timestamp: env.config.ApricotPhase5Time, + timestamp: env.config.UpgradeConfig.ApricotPhase5Time, }, } diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 387b5d2a831d..994250dd5940 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -42,6 +42,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -292,32 +293,34 @@ func defaultConfig(t *testing.T, f fork) *config.Config { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }, - ApricotPhase3Time: mockable.MaxTime, - ApricotPhase5Time: mockable.MaxTime, - BanffTime: mockable.MaxTime, - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + ApricotPhase3Time: mockable.MaxTime, + ApricotPhase5Time: mockable.MaxTime, + BanffTime: mockable.MaxTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, } switch f { case eUpgrade: - c.EUpgradeTime = defaultValidateStartTime.Add(-2 * time.Second) + c.UpgradeConfig.EUpgradeTime = defaultValidateStartTime.Add(-2 * time.Second) fallthrough case durango: - c.DurangoTime = defaultValidateStartTime.Add(-2 * time.Second) + c.UpgradeConfig.DurangoTime = defaultValidateStartTime.Add(-2 * time.Second) fallthrough case cortina: - c.CortinaTime = defaultValidateStartTime.Add(-2 * time.Second) + c.UpgradeConfig.CortinaTime = defaultValidateStartTime.Add(-2 * time.Second) fallthrough case banff: - c.BanffTime = defaultValidateStartTime.Add(-2 * time.Second) + c.UpgradeConfig.BanffTime = defaultValidateStartTime.Add(-2 * time.Second) fallthrough case apricotPhase5: - c.ApricotPhase5Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase5Time = defaultValidateEndTime fallthrough case apricotPhase3: - c.ApricotPhase3Time = defaultValidateEndTime + c.UpgradeConfig.ApricotPhase3Time = defaultValidateEndTime default: require.FailNow(t, "unhandled fork", f) } diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index 4ae35d80ae03..c05607526841 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -84,7 +84,7 @@ func TestNewImportTx(t *testing.T) { }, ), sourceKeys: []*secp256k1.PrivateKey{sourceKey}, - timestamp: env.config.ApricotPhase5Time, + timestamp: env.config.UpgradeConfig.ApricotPhase5Time, expectedErr: nil, }, { @@ -101,7 +101,7 @@ func TestNewImportTx(t *testing.T) { }, ), sourceKeys: []*secp256k1.PrivateKey{sourceKey}, - timestamp: env.config.ApricotPhase5Time, + timestamp: env.config.UpgradeConfig.ApricotPhase5Time, expectedErr: nil, }, } diff --git a/vms/platformvm/txs/executor/proposal_tx_executor.go b/vms/platformvm/txs/executor/proposal_tx_executor.go index 0f082cb8b296..294e01486a17 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor.go @@ -103,12 +103,12 @@ func (e *ProposalTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error { // activation. Following the activation, AddValidatorTxs must be issued into // StandardBlocks. currentTimestamp := e.OnCommitState.GetTimestamp() - if e.Config.IsBanffActivated(currentTimestamp) { + if e.Config.UpgradeConfig.IsBanffActivated(currentTimestamp) { return fmt.Errorf( "%w: timestamp (%s) >= Banff fork time (%s)", ErrProposedAddStakerTxAfterBanff, currentTimestamp, - e.Config.BanffTime, + e.Config.UpgradeConfig.BanffTime, ) } @@ -150,12 +150,12 @@ func (e *ProposalTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) // activation. Following the activation, AddSubnetValidatorTxs must be // issued into StandardBlocks. currentTimestamp := e.OnCommitState.GetTimestamp() - if e.Config.IsBanffActivated(currentTimestamp) { + if e.Config.UpgradeConfig.IsBanffActivated(currentTimestamp) { return fmt.Errorf( "%w: timestamp (%s) >= Banff fork time (%s)", ErrProposedAddStakerTxAfterBanff, currentTimestamp, - e.Config.BanffTime, + e.Config.UpgradeConfig.BanffTime, ) } @@ -196,12 +196,12 @@ func (e *ProposalTxExecutor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { // activation. Following the activation, AddDelegatorTxs must be issued into // StandardBlocks. currentTimestamp := e.OnCommitState.GetTimestamp() - if e.Config.IsBanffActivated(currentTimestamp) { + if e.Config.UpgradeConfig.IsBanffActivated(currentTimestamp) { return fmt.Errorf( "%w: timestamp (%s) >= Banff fork time (%s)", ErrProposedAddStakerTxAfterBanff, currentTimestamp, - e.Config.BanffTime, + e.Config.UpgradeConfig.BanffTime, ) } @@ -248,12 +248,12 @@ func (e *ProposalTxExecutor) AdvanceTimeTx(tx *txs.AdvanceTimeTx) error { // Validate [newChainTime] newChainTime := tx.Timestamp() - if e.Config.IsBanffActivated(newChainTime) { + if e.Config.UpgradeConfig.IsBanffActivated(newChainTime) { return fmt.Errorf( "%w: proposed timestamp (%s) >= Banff fork time (%s)", ErrAdvanceTimeTxIssuedAfterBanff, newChainTime, - e.Config.BanffTime, + e.Config.UpgradeConfig.BanffTime, ) } @@ -558,7 +558,7 @@ func (e *ProposalTxExecutor) rewardDelegatorTx(uDelegatorTx txs.DelegatorTx, del } // Reward the delegatee here - if e.Config.IsCortinaActivated(validator.StartTime) { + if e.Config.UpgradeConfig.IsCortinaActivated(validator.StartTime) { previousDelegateeReward, err := e.OnCommitState.GetDelegateeReward( validator.SubnetID, validator.NodeID, diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index 6fe0f7831235..87caaca7d7c1 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -235,7 +235,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { t.Run(tt.description, func(t *testing.T) { require := require.New(t) env := newEnvironment(t, apricotPhase5) - env.config.ApricotPhase3Time = tt.AP3Time + env.config.UpgradeConfig.ApricotPhase3Time = tt.AP3Time tx, err := env.txBuilder.NewAddDelegatorTx( &txs.Validator{ diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 893a8a1c3405..befd736a674b 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -97,7 +97,7 @@ func verifyAddValidatorTx( error, ) { currentTimestamp := chainState.GetTimestamp() - if backend.Config.IsDurangoActivated(currentTimestamp) { + if backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { return nil, ErrAddValidatorTxPostDurango } @@ -194,7 +194,7 @@ func verifyAddSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -288,7 +288,7 @@ func verifyRemoveSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return nil, false, err @@ -355,7 +355,7 @@ func verifyAddDelegatorTx( error, ) { currentTimestamp := chainState.GetTimestamp() - if backend.Config.IsDurangoActivated(currentTimestamp) { + if backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { return nil, ErrAddDelegatorTxPostDurango } @@ -413,7 +413,7 @@ func verifyAddDelegatorTx( return nil, ErrStakeOverflow } - if backend.Config.IsApricotPhase3Activated(currentTimestamp) { + if backend.Config.UpgradeConfig.IsApricotPhase3Activated(currentTimestamp) { maximumWeight = min(maximumWeight, backend.Config.MaxValidatorStake) } @@ -472,7 +472,7 @@ func verifyAddPermissionlessValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -594,7 +594,7 @@ func verifyAddPermissionlessDelegatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -737,7 +737,7 @@ func verifyTransferSubnetOwnershipTx( sTx *txs.Tx, tx *txs.TransferSubnetOwnershipTx, ) error { - if !backend.Config.IsDurangoActivated(chainState.GetTimestamp()) { + if !backend.Config.UpgradeConfig.IsDurangoActivated(chainState.GetTimestamp()) { return ErrDurangoUpgradeNotActive } diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index aa3ea9a2aafe..4ee5ced73173 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -56,7 +56,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -107,7 +107,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -147,7 +147,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -233,7 +233,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -418,7 +418,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -541,7 +541,7 @@ func (e *StandardTxExecutor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwn } func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { - if !e.Backend.Config.IsDurangoActivated(e.State.GetTimestamp()) { + if !e.Backend.Config.UpgradeConfig.IsDurangoActivated(e.State.GetTimestamp()) { return ErrDurangoUpgradeNotActive } @@ -585,7 +585,7 @@ func (e *StandardTxExecutor) putStaker(stakerTx txs.Staker) error { err error ) - if !e.Config.IsDurangoActivated(chainTime) { + if !e.Config.UpgradeConfig.IsDurangoActivated(chainTime) { // Pre-Durango, stakers set a future [StartTime] and are added to the // pending staker set. They are promoted to the current staker set once // the chain time reaches [StartTime]. diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index d582e592d52a..28fb5a2404fb 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -31,6 +31,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -70,7 +71,7 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { } for _, test := range tests { // Case: Empty validator node ID after banff - env.config.BanffTime = test.banffTime + env.config.UpgradeConfig.BanffTime = test.banffTime tx, err := env.txBuilder.NewAddValidatorTx( // create the tx &txs.Validator{ @@ -315,7 +316,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { t.Run(tt.description, func(t *testing.T) { require := require.New(t) env := newEnvironment(t, apricotPhase5) - env.config.ApricotPhase3Time = tt.AP3Time + env.config.UpgradeConfig.ApricotPhase3Time = tt.AP3Time tx, err := env.txBuilder.NewAddDelegatorTx( &txs.Validator{ @@ -339,7 +340,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - env.config.BanffTime = onAcceptState.GetTimestamp() + env.config.UpgradeConfig.BanffTime = onAcceptState.GetTimestamp() executor := StandardTxExecutor{ Backend: &env.backend, @@ -2080,32 +2081,34 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { func defaultTestConfig(t *testing.T, f fork, tm time.Time) *config.Config { c := &config.Config{ - ApricotPhase3Time: mockable.MaxTime, - ApricotPhase5Time: mockable.MaxTime, - BanffTime: mockable.MaxTime, - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + ApricotPhase3Time: mockable.MaxTime, + ApricotPhase5Time: mockable.MaxTime, + BanffTime: mockable.MaxTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, } switch f { case eUpgrade: - c.EUpgradeTime = tm + c.UpgradeConfig.EUpgradeTime = tm fallthrough case durango: - c.DurangoTime = tm + c.UpgradeConfig.DurangoTime = tm fallthrough case cortina: - c.CortinaTime = tm + c.UpgradeConfig.CortinaTime = tm fallthrough case banff: - c.BanffTime = tm + c.UpgradeConfig.BanffTime = tm fallthrough case apricotPhase5: - c.ApricotPhase5Time = tm + c.UpgradeConfig.ApricotPhase5Time = tm fallthrough case apricotPhase3: - c.ApricotPhase3Time = tm + c.UpgradeConfig.ApricotPhase3Time = tm default: require.FailNow(t, "unhandled fork", f) } diff --git a/vms/platformvm/upgrade/config.go b/vms/platformvm/upgrade/config.go new file mode 100644 index 000000000000..1d92736a2ee3 --- /dev/null +++ b/vms/platformvm/upgrade/config.go @@ -0,0 +1,50 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package upgrade + +import "time" + +type Config struct { + // Time of the AP3 network upgrade + ApricotPhase3Time time.Time + + // Time of the AP5 network upgrade + ApricotPhase5Time time.Time + + // Time of the Banff network upgrade + BanffTime time.Time + + // Time of the Cortina network upgrade + CortinaTime time.Time + + // Time of the Durango network upgrade + DurangoTime time.Time + + // Time of the E network upgrade + EUpgradeTime time.Time +} + +func (c *Config) IsApricotPhase3Activated(timestamp time.Time) bool { + return !timestamp.Before(c.ApricotPhase3Time) +} + +func (c *Config) IsApricotPhase5Activated(timestamp time.Time) bool { + return !timestamp.Before(c.ApricotPhase5Time) +} + +func (c *Config) IsBanffActivated(timestamp time.Time) bool { + return !timestamp.Before(c.BanffTime) +} + +func (c *Config) IsCortinaActivated(timestamp time.Time) bool { + return !timestamp.Before(c.CortinaTime) +} + +func (c *Config) IsDurangoActivated(timestamp time.Time) bool { + return !timestamp.Before(c.DurangoTime) +} + +func (c *Config) IsEActivated(timestamp time.Time) bool { + return !timestamp.Before(c.EUpgradeTime) +} diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 9effc6fbeeb2..4c1e3ef9fe2c 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -44,6 +44,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" @@ -661,11 +662,13 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - ApricotPhase3Time: forkTime, - ApricotPhase5Time: forkTime, - BanffTime: forkTime, - CortinaTime: forkTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + ApricotPhase3Time: forkTime, + ApricotPhase5Time: forkTime, + BanffTime: forkTime, + CortinaTime: forkTime, + EUpgradeTime: mockable.MaxTime, + }, }} vm.clock.Set(forkTime.Add(time.Second)) diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 0218e115521d..6813919614b8 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -45,6 +45,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" @@ -251,7 +252,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require := require.New(t) vm, txBuilder, _, _ := defaultVM(t, apricotPhase3) - vm.ApricotPhase3Time = test.ap3Time + vm.UpgradeConfig.ApricotPhase3Time = test.ap3Time vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -442,10 +443,12 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: latestForkTime, - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + BanffTime: latestForkTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, }} ctx := snowtest.Context(t, snowtest.PChainID) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index f5be2e5684a4..6f1177ed17f1 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -58,6 +58,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" p2ppb "github.com/ava-labs/avalanchego/proto/pb/p2p" @@ -254,12 +255,14 @@ func defaultVM(t *testing.T, f fork) (*VM, *txstest.Builder, database.Database, MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - ApricotPhase3Time: apricotPhase3Time, - ApricotPhase5Time: apricotPhase5Time, - BanffTime: banffTime, - CortinaTime: cortinaTime, - DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, + UpgradeConfig: upgrade.Config{ + ApricotPhase3Time: apricotPhase3Time, + ApricotPhase5Time: apricotPhase5Time, + BanffTime: banffTime, + CortinaTime: cortinaTime, + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + }, }} db := memdb.New() @@ -1178,10 +1181,12 @@ func TestRestartFullyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} firstCtx := snowtest.Context(t, snowtest.PChainID) @@ -1266,10 +1271,12 @@ func TestRestartFullyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} secondCtx := snowtest.Context(t, snowtest.PChainID) @@ -1315,10 +1322,12 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} initialClkTime := latestForkTime.Add(time.Second) @@ -1662,10 +1671,12 @@ func TestUnverifiedParent(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} initialClkTime := latestForkTime.Add(time.Second) @@ -1823,10 +1834,12 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { RewardConfig: defaultRewardConfig, Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} firstCtx := snowtest.Context(t, snowtest.PChainID) @@ -1872,10 +1885,12 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { UptimePercentage: secondUptimePercentage / 100., Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} secondCtx := snowtest.Context(t, snowtest.PChainID) @@ -1972,10 +1987,12 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { RewardConfig: defaultRewardConfig, Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + UpgradeConfig: upgrade.Config{ + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EUpgradeTime: mockable.MaxTime, + }, }} ctx := snowtest.Context(t, snowtest.PChainID) From 8cbc4e2a4c1edf294569e866bc4679ff78cfb243 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 14 May 2024 14:46:34 +0200 Subject: [PATCH 034/100] simplified fee unit test setup --- vms/platformvm/txs/fee/calculator_test.go | 346 +++------------------- 1 file changed, 40 insertions(+), 306 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index f684b0dd8c23..d5f9ff8be34b 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -10,31 +10,17 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/signer" - "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" -) - -var ( - preFundedKeys = secp256k1.TestKeys() - feeTestDefaultStakeWeight = uint64(2024) ) func TestTxFees(t *testing.T) { type feeTests struct { name string chainTime time.Time - unsignedTx func(t *testing.T) txs.UnsignedTx + unsignedTx func() txs.UnsignedTx expected uint64 } @@ -124,36 +110,36 @@ func TestTxFees(t *testing.T) { { name: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func(t *testing.T) txs.UnsignedTx { - return addPermissionlessValidatorTx(t, constants.PrimaryNetworkID) + unsignedTx: func() txs.UnsignedTx { + return addPermissionlessValidatorTx(constants.PrimaryNetworkID) }, expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, }, { name: "AddPermissionlessValidatorTx Subnet pre EUpgrade", chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func(t *testing.T) txs.UnsignedTx { + unsignedTx: func() txs.UnsignedTx { subnetID := ids.GenerateTestID() require.NotEqual(t, constants.PrimaryNetworkID, subnetID) - return addPermissionlessValidatorTx(t, subnetID) + return addPermissionlessValidatorTx(subnetID) }, expected: feeTestsDefaultCfg.AddSubnetValidatorFee, }, { name: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func(t *testing.T) txs.UnsignedTx { - return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) + unsignedTx: func() txs.UnsignedTx { + return addPermissionlessDelegatorTx(constants.PrimaryNetworkID) }, expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, }, { name: "AddPermissionlessDelegatorTx pre EUpgrade", chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func(t *testing.T) txs.UnsignedTx { + unsignedTx: func() txs.UnsignedTx { subnetID := ids.GenerateTestID() require.NotEqual(t, constants.PrimaryNetworkID, subnetID) - return addPermissionlessDelegatorTx(t, subnetID) + return addPermissionlessDelegatorTx(subnetID) }, expected: feeTestsDefaultCfg.AddSubnetDelegatorFee, }, @@ -178,7 +164,7 @@ func TestTxFees(t *testing.T) { { name: "RewardValidatorTx pre EUpgrade", chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func(_ *testing.T) txs.UnsignedTx { + unsignedTx: func() txs.UnsignedTx { return &txs.RewardValidatorTx{ TxID: ids.GenerateTestID(), } @@ -188,7 +174,7 @@ func TestTxFees(t *testing.T) { { name: "AdvanceTimeTx pre EUpgrade", chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func(_ *testing.T) txs.UnsignedTx { + unsignedTx: func() txs.UnsignedTx { return &txs.AdvanceTimeTx{ Time: uint64(time.Now().Unix()), } @@ -199,317 +185,65 @@ func TestTxFees(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - uTx := tt.unsignedTx(t) + uTx := tt.unsignedTx() fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades) require.Equal(t, tt.expected, fc.CalculateFee(uTx, tt.chainTime)) }) } } -func addValidatorTx(t *testing.T) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, stakes, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.AddValidatorTx{ - BaseTx: baseTx, - Validator: txs.Validator{ - NodeID: defaultCtx.NodeID, - Start: uint64(time.Now().Truncate(time.Second).Unix()), - End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), - Wght: feeTestDefaultStakeWeight, - }, - StakeOuts: stakes, - RewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ids.GenerateTestShortID()}, - }, - DelegationShares: reward.PercentDenominator, - } - return uTx +func addValidatorTx() txs.UnsignedTx { + return &txs.AddValidatorTx{} } -func addSubnetValidatorTx(t *testing.T) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - subnetID := ids.GenerateTestID() - baseTx, _, subnetAuth := txsCreationHelpers(defaultCtx) - uTx := &txs.AddSubnetValidatorTx{ - BaseTx: baseTx, - SubnetValidator: txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: defaultCtx.NodeID, - Start: uint64(time.Now().Truncate(time.Second).Unix()), - End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), - Wght: feeTestDefaultStakeWeight, - }, - Subnet: subnetID, - }, - SubnetAuth: subnetAuth, - } - return uTx +func addSubnetValidatorTx() txs.UnsignedTx { + return &txs.AddSubnetValidatorTx{} } -func addDelegatorTx(t *testing.T) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, stakes, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.AddDelegatorTx{ - BaseTx: baseTx, - Validator: txs.Validator{ - NodeID: defaultCtx.NodeID, - Start: uint64(time.Now().Truncate(time.Second).Unix()), - End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), - Wght: feeTestDefaultStakeWeight, - }, - StakeOuts: stakes, - DelegationRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, - }, - } - return uTx +func addDelegatorTx() txs.UnsignedTx { + return &txs.AddDelegatorTx{} } -func createChainTx(t *testing.T) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, subnetAuth := txsCreationHelpers(defaultCtx) - uTx := &txs.CreateChainTx{ - BaseTx: baseTx, - SubnetID: ids.GenerateTestID(), - ChainName: "testingStuff", - VMID: ids.GenerateTestID(), - FxIDs: []ids.ID{ids.GenerateTestID()}, - GenesisData: []byte{0xff}, - SubnetAuth: subnetAuth, - } - return uTx +func createChainTx() txs.UnsignedTx { + return &txs.CreateChainTx{} } -func createSubnetTx(t *testing.T) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.CreateSubnetTx{ - BaseTx: baseTx, - Owner: &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, - }, - } - return uTx +func createSubnetTx() txs.UnsignedTx { + return &txs.CreateSubnetTx{} } -func removeSubnetValidatorTx(t *testing.T) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, auth := txsCreationHelpers(defaultCtx) - uTx := &txs.RemoveSubnetValidatorTx{ - BaseTx: baseTx, - NodeID: ids.GenerateTestNodeID(), - Subnet: ids.GenerateTestID(), - SubnetAuth: auth, - } - return uTx +func removeSubnetValidatorTx() txs.UnsignedTx { + return &txs.RemoveSubnetValidatorTx{} } -func transformSubnetTx(t *testing.T) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, auth := txsCreationHelpers(defaultCtx) - uTx := &txs.TransformSubnetTx{ - BaseTx: baseTx, - Subnet: ids.GenerateTestID(), - AssetID: ids.GenerateTestID(), - InitialSupply: 0x1000000000000000, - MaximumSupply: 0x1000000000000000, - MinConsumptionRate: 0, - MaxConsumptionRate: 0, - MinValidatorStake: 1, - MaxValidatorStake: 0x1000000000000000, - MinStakeDuration: 1, - MaxStakeDuration: 1, - MinDelegationFee: 0, - MinDelegatorStake: 0xffffffffffffffff, - MaxValidatorWeightFactor: 255, - UptimeRequirement: 0, - SubnetAuth: auth, - } - return uTx +func transformSubnetTx() txs.UnsignedTx { + return &txs.TransformSubnetTx{} } -func transferSubnetOwnershipTx(t *testing.T) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.TransferSubnetOwnershipTx{ - BaseTx: baseTx, - Subnet: ids.GenerateTestID(), - SubnetAuth: &secp256k1fx.Input{ - SigIndices: []uint32{3}, - }, - Owner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - ids.GenerateTestShortID(), - }, - }, - } - return uTx +func transferSubnetOwnershipTx() txs.UnsignedTx { + return &txs.TransferSubnetOwnershipTx{} } -func addPermissionlessValidatorTx(t *testing.T, subnetID ids.ID) txs.UnsignedTx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, stakes, _ := txsCreationHelpers(defaultCtx) - sk, err := bls.NewSecretKey() - r.NoError(err) - uTx := &txs.AddPermissionlessValidatorTx{ - BaseTx: baseTx, - Subnet: subnetID, - Signer: signer.NewProofOfPossession(sk), - StakeOuts: stakes, - ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - ids.GenerateTestShortID(), - }, - }, - DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - ids.GenerateTestShortID(), - }, - }, - DelegationShares: reward.PercentDenominator, +func addPermissionlessValidatorTx(subnetID ids.ID) txs.UnsignedTx { + return &txs.AddPermissionlessValidatorTx{ + Subnet: subnetID, } - return uTx } -func addPermissionlessDelegatorTx(t *testing.T, subnetID ids.ID) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, stakes, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.AddPermissionlessDelegatorTx{ - BaseTx: baseTx, - Validator: txs.Validator{ - NodeID: ids.GenerateTestNodeID(), - Start: 12345, - End: 12345 + 200*24*60*60, - Wght: 2 * units.KiloAvax, - }, - Subnet: subnetID, - StakeOuts: stakes, - DelegationRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - ids.GenerateTestShortID(), - }, - }, +func addPermissionlessDelegatorTx(subnetID ids.ID) txs.UnsignedTx { + return &txs.AddPermissionlessDelegatorTx{ + Subnet: subnetID, } - return uTx } -func baseTx(t *testing.T) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, _ := txsCreationHelpers(defaultCtx) - uTx := &baseTx - return uTx -} - -func importTx(t *testing.T) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.ImportTx{ - BaseTx: baseTx, - SourceChain: ids.GenerateTestID(), - ImportedInputs: []*avax.TransferableInput{{ - UTXOID: avax.UTXOID{ - TxID: ids.Empty.Prefix(1), - OutputIndex: 1, - }, - Asset: avax.Asset{ID: ids.ID{'a', 's', 's', 'e', 'r', 't'}}, - In: &secp256k1fx.TransferInput{ - Amt: 50000, - Input: secp256k1fx.Input{SigIndices: []uint32{0}}, - }, - }}, - } - return uTx +func baseTx() txs.UnsignedTx { + return &txs.BaseTx{} } -func exportTx(t *testing.T) txs.UnsignedTx { - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, outputs, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.ExportTx{ - BaseTx: baseTx, - DestinationChain: ids.GenerateTestID(), - ExportedOutputs: outputs, - } - return uTx +func importTx() txs.UnsignedTx { + return &txs.ImportTx{} } -func txsCreationHelpers(defaultCtx *snow.Context) ( - baseTx txs.BaseTx, - stakes []*avax.TransferableOutput, - auth *secp256k1fx.Input, -) { - inputs := []*avax.TransferableInput{{ - UTXOID: avax.UTXOID{ - TxID: ids.ID{'t', 'x', 'I', 'D'}, - OutputIndex: 2, - }, - Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, - In: &secp256k1fx.TransferInput{ - Amt: uint64(5678), - Input: secp256k1fx.Input{SigIndices: []uint32{0}}, - }, - }} - outputs := []*avax.TransferableOutput{{ - Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: uint64(1234), - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, - }, - }, - }} - stakes = []*avax.TransferableOutput{{ - Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, - Out: &stakeable.LockOut{ - Locktime: uint64(time.Now().Add(time.Second).Unix()), - TransferableOut: &secp256k1fx.TransferOutput{ - Amt: feeTestDefaultStakeWeight, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, - }, - }, - }, - }} - auth = &secp256k1fx.Input{ - SigIndices: []uint32{0, 1}, - } - baseTx = txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: defaultCtx.NetworkID, - BlockchainID: defaultCtx.ChainID, - Ins: inputs, - Outs: outputs, - }, - } - - return baseTx, stakes, auth +func exportTx() txs.UnsignedTx { + return &txs.ExportTx{} } From 88523768ce01ec5f6aa5cc2601d903d96698dc6c Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 14 May 2024 23:16:10 +0200 Subject: [PATCH 035/100] nits --- vms/platformvm/txs/fee/calculator_test.go | 44 ++++++++++++----------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index d5f9ff8be34b..c25fec9073e8 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -17,13 +17,6 @@ import ( ) func TestTxFees(t *testing.T) { - type feeTests struct { - name string - chainTime time.Time - unsignedTx func() txs.UnsignedTx - expected uint64 - } - feeTestsDefaultCfg := StaticConfig{ TxFee: 1 * units.Avax, CreateAssetTxFee: 2 * units.Avax, @@ -46,64 +39,73 @@ func TestTxFees(t *testing.T) { ApricotPhase3Time: latestForkTime.Add(-5 * time.Hour), } - tests := []feeTests{ + // chain times needed to have specific upgrades active + preEUpgradeTime := upgrades.EUpgradeTime.Add(-1 * time.Second) + preApricotPhase3Time := upgrades.ApricotPhase3Time.Add(-1 * time.Second) + + tests := []struct { + name string + chainTime time.Time + unsignedTx func() txs.UnsignedTx + expected uint64 + }{ { name: "AddValidatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + chainTime: preEUpgradeTime, unsignedTx: addValidatorTx, expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, }, { name: "AddSubnetValidatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + chainTime: preEUpgradeTime, unsignedTx: addSubnetValidatorTx, expected: feeTestsDefaultCfg.AddSubnetValidatorFee, }, { name: "AddDelegatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + chainTime: preEUpgradeTime, unsignedTx: addDelegatorTx, expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, }, { name: "CreateChainTx pre ApricotPhase3", - chainTime: upgrades.ApricotPhase3Time.Add(-1 * time.Second), + chainTime: preApricotPhase3Time, unsignedTx: createChainTx, expected: feeTestsDefaultCfg.CreateAssetTxFee, }, { name: "CreateChainTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + chainTime: preEUpgradeTime, unsignedTx: createChainTx, expected: feeTestsDefaultCfg.CreateBlockchainTxFee, }, { name: "CreateSubnetTx pre ApricotPhase3", - chainTime: upgrades.ApricotPhase3Time.Add(-1 * time.Second), + chainTime: preApricotPhase3Time, unsignedTx: createSubnetTx, expected: feeTestsDefaultCfg.CreateAssetTxFee, }, { name: "CreateSubnetTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + chainTime: preEUpgradeTime, unsignedTx: createSubnetTx, expected: feeTestsDefaultCfg.CreateSubnetTxFee, }, { name: "RemoveSubnetValidatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + chainTime: preEUpgradeTime, unsignedTx: removeSubnetValidatorTx, expected: feeTestsDefaultCfg.TxFee, }, { name: "TransformSubnetTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + chainTime: preEUpgradeTime, unsignedTx: transformSubnetTx, expected: feeTestsDefaultCfg.TransformSubnetTxFee, }, { name: "TransferSubnetOwnershipTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + chainTime: preEUpgradeTime, unsignedTx: transferSubnetOwnershipTx, expected: feeTestsDefaultCfg.TxFee, }, @@ -145,19 +147,19 @@ func TestTxFees(t *testing.T) { }, { name: "BaseTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + chainTime: preEUpgradeTime, unsignedTx: baseTx, expected: feeTestsDefaultCfg.TxFee, }, { name: "ImportTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + chainTime: preEUpgradeTime, unsignedTx: importTx, expected: feeTestsDefaultCfg.TxFee, }, { name: "ExportTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + chainTime: preEUpgradeTime, unsignedTx: exportTx, expected: feeTestsDefaultCfg.TxFee, }, From 10176c94e955d9cc3d97d6913265e5ef44b69673 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 15 May 2024 09:31:00 +0200 Subject: [PATCH 036/100] nit --- vms/platformvm/txs/executor/staker_tx_verification.go | 1 - 1 file changed, 1 deletion(-) diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index c5dd1811daa1..0aac4ad50f64 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -719,7 +719,6 @@ func verifyAddPermissionlessDelegatorTx( feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) fee := feeCalculator.CalculateFee(tx, currentTimestamp) - // Verify the flowcheck if err := backend.FlowChecker.VerifySpend( tx, chainState, From c815178d6229c2e184c1f2e1465dc0dc6eefe0b4 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 16 May 2024 10:05:45 +0200 Subject: [PATCH 037/100] nit --- vms/platformvm/txs/fee/calculator.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index fbb996c3a50c..79ff3fe2e9a7 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -26,7 +26,7 @@ type Calculator struct { } // [CalculateFee] returns the minimal fee needed to accept [tx], at chain time [time] -func (c Calculator) CalculateFee(tx txs.UnsignedTx, time time.Time) uint64 { +func (c *Calculator) CalculateFee(tx txs.UnsignedTx, time time.Time) uint64 { tmp := &calculator{ upgrades: c.upgradeTimes, staticCfg: c.config, @@ -84,13 +84,13 @@ func (c *calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { } func (c *calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - c.fee = 0 - return nil // no fees + c.fee = 0 // no fees + return nil } func (c *calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { - c.fee = 0 - return nil // no fees + c.fee = 0 // no fees + return nil } func (c *calculator) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { From eee5aba7edda7967631e2cff05fc18aee046f692 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 20 May 2024 09:54:03 -0400 Subject: [PATCH 038/100] drop duplicated fields --- vms/platformvm/txs/fee/static_config.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/vms/platformvm/txs/fee/static_config.go b/vms/platformvm/txs/fee/static_config.go index 12899b315b32..e0d70ef89613 100644 --- a/vms/platformvm/txs/fee/static_config.go +++ b/vms/platformvm/txs/fee/static_config.go @@ -30,16 +30,4 @@ type StaticConfig struct { // Transaction fee for adding a subnet delegator AddSubnetDelegatorFee uint64 - - // The minimum amount of tokens one must bond to be a validator - MinValidatorStake uint64 - - // The maximum amount of tokens that can be bonded on a validator - MaxValidatorStake uint64 - - // Minimum stake, in nAVAX, that can be delegated on the primary network - MinDelegatorStake uint64 - - // Minimum fee that can be charged for delegation - MinDelegationFee uint32 } From be373e2df172bcb0b07b8b9746a77320fc8bcce3 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 20 May 2024 10:04:10 -0400 Subject: [PATCH 039/100] replaced genesis.TxFeeConfig with fee.StaticConfig --- config/config.go | 7 ++--- genesis/genesis_fuji.go | 3 ++- genesis/genesis_local.go | 3 ++- genesis/genesis_mainnet.go | 3 ++- genesis/params.go | 34 +++++-------------------- node/config.go | 15 ++++++----- vms/platformvm/txs/fee/static_config.go | 18 ++++++------- 7 files changed, 34 insertions(+), 49 deletions(-) diff --git a/config/config.go b/config/config.go index 760c0022b123..4cc327240637 100644 --- a/config/config.go +++ b/config/config.go @@ -45,6 +45,7 @@ import ( "github.com/ava-labs/avalanchego/utils/timer" "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/proposervm" ) @@ -758,9 +759,9 @@ func getStakingConfig(v *viper.Viper, networkID uint32) (node.StakingConfig, err return config, nil } -func getTxFeeConfig(v *viper.Viper, networkID uint32) genesis.TxFeeConfig { +func getTxFeeConfig(v *viper.Viper, networkID uint32) fee.StaticConfig { if networkID != constants.MainnetID && networkID != constants.FujiID { - return genesis.TxFeeConfig{ + return fee.StaticConfig{ TxFee: v.GetUint64(TxFeeKey), CreateAssetTxFee: v.GetUint64(CreateAssetTxFeeKey), CreateSubnetTxFee: v.GetUint64(CreateSubnetTxFeeKey), @@ -1325,7 +1326,7 @@ func GetNodeConfig(v *viper.Viper) (node.Config, error) { nodeConfig.FdLimit = v.GetUint64(FdLimitKey) // Tx Fee - nodeConfig.TxFeeConfig = getTxFeeConfig(v, nodeConfig.NetworkID) + nodeConfig.StaticConfig = getTxFeeConfig(v, nodeConfig.NetworkID) // Genesis Data genesisStakingCfg := nodeConfig.StakingConfig.StakingConfig diff --git a/genesis/genesis_fuji.go b/genesis/genesis_fuji.go index 27c43f79fd0b..06cd2dd143ac 100644 --- a/genesis/genesis_fuji.go +++ b/genesis/genesis_fuji.go @@ -10,6 +10,7 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) var ( @@ -18,7 +19,7 @@ var ( // FujiParams are the params used for the fuji testnet FujiParams = Params{ - TxFeeConfig: TxFeeConfig{ + StaticConfig: fee.StaticConfig{ TxFee: units.MilliAvax, CreateAssetTxFee: 10 * units.MilliAvax, CreateSubnetTxFee: 100 * units.MilliAvax, diff --git a/genesis/genesis_local.go b/genesis/genesis_local.go index 5a76aa25cfcf..72f180ce3445 100644 --- a/genesis/genesis_local.go +++ b/genesis/genesis_local.go @@ -13,6 +13,7 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) // PrivateKey-vmRQiZeXEXYMyJhEiqdC2z5JhuDbxL8ix9UVvjgMu2Er1NepE => P-local1g65uqn6t77p656w64023nh8nd9updzmxyymev2 @@ -36,7 +37,7 @@ var ( // LocalParams are the params used for local networks LocalParams = Params{ - TxFeeConfig: TxFeeConfig{ + StaticConfig: fee.StaticConfig{ TxFee: units.MilliAvax, CreateAssetTxFee: units.MilliAvax, CreateSubnetTxFee: 100 * units.MilliAvax, diff --git a/genesis/genesis_mainnet.go b/genesis/genesis_mainnet.go index 3808174ebbd1..94eae11cb2c8 100644 --- a/genesis/genesis_mainnet.go +++ b/genesis/genesis_mainnet.go @@ -10,6 +10,7 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) var ( @@ -18,7 +19,7 @@ var ( // MainnetParams are the params used for mainnet MainnetParams = Params{ - TxFeeConfig: TxFeeConfig{ + StaticConfig: fee.StaticConfig{ TxFee: units.MilliAvax, CreateAssetTxFee: 10 * units.MilliAvax, CreateSubnetTxFee: 1 * units.Avax, diff --git a/genesis/params.go b/genesis/params.go index e2ae45c697e6..6d4f5f4d978f 100644 --- a/genesis/params.go +++ b/genesis/params.go @@ -8,6 +8,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) type StakingConfig struct { @@ -33,42 +34,21 @@ type StakingConfig struct { RewardConfig reward.Config `json:"rewardConfig"` } -type TxFeeConfig struct { - // Transaction fee - TxFee uint64 `json:"txFee"` - // Transaction fee for create asset transactions - CreateAssetTxFee uint64 `json:"createAssetTxFee"` - // Transaction fee for create subnet transactions - CreateSubnetTxFee uint64 `json:"createSubnetTxFee"` - // Transaction fee for transform subnet transactions - TransformSubnetTxFee uint64 `json:"transformSubnetTxFee"` - // Transaction fee for create blockchain transactions - CreateBlockchainTxFee uint64 `json:"createBlockchainTxFee"` - // Transaction fee for adding a primary network validator - AddPrimaryNetworkValidatorFee uint64 `json:"addPrimaryNetworkValidatorFee"` - // Transaction fee for adding a primary network delegator - AddPrimaryNetworkDelegatorFee uint64 `json:"addPrimaryNetworkDelegatorFee"` - // Transaction fee for adding a subnet validator - AddSubnetValidatorFee uint64 `json:"addSubnetValidatorFee"` - // Transaction fee for adding a subnet delegator - AddSubnetDelegatorFee uint64 `json:"addSubnetDelegatorFee"` -} - type Params struct { StakingConfig - TxFeeConfig + fee.StaticConfig } -func GetTxFeeConfig(networkID uint32) TxFeeConfig { +func GetTxFeeConfig(networkID uint32) fee.StaticConfig { switch networkID { case constants.MainnetID: - return MainnetParams.TxFeeConfig + return MainnetParams.StaticConfig case constants.FujiID: - return FujiParams.TxFeeConfig + return FujiParams.StaticConfig case constants.LocalID: - return LocalParams.TxFeeConfig + return LocalParams.StaticConfig default: - return LocalParams.TxFeeConfig + return LocalParams.StaticConfig } } diff --git a/node/config.go b/node/config.go index 716b9a32c90a..f5f8c1332530 100644 --- a/node/config.go +++ b/node/config.go @@ -23,6 +23,7 @@ import ( "github.com/ava-labs/avalanchego/utils/profiler" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) type APIIndexerConfig struct { @@ -122,13 +123,13 @@ type DatabaseConfig struct { // Config contains all of the configurations of an Avalanche node. type Config struct { - HTTPConfig `json:"httpConfig"` - IPConfig `json:"ipConfig"` - StakingConfig `json:"stakingConfig"` - genesis.TxFeeConfig `json:"txFeeConfig"` - StateSyncConfig `json:"stateSyncConfig"` - BootstrapConfig `json:"bootstrapConfig"` - DatabaseConfig `json:"databaseConfig"` + HTTPConfig `json:"httpConfig"` + IPConfig `json:"ipConfig"` + StakingConfig `json:"stakingConfig"` + fee.StaticConfig `json:"txFeeConfig"` + StateSyncConfig `json:"stateSyncConfig"` + BootstrapConfig `json:"bootstrapConfig"` + DatabaseConfig `json:"databaseConfig"` // Genesis information GenesisBytes []byte `json:"-"` diff --git a/vms/platformvm/txs/fee/static_config.go b/vms/platformvm/txs/fee/static_config.go index e0d70ef89613..e03fb701806a 100644 --- a/vms/platformvm/txs/fee/static_config.go +++ b/vms/platformvm/txs/fee/static_config.go @@ -5,29 +5,29 @@ package fee type StaticConfig struct { // Fee that is burned by every non-state creating transaction - TxFee uint64 + TxFee uint64 `json:"txFee"` // Fee that must be burned by every state creating transaction before AP3 - CreateAssetTxFee uint64 + CreateAssetTxFee uint64 `json:"createAssetTxFee"` // Fee that must be burned by every subnet creating transaction after AP3 - CreateSubnetTxFee uint64 + CreateSubnetTxFee uint64 `json:"createSubnetTxFee"` // Fee that must be burned by every transform subnet transaction - TransformSubnetTxFee uint64 + TransformSubnetTxFee uint64 `json:"transformSubnetTxFee"` // Fee that must be burned by every blockchain creating transaction after AP3 - CreateBlockchainTxFee uint64 + CreateBlockchainTxFee uint64 `json:"createBlockchainTxFee"` // Transaction fee for adding a primary network validator - AddPrimaryNetworkValidatorFee uint64 + AddPrimaryNetworkValidatorFee uint64 `json:"addPrimaryNetworkValidatorFee"` // Transaction fee for adding a primary network delegator - AddPrimaryNetworkDelegatorFee uint64 + AddPrimaryNetworkDelegatorFee uint64 `json:"addPrimaryNetworkDelegatorFee"` // Transaction fee for adding a subnet validator - AddSubnetValidatorFee uint64 + AddSubnetValidatorFee uint64 `json:"addSubnetValidatorFee"` // Transaction fee for adding a subnet delegator - AddSubnetDelegatorFee uint64 + AddSubnetDelegatorFee uint64 `json:"addSubnetDelegatorFee"` } From 34631c6a068e280b34a53261bcbe0ac5efcf28ae Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 20 May 2024 14:03:14 -0400 Subject: [PATCH 040/100] moved FeeCalculator instatiation to block level --- vms/platformvm/block/builder/builder.go | 10 +- vms/platformvm/block/builder/helpers_test.go | 8 +- vms/platformvm/block/executor/helpers_test.go | 8 +- vms/platformvm/block/executor/manager.go | 9 +- vms/platformvm/block/executor/verifier.go | 12 +- .../txs/executor/advance_time_test.go | 23 ++ .../txs/executor/atomic_tx_executor.go | 9 +- .../txs/executor/create_chain_test.go | 41 ++- .../txs/executor/create_subnet_test.go | 9 +- vms/platformvm/txs/executor/export_test.go | 9 +- vms/platformvm/txs/executor/helpers_test.go | 8 +- vms/platformvm/txs/executor/import_test.go | 9 +- .../txs/executor/proposal_tx_executor.go | 7 +- .../txs/executor/proposal_tx_executor_test.go | 33 ++ .../txs/executor/reward_validator_test.go | 19 ++ .../txs/executor/staker_tx_verification.go | 14 +- .../executor/staker_tx_verification_test.go | 12 +- .../txs/executor/standard_tx_executor.go | 30 +- .../txs/executor/standard_tx_executor_test.go | 296 ++++++++++++------ vms/platformvm/txs/fee/calculator.go | 4 +- 20 files changed, 394 insertions(+), 176 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 1a7f2f0556e6..74cf20387241 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -22,6 +22,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" @@ -332,6 +333,8 @@ func packBlockTxs( } var ( + feeCalculator = fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) + blockTxs []*txs.Tx inputs set.Set[ids.ID] ) @@ -355,9 +358,10 @@ func packBlockTxs( } executor := &txexecutor.StandardTxExecutor{ - Backend: backend, - State: txDiff, - Tx: tx, + Backend: backend, + State: txDiff, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(executor) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 0108162649d6..cdb69045f0bb 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -264,10 +264,12 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(genesisID, env.blkManager) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) executor := txexecutor.StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: testSubnet1, + Backend: &env.backend, + State: stateDiff, + FeeCalculator: feeCalculator, + Tx: testSubnet1, } require.NoError(testSubnet1.Unsigned.Visit(&executor)) diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index d87b67c76d25..99b45e815307 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -279,10 +279,12 @@ func addSubnet(env *environment) { panic(err) } + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) executor := executor.StandardTxExecutor{ - Backend: env.backend, - State: stateDiff, - Tx: testSubnet1, + Backend: env.backend, + State: stateDiff, + FeeCalculator: feeCalculator, + Tx: testSubnet1, } err = testSubnet1.Unsigned.Visit(&executor) if err != nil { diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index ecc07f579815..31dc4d468dca 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -14,6 +14,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" "github.com/ava-labs/avalanchego/vms/platformvm/validators" ) @@ -142,10 +143,12 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } + feeCalculator := fee.NewStaticCalculator(m.txExecutorBackend.Config.StaticFeeConfig, m.txExecutorBackend.Config.UpgradeConfig) return tx.Unsigned.Visit(&executor.StandardTxExecutor{ - Backend: m.txExecutorBackend, - State: stateDiff, - Tx: tx, + Backend: m.txExecutorBackend, + State: stateDiff, + FeeCalculator: feeCalculator, + Tx: tx, }) } diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index c56abc45e3c1..275eb2238e15 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -15,6 +15,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) var ( @@ -360,10 +361,12 @@ func (v *verifier) proposalBlock( atomicRequests map[ids.ID]*atomic.Requests, onAcceptFunc func(), ) error { + feeCalculator := fee.NewStaticCalculator(v.txExecutorBackend.Config.StaticFeeConfig, v.txExecutorBackend.Config.UpgradeConfig) txExecutor := executor.ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: v.txExecutorBackend, + FeeCalculator: feeCalculator, Tx: b.Tx, } @@ -433,6 +436,8 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID error, ) { var ( + feeCalculator = fee.NewStaticCalculator(v.txExecutorBackend.Config.StaticFeeConfig, v.txExecutorBackend.Config.UpgradeConfig) + onAcceptFunc func() inputs set.Set[ids.ID] funcs = make([]func(), 0, len(txs)) @@ -440,9 +445,10 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID ) for _, tx := range txs { txExecutor := executor.StandardTxExecutor{ - Backend: v.txExecutorBackend, - State: state, - Tx: tx, + Backend: v.txExecutorBackend, + State: state, + FeeCalculator: feeCalculator, + Tx: tx, } if err := tx.Unsigned.Visit(&txExecutor); err != nil { txID := tx.ID() diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index 755cbb3b2beb..e246ff4f77fd 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -63,10 +64,12 @@ func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) @@ -109,10 +112,12 @@ func TestAdvanceTimeTxTimestampTooEarly(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -144,10 +149,12 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -173,10 +180,12 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -413,10 +422,12 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) @@ -543,10 +554,12 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) @@ -620,10 +633,12 @@ func TestTrackedSubnet(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) @@ -668,10 +683,12 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) @@ -733,6 +750,7 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) @@ -771,10 +789,12 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) @@ -831,6 +851,7 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) @@ -866,10 +887,12 @@ func TestAdvanceTimeTxAfterBanff(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) diff --git a/vms/platformvm/txs/executor/atomic_tx_executor.go b/vms/platformvm/txs/executor/atomic_tx_executor.go index 2a35cb45eeab..b71ee96d7f58 100644 --- a/vms/platformvm/txs/executor/atomic_tx_executor.go +++ b/vms/platformvm/txs/executor/atomic_tx_executor.go @@ -9,6 +9,7 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) var _ txs.Visitor = (*AtomicTxExecutor)(nil) @@ -98,10 +99,12 @@ func (e *AtomicTxExecutor) atomicTx(tx txs.UnsignedTx) error { } e.OnAccept = onAccept + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: e.Backend, - State: e.OnAccept, - Tx: e.Tx, + Backend: e.Backend, + State: e.OnAccept, + FeeCalculator: feeCalculator, + Tx: e.Tx, } err = tx.Visit(&executor) e.Inputs = executor.Inputs diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 346c8ab1468a..ccf09bbc23b5 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -46,10 +47,12 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + FeeCalculator: feeCalculator, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -84,10 +87,12 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + FeeCalculator: feeCalculator, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -116,10 +121,12 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + FeeCalculator: feeCalculator, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, database.ErrNotFound) @@ -145,10 +152,12 @@ func TestCreateChainTxValid(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + FeeCalculator: feeCalculator, + State: stateDiff, + Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) } @@ -212,10 +221,12 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + FeeCalculator: feeCalculator, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, test.expectedError) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index c1902dd56625..ed55bf5a743f 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -13,6 +13,7 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/state" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -75,10 +76,12 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + FeeCalculator: feeCalculator, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, test.expectedErr) diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index 7959791187db..bc3b44c37b6c 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -13,6 +13,7 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/state" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -72,10 +73,12 @@ func TestNewExportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) verifier := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + FeeCalculator: feeCalculator, + State: stateDiff, + Tx: tx, } require.NoError(tx.Unsigned.Visit(&verifier)) }) diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 74c706227fea..b6a206838c7c 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -232,10 +232,12 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: testSubnet1, + Backend: &env.backend, + FeeCalculator: feeCalculator, + State: stateDiff, + Tx: testSubnet1, } require.NoError(testSubnet1.Unsigned.Visit(&executor)) diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index 7bb0be9afcc1..f2cfdf05b9b1 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) @@ -155,10 +156,12 @@ func TestNewImportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) verifier := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + FeeCalculator: feeCalculator, + State: stateDiff, + Tx: tx, } require.NoError(tx.Unsigned.Visit(&verifier)) }) diff --git a/vms/platformvm/txs/executor/proposal_tx_executor.go b/vms/platformvm/txs/executor/proposal_tx_executor.go index 294e01486a17..b5f195ef5d24 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor.go @@ -16,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) const ( @@ -45,7 +46,8 @@ var ( type ProposalTxExecutor struct { // inputs, to be filled before visitor methods are called *Backend - Tx *txs.Tx + FeeCalculator *fee.Calculator + Tx *txs.Tx // [OnCommitState] is the state used for validation. // [OnCommitState] is modified by this struct's methods to // reflect changes made to the state if the proposal is committed. @@ -114,6 +116,7 @@ func (e *ProposalTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error { onAbortOuts, err := verifyAddValidatorTx( e.Backend, + e.FeeCalculator, e.OnCommitState, e.Tx, tx, @@ -161,6 +164,7 @@ func (e *ProposalTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) if err := verifyAddSubnetValidatorTx( e.Backend, + e.FeeCalculator, e.OnCommitState, e.Tx, tx, @@ -207,6 +211,7 @@ func (e *ProposalTxExecutor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { onAbortOuts, err := verifyAddDelegatorTx( e.Backend, + e.FeeCalculator, e.OnCommitState, e.Tx, tx, diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index 87caaca7d7c1..e92556cde575 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -262,10 +263,12 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -305,10 +308,12 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -340,10 +345,12 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) @@ -393,10 +400,12 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -443,10 +452,12 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -476,10 +487,12 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -509,10 +522,12 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) @@ -544,10 +559,12 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -609,10 +626,12 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: duplicateSubnetTx, } err = duplicateSubnetTx.Unsigned.Visit(&executor) @@ -652,10 +671,12 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -689,10 +710,12 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -736,10 +759,12 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -780,10 +805,12 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -816,10 +843,12 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -866,10 +895,12 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) @@ -908,10 +939,12 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&executor) diff --git a/vms/platformvm/txs/executor/reward_validator_test.go b/vms/platformvm/txs/executor/reward_validator_test.go index 215e9a6f729a..ca736383d443 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -59,10 +60,12 @@ func TestRewardValidatorTxExecuteOnCommit(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&txExecutor) @@ -85,6 +88,7 @@ func TestRewardValidatorTxExecuteOnCommit(t *testing.T) { OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&txExecutor) @@ -104,6 +108,7 @@ func TestRewardValidatorTxExecuteOnCommit(t *testing.T) { OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&txExecutor)) @@ -159,10 +164,12 @@ func TestRewardValidatorTxExecuteOnAbort(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&txExecutor) @@ -179,6 +186,7 @@ func TestRewardValidatorTxExecuteOnAbort(t *testing.T) { OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } err = tx.Unsigned.Visit(&txExecutor) @@ -198,6 +206,7 @@ func TestRewardValidatorTxExecuteOnAbort(t *testing.T) { OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&txExecutor)) @@ -312,10 +321,12 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&txExecutor)) @@ -452,10 +463,12 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&txExecutor)) @@ -504,6 +517,7 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&txExecutor)) @@ -672,10 +686,12 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * delOnAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) txExecutor := ProposalTxExecutor{ OnCommitState: delOnCommitState, OnAbortState: delOnAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&txExecutor)) @@ -697,6 +713,7 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * OnCommitState: vdrOnCommitState, OnAbortState: vdrOnAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&txExecutor)) @@ -830,10 +847,12 @@ func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, Backend: &env.backend, + FeeCalculator: feeCalculator, Tx: tx, } require.NoError(tx.Unsigned.Visit(&txExecutor)) diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 0aac4ad50f64..e8c76b1f6f7e 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -90,6 +90,7 @@ func verifySubnetValidatorPrimaryNetworkRequirements( // added to the staking set. func verifyAddValidatorTx( backend *Backend, + feeCalculator *fee.Calculator, chainState state.Chain, sTx *txs.Tx, tx *txs.AddValidatorTx, @@ -164,7 +165,6 @@ func verifyAddValidatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( @@ -187,6 +187,7 @@ func verifyAddValidatorTx( // AddSubnetValidatorTx. func verifyAddSubnetValidatorTx( backend *Backend, + feeCalculator *fee.Calculator, chainState state.Chain, sTx *txs.Tx, tx *txs.AddSubnetValidatorTx, @@ -255,7 +256,6 @@ func verifyAddSubnetValidatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( @@ -284,6 +284,7 @@ func verifyAddSubnetValidatorTx( // * The flow checker passes. func verifyRemoveSubnetValidatorTx( backend *Backend, + feeCalculator *fee.Calculator, chainState state.Chain, sTx *txs.Tx, tx *txs.RemoveSubnetValidatorTx, @@ -333,7 +334,6 @@ func verifyRemoveSubnetValidatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( @@ -357,6 +357,7 @@ func verifyRemoveSubnetValidatorTx( // added to the staking set. func verifyAddDelegatorTx( backend *Backend, + feeCalculator *fee.Calculator, chainState state.Chain, sTx *txs.Tx, tx *txs.AddDelegatorTx, @@ -451,7 +452,6 @@ func verifyAddDelegatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( @@ -474,6 +474,7 @@ func verifyAddDelegatorTx( // AddPermissionlessValidatorTx. func verifyAddPermissionlessValidatorTx( backend *Backend, + feeCalculator *fee.Calculator, chainState state.Chain, sTx *txs.Tx, tx *txs.AddPermissionlessValidatorTx, @@ -571,7 +572,6 @@ func verifyAddPermissionlessValidatorTx( copy(outs[len(tx.Outs):], tx.StakeOuts) // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( @@ -594,6 +594,7 @@ func verifyAddPermissionlessValidatorTx( // AddPermissionlessDelegatorTx. func verifyAddPermissionlessDelegatorTx( backend *Backend, + feeCalculator *fee.Calculator, chainState state.Chain, sTx *txs.Tx, tx *txs.AddPermissionlessDelegatorTx, @@ -716,7 +717,6 @@ func verifyAddPermissionlessDelegatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( @@ -742,6 +742,7 @@ func verifyAddPermissionlessDelegatorTx( // * The flow checker passes. func verifyTransferSubnetOwnershipTx( backend *Backend, + feeCalculator *fee.Calculator, chainState state.Chain, sTx *txs.Tx, tx *txs.TransferSubnetOwnershipTx, @@ -771,7 +772,6 @@ func verifyTransferSubnetOwnershipTx( // Verify the flowcheck currentTimestamp := chainState.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) fee := feeCalculator.CalculateFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index bde3da64ad7a..f60cae17a864 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -22,6 +22,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -505,13 +506,14 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { ctrl := gomock.NewController(t) var ( - backend = tt.backendF(ctrl) - state = tt.stateF(ctrl) - sTx = tt.sTxF() - tx = tt.txF() + backend = tt.backendF(ctrl) + state = tt.stateF(ctrl) + sTx = tt.sTxF() + tx = tt.txF() + feeCalculator = fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) ) - err := verifyAddPermissionlessValidatorTx(backend, state, sTx, tx) + err := verifyAddPermissionlessValidatorTx(backend, feeCalculator, state, sTx, tx) require.ErrorIs(t, err, tt.expectedErr) }) } diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 725f1aaff814..40057d011fad 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -33,8 +33,9 @@ var ( type StandardTxExecutor struct { // inputs, to be filled before visitor methods are called *Backend - State state.Diff // state is expected to be modified - Tx *txs.Tx + State state.Diff // state is expected to be modified + FeeCalculator *fee.Calculator + Tx *txs.Tx // outputs of visitor execution OnAccept func() // may be nil @@ -69,8 +70,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) + fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, @@ -117,8 +117,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) + fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, @@ -200,8 +199,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) + fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpendUTXOs( tx, @@ -259,8 +257,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) + fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, @@ -326,6 +323,7 @@ func (e *StandardTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error { if _, err := verifyAddValidatorTx( e.Backend, + e.FeeCalculator, e.State, e.Tx, tx, @@ -355,6 +353,7 @@ func (e *StandardTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error { func (e *StandardTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { if err := verifyAddSubnetValidatorTx( e.Backend, + e.FeeCalculator, e.State, e.Tx, tx, @@ -375,6 +374,7 @@ func (e *StandardTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) func (e *StandardTxExecutor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { if _, err := verifyAddDelegatorTx( e.Backend, + e.FeeCalculator, e.State, e.Tx, tx, @@ -400,6 +400,7 @@ func (e *StandardTxExecutor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { func (e *StandardTxExecutor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { staker, isCurrentValidator, err := verifyRemoveSubnetValidatorTx( e.Backend, + e.FeeCalculator, e.State, e.Tx, tx, @@ -448,8 +449,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) + fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) totalRewardAmount := tx.MaximumSupply - tx.InitialSupply if err := e.Backend.FlowChecker.VerifySpend( @@ -484,6 +484,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error func (e *StandardTxExecutor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { if err := verifyAddPermissionlessValidatorTx( e.Backend, + e.FeeCalculator, e.State, e.Tx, tx, @@ -516,6 +517,7 @@ func (e *StandardTxExecutor) AddPermissionlessValidatorTx(tx *txs.AddPermissionl func (e *StandardTxExecutor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { if err := verifyAddPermissionlessDelegatorTx( e.Backend, + e.FeeCalculator, e.State, e.Tx, tx, @@ -540,6 +542,7 @@ func (e *StandardTxExecutor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionl func (e *StandardTxExecutor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { err := verifyTransferSubnetOwnershipTx( e.Backend, + e.FeeCalculator, e.State, e.Tx, tx, @@ -572,8 +575,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { // Verify the flowcheck currentTimestamp := e.State.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) + fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index de69b0ff5a8c..3cec25db7c1c 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -32,6 +32,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -93,10 +94,12 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + State: stateDiff, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, test.expectedError) @@ -343,10 +346,12 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { env.config.UpgradeConfig.BanffTime = onAcceptState.GetTimestamp() + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, tt.expectedExecutionErr) @@ -384,10 +389,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrPeriodMismatch) @@ -415,10 +422,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) } @@ -464,10 +473,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrNotValidator) @@ -510,10 +521,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrPeriodMismatch) @@ -539,10 +552,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrPeriodMismatch) @@ -567,10 +582,13 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) } @@ -598,10 +616,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrTimestampNotBeforeStartTime) @@ -660,10 +680,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: duplicateSubnetTx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: duplicateSubnetTx, } err = duplicateSubnetTx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrDuplicateValidator) @@ -700,10 +722,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, secp256k1fx.ErrInputIndicesNotSortedUnique) @@ -736,10 +760,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -770,10 +796,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -814,10 +842,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrDuplicateValidator) @@ -853,10 +883,12 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrTimestampNotBeforeStartTime) @@ -896,10 +928,12 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutCurrentValidator(staker) onAcceptState.AddTx(tx, status.Committed) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrAlreadyValidator) @@ -936,10 +970,12 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutPendingValidator(staker) onAcceptState.AddTx(tx, status.Committed) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrAlreadyValidator) @@ -975,10 +1011,12 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.DeleteUTXO(utxoID) } + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + FeeCalculator: feeCalculator, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrFlowCheckFailed) @@ -1073,10 +1111,12 @@ func TestDurangoDisabledTransactions(t *testing.T) { tx := tt.buildTx(env) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) err = tx.Unsigned.Visit(&StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, }) require.ErrorIs(err, tt.expectedErr) }) @@ -1269,10 +1309,12 @@ func TestDurangoMemoField(t *testing.T) { onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) require.NoError(t, subnetValTx.Unsigned.Visit(&StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: subnetValTx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: subnetValTx, })) tx, err := env.txBuilder.NewRemoveSubnetValidatorTx( @@ -1457,21 +1499,25 @@ func TestDurangoMemoField(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + // Populated memo field should error tx, onAcceptState := tt.setupTest(env, []byte{'m', 'e', 'm', 'o'}) err := tx.Unsigned.Visit(&StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, }) require.ErrorIs(err, avax.ErrMemoTooLarge) // Empty memo field should not error tx, onAcceptState = tt.setupTest(env, []byte{}) require.NoError(tx.Unsigned.Visit(&StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + State: onAcceptState, + FeeCalculator: feeCalculator, + Tx: tx, })) }) } @@ -1599,16 +1645,20 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().DeleteCurrentValidator(env.staker) env.state.EXPECT().DeleteUTXO(gomock.Any()).Times(len(env.unsignedTx.Ins)) env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) + + cfg := defaultTestConfig(t, durango, env.latestForkTime) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(t, durango, env.latestForkTime), + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1622,16 +1672,20 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { // Setting the subnet ID to the Primary Network ID makes the tx fail syntactic verification env.tx.Unsigned.(*txs.RemoveSubnetValidatorTx).Subnet = constants.PrimaryNetworkID env.state = state.NewMockDiff(ctrl) + + cfg := defaultTestConfig(t, durango, env.latestForkTime) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(t, durango, env.latestForkTime), + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1646,16 +1700,20 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) env.state.EXPECT().GetPendingValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) + + cfg := defaultTestConfig(t, durango, env.latestForkTime) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(t, durango, env.latestForkTime), + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1673,16 +1731,20 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { // Set dependency expectations. env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(&staker, nil).Times(1) + + cfg := defaultTestConfig(t, durango, env.latestForkTime) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(t, durango, env.latestForkTime), + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1698,16 +1760,20 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) + + cfg := defaultTestConfig(t, durango, env.latestForkTime) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(t, durango, env.latestForkTime), + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1722,16 +1788,20 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound) + + cfg := defaultTestConfig(t, durango, env.latestForkTime) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(t, durango, env.latestForkTime), + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1748,16 +1818,20 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil) env.fx.EXPECT().VerifyPermission(gomock.Any(), env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(errTest) + + cfg := defaultTestConfig(t, durango, env.latestForkTime) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(t, durango, env.latestForkTime), + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1777,16 +1851,20 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.flowChecker.EXPECT().VerifySpend( gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), ).Return(errTest) + + cfg := defaultTestConfig(t, durango, env.latestForkTime) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(t, durango, env.latestForkTime), + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1930,16 +2008,20 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { // Setting the tx to nil makes the tx fail syntactic verification env.tx.Unsigned = (*txs.TransformSubnetTx)(nil) env.state = state.NewMockDiff(ctrl) + + cfg := defaultTestConfig(t, durango, env.latestForkTime) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(t, durango, env.latestForkTime), + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1953,16 +2035,20 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.unsignedTx.MaxStakeDuration = math.MaxUint32 env.state = state.NewMockDiff(ctrl) env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + + cfg := defaultTestConfig(t, durango, env.latestForkTime) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ - Config: defaultTestConfig(t, durango, env.latestForkTime), + Config: cfg, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1981,6 +2067,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1989,8 +2076,9 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -2014,6 +2102,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2022,8 +2111,9 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -2052,6 +2142,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2060,8 +2151,9 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + FeeCalculator: feeCalculator, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 79ff3fe2e9a7..f349f282f7ca 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -13,8 +13,8 @@ import ( var _ txs.Visitor = (*calculator)(nil) -func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config) Calculator { - return Calculator{ +func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config) *Calculator { + return &Calculator{ config: config, upgradeTimes: upgradeTimes, } From 32e26d528fc767f59f38f2154351fc78bd79cfc0 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 20 May 2024 15:09:52 -0400 Subject: [PATCH 041/100] feeding chainTime to fee Calculator to ctor --- vms/platformvm/block/builder/builder.go | 2 +- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/block/executor/manager.go | 2 +- vms/platformvm/block/executor/verifier.go | 4 +- vms/platformvm/service_test.go | 4 +- .../txs/executor/advance_time_test.go | 20 ++--- .../txs/executor/atomic_tx_executor.go | 2 +- .../txs/executor/create_chain_test.go | 10 +-- .../txs/executor/create_subnet_test.go | 2 +- vms/platformvm/txs/executor/export_test.go | 2 +- vms/platformvm/txs/executor/helpers_test.go | 2 +- vms/platformvm/txs/executor/import_test.go | 2 +- .../txs/executor/proposal_tx_executor_test.go | 32 +++---- .../txs/executor/reward_validator_test.go | 12 +-- .../txs/executor/staker_tx_verification.go | 25 ++---- .../executor/staker_tx_verification_test.go | 32 +++---- .../txs/executor/standard_tx_executor.go | 22 ++--- .../txs/executor/standard_tx_executor_test.go | 90 +++++++++---------- vms/platformvm/txs/fee/calculator.go | 8 +- vms/platformvm/txs/fee/calculator_test.go | 4 +- vms/platformvm/txs/txstest/context.go | 6 +- 22 files changed, 139 insertions(+), 148 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 74cf20387241..153a545764ce 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -333,7 +333,7 @@ func packBlockTxs( } var ( - feeCalculator = fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) + feeCalculator = fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, timestamp) blockTxs []*txs.Tx inputs set.Set[ids.ID] diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index cdb69045f0bb..48c516cbc479 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -264,7 +264,7 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(genesisID, env.blkManager) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) executor := txexecutor.StandardTxExecutor{ Backend: &env.backend, State: stateDiff, diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 99b45e815307..ee3ffb980e6b 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -279,7 +279,7 @@ func addSubnet(env *environment) { panic(err) } - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) executor := executor.StandardTxExecutor{ Backend: env.backend, State: stateDiff, diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index 31dc4d468dca..afb950b2264b 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -143,7 +143,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - feeCalculator := fee.NewStaticCalculator(m.txExecutorBackend.Config.StaticFeeConfig, m.txExecutorBackend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(m.txExecutorBackend.Config.StaticFeeConfig, m.txExecutorBackend.Config.UpgradeConfig, nextBlkTime) return tx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: m.txExecutorBackend, State: stateDiff, diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 275eb2238e15..846444c4a651 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -361,7 +361,7 @@ func (v *verifier) proposalBlock( atomicRequests map[ids.ID]*atomic.Requests, onAcceptFunc func(), ) error { - feeCalculator := fee.NewStaticCalculator(v.txExecutorBackend.Config.StaticFeeConfig, v.txExecutorBackend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(v.txExecutorBackend.Config.StaticFeeConfig, v.txExecutorBackend.Config.UpgradeConfig, onCommitState.GetTimestamp()) txExecutor := executor.ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -436,7 +436,7 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID error, ) { var ( - feeCalculator = fee.NewStaticCalculator(v.txExecutorBackend.Config.StaticFeeConfig, v.txExecutorBackend.Config.UpgradeConfig) + feeCalculator = fee.NewStaticCalculator(v.txExecutorBackend.Config.StaticFeeConfig, v.txExecutorBackend.Config.UpgradeConfig, state.GetTimestamp()) onAcceptFunc func() inputs set.Set[ids.ID] diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 95e2f98c3228..52811d7cf5b8 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -368,8 +368,8 @@ func TestGetBalance(t *testing.T) { service, _, _ := defaultService(t) var ( - feeCalc = fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig) - createSubnetFee = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, service.vm.clock.Time()) + feeCalc = fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig, service.vm.clock.Time()) + createSubnetFee = feeCalc.CalculateFee(&txs.CreateSubnetTx{}) ) // Ensure GetStake is correct for each of the genesis validators diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index e246ff4f77fd..a4fecaa4c94c 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -64,7 +64,7 @@ func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -112,7 +112,7 @@ func TestAdvanceTimeTxTimestampTooEarly(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -149,7 +149,7 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -180,7 +180,7 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -422,7 +422,7 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -554,7 +554,7 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -633,7 +633,7 @@ func TestTrackedSubnet(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -683,7 +683,7 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -789,7 +789,7 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -887,7 +887,7 @@ func TestAdvanceTimeTxAfterBanff(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, diff --git a/vms/platformvm/txs/executor/atomic_tx_executor.go b/vms/platformvm/txs/executor/atomic_tx_executor.go index b71ee96d7f58..3365a216afde 100644 --- a/vms/platformvm/txs/executor/atomic_tx_executor.go +++ b/vms/platformvm/txs/executor/atomic_tx_executor.go @@ -99,7 +99,7 @@ func (e *AtomicTxExecutor) atomicTx(tx txs.UnsignedTx) error { } e.OnAccept = onAccept - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, e.OnAccept.GetTimestamp()) executor := StandardTxExecutor{ Backend: e.Backend, State: e.OnAccept, diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index ccf09bbc23b5..6da507b49948 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -47,7 +47,7 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -87,7 +87,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -121,7 +121,7 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -152,7 +152,7 @@ func TestCreateChainTxValid(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -221,7 +221,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index ed55bf5a743f..a8b65b621a52 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -76,7 +76,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index bc3b44c37b6c..829ad71b9b7a 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -73,7 +73,7 @@ func TestNewExportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) verifier := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index b6a206838c7c..f85b2a56a38d 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -232,7 +232,7 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index f2cfdf05b9b1..7cf07c0022a7 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -156,7 +156,7 @@ func TestNewImportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) verifier := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index e92556cde575..51f4c7ea1ee8 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -263,7 +263,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -308,7 +308,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -345,7 +345,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -400,7 +400,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -452,7 +452,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -487,7 +487,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -522,7 +522,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -559,7 +559,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -626,7 +626,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -671,7 +671,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -710,7 +710,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -759,7 +759,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -805,7 +805,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -843,7 +843,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -895,7 +895,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -939,7 +939,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, diff --git a/vms/platformvm/txs/executor/reward_validator_test.go b/vms/platformvm/txs/executor/reward_validator_test.go index ca736383d443..0c22fac99838 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -60,7 +60,7 @@ func TestRewardValidatorTxExecuteOnCommit(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAbortState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -164,7 +164,7 @@ func TestRewardValidatorTxExecuteOnAbort(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAbortState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -321,7 +321,7 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -463,7 +463,7 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -686,7 +686,7 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * delOnAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, delOnCommitState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: delOnCommitState, OnAbortState: delOnAbortState, @@ -847,7 +847,7 @@ func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index e8c76b1f6f7e..a31902c35b0c 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -165,8 +165,7 @@ func verifyAddValidatorTx( } // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + fee := feeCalculator.CalculateFee(tx) if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -256,8 +255,7 @@ func verifyAddSubnetValidatorTx( } // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + fee := feeCalculator.CalculateFee(tx) if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -334,8 +332,7 @@ func verifyRemoveSubnetValidatorTx( } // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + fee := feeCalculator.CalculateFee(tx) if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -452,8 +449,7 @@ func verifyAddDelegatorTx( } // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + fee := feeCalculator.CalculateFee(tx) if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -572,8 +568,7 @@ func verifyAddPermissionlessValidatorTx( copy(outs[len(tx.Outs):], tx.StakeOuts) // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + fee := feeCalculator.CalculateFee(tx) if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -717,8 +712,7 @@ func verifyAddPermissionlessDelegatorTx( } // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + fee := feeCalculator.CalculateFee(tx) if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -747,7 +741,8 @@ func verifyTransferSubnetOwnershipTx( sTx *txs.Tx, tx *txs.TransferSubnetOwnershipTx, ) error { - if !backend.Config.UpgradeConfig.IsDurangoActivated(chainState.GetTimestamp()) { + currentTimestamp := chainState.GetTimestamp() + if !backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { return ErrDurangoUpgradeNotActive } @@ -771,9 +766,7 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck - currentTimestamp := chainState.GetTimestamp() - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + fee := feeCalculator.CalculateFee(tx) if err := backend.FlowChecker.VerifySpend( tx, chainState, diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index f60cae17a864..40e18f422b53 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -114,8 +114,10 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Config: defaultTestConfig(t, durango, activeForkTime), } }, - stateF: func(*gomock.Controller) state.Chain { - return nil + stateF: func(ctrl *gomock.Controller) state.Chain { + mockState := state.NewMockChain(ctrl) + mockState.EXPECT().GetTimestamp().Return(now) + return mockState }, sTxF: func() *txs.Tx { return nil @@ -136,7 +138,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now) // chain time is after Durango fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after Durango fork activation since now.After(activeForkTime) return mockState }, sTxF: func() *txs.Tx { @@ -160,7 +162,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(verifiedTx.StartTime()) + state.EXPECT().GetTimestamp().Return(verifiedTx.StartTime()).Times(2) return state }, sTxF: func() *txs.Tx { @@ -184,7 +186,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) + state.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -211,7 +213,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) + state.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -238,7 +240,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) + state.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -266,7 +268,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) + state.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -297,7 +299,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(time.Unix(1, 0)) // chain time is after fork activation since time.Unix(1, 0).After(activeForkTime) + state.EXPECT().GetTimestamp().Return(time.Unix(1, 0)).Times(2) // chain time is after fork activation since time.Unix(1, 0).After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -328,7 +330,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return mockState }, @@ -361,7 +363,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) // State says validator exists mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, nil) @@ -388,7 +390,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(3) // chain time is after latest fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) mockState.EXPECT().GetPendingValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) @@ -435,7 +437,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(3) // chain time is after latest fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) mockState.EXPECT().GetPendingValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) @@ -481,7 +483,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after Durango fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(3) // chain time is after Durango fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) mockState.EXPECT().GetPendingValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) @@ -510,7 +512,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { state = tt.stateF(ctrl) sTx = tt.sTxF() tx = tt.txF() - feeCalculator = fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) + feeCalculator = fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, state.GetTimestamp()) ) err := verifyAddPermissionlessValidatorTx(backend, feeCalculator, state, sTx, tx) diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 40057d011fad..76983a6d1958 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -70,8 +70,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) - + fee := e.FeeCalculator.CalculateFee(tx) if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -117,8 +116,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } // Verify the flowcheck - fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) - + fee := e.FeeCalculator.CalculateFee(tx) if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -199,8 +197,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) - + fee := e.FeeCalculator.CalculateFee(tx) if err := e.FlowChecker.VerifySpendUTXOs( tx, utxos, @@ -257,8 +254,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) - + fee := e.FeeCalculator.CalculateFee(tx) if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -449,8 +445,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error } // Verify the flowcheck - fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) - + fee := e.FeeCalculator.CalculateFee(tx) totalRewardAmount := tx.MaximumSupply - tx.InitialSupply if err := e.Backend.FlowChecker.VerifySpend( tx, @@ -560,7 +555,8 @@ func (e *StandardTxExecutor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwn } func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { - if !e.Backend.Config.UpgradeConfig.IsDurangoActivated(e.State.GetTimestamp()) { + currentTimestamp := e.State.GetTimestamp() + if !e.Backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { return ErrDurangoUpgradeNotActive } @@ -574,9 +570,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { } // Verify the flowcheck - currentTimestamp := e.State.GetTimestamp() - fee := e.FeeCalculator.CalculateFee(tx, currentTimestamp) - + fee := e.FeeCalculator.CalculateFee(tx) if err := e.FlowChecker.VerifySpend( tx, e.State, diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 3cec25db7c1c..149af52cf306 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -94,7 +94,7 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: stateDiff, @@ -346,7 +346,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { env.config.UpgradeConfig.BanffTime = onAcceptState.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -389,7 +389,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -422,7 +422,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -473,7 +473,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -521,7 +521,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -552,7 +552,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -583,7 +583,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -616,7 +616,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -680,7 +680,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -722,7 +722,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -760,7 +760,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -796,7 +796,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -842,7 +842,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -883,7 +883,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -928,7 +928,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutCurrentValidator(staker) onAcceptState.AddTx(tx, status.Committed) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -970,7 +970,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutPendingValidator(staker) onAcceptState.AddTx(tx, status.Committed) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1011,7 +1011,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.DeleteUTXO(utxoID) } - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -1111,7 +1111,7 @@ func TestDurangoDisabledTransactions(t *testing.T) { tx := tt.buildTx(env) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) err = tx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1309,7 +1309,7 @@ func TestDurangoMemoField(t *testing.T) { onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) require.NoError(t, subnetValTx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1499,7 +1499,7 @@ func TestDurangoMemoField(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, env.state.GetTimestamp()) // Populated memo field should error tx, onAcceptState := tt.setupTest(env, []byte{'m', 'e', 'm', 'o'}) @@ -1634,7 +1634,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) // Set dependency expectations. - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil).Times(1) subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil).Times(1) @@ -1647,7 +1647,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1674,7 +1674,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1697,12 +1697,12 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { newExecutor: func(ctrl *gomock.Controller) (*txs.RemoveSubnetValidatorTx, *StandardTxExecutor) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) env.state.EXPECT().GetPendingValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1729,11 +1729,11 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { staker.Priority = txs.SubnetPermissionlessValidatorCurrentPriority // Set dependency expectations. - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(&staker, nil).Times(1) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1758,11 +1758,11 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { // Remove credentials env.tx.Creds = nil env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1785,12 +1785,12 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { newExecutor: func(ctrl *gomock.Controller) (*txs.RemoveSubnetValidatorTx, *StandardTxExecutor) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1813,14 +1813,14 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { newExecutor: func(ctrl *gomock.Controller) (*txs.RemoveSubnetValidatorTx, *StandardTxExecutor) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil) env.fx.EXPECT().VerifyPermission(gomock.Any(), env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(errTest) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1843,7 +1843,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { newExecutor: func(ctrl *gomock.Controller) (*txs.RemoveSubnetValidatorTx, *StandardTxExecutor) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil) @@ -1853,7 +1853,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { ).Return(errTest) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2010,7 +2010,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2034,10 +2034,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env := newValidTransformSubnetTxVerifyEnv(t, ctrl) env.unsignedTx.MaxStakeDuration = math.MaxUint32 env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2062,12 +2062,12 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { // Remove credentials env.tx.Creds = nil env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2091,7 +2091,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env := newValidTransformSubnetTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) subnetOwner := fx.NewMockOwner(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil) env.state.EXPECT().GetSubnetTransformation(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound).Times(1) env.fx.EXPECT().VerifyPermission(gomock.Any(), env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(nil) @@ -2102,7 +2102,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2127,7 +2127,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { // Set dependency expectations. subnetOwner := fx.NewMockOwner(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil).Times(1) env.state.EXPECT().GetSubnetTransformation(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound).Times(1) env.fx.EXPECT().VerifyPermission(env.unsignedTx, env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(nil).Times(1) @@ -2142,7 +2142,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index f349f282f7ca..a4a2f3d6c216 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -13,24 +13,26 @@ import ( var _ txs.Visitor = (*calculator)(nil) -func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config) *Calculator { +func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config, chainTime time.Time) *Calculator { return &Calculator{ config: config, upgradeTimes: upgradeTimes, + time: chainTime, } } type Calculator struct { config StaticConfig upgradeTimes upgrade.Config + time time.Time } // [CalculateFee] returns the minimal fee needed to accept [tx], at chain time [time] -func (c *Calculator) CalculateFee(tx txs.UnsignedTx, time time.Time) uint64 { +func (c *Calculator) CalculateFee(tx txs.UnsignedTx) uint64 { tmp := &calculator{ upgrades: c.upgradeTimes, staticCfg: c.config, - time: time, + time: c.time, } // this is guaranteed to never return an error diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index c25fec9073e8..a81b0c9b0e6b 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -188,8 +188,8 @@ func TestTxFees(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { uTx := tt.unsignedTx() - fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades) - require.Equal(t, tt.expected, fc.CalculateFee(uTx, tt.chainTime)) + fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) + require.Equal(t, tt.expected, fc.CalculateFee(uTx)) }) } } diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index ec2252a632e1..482f4a532175 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -19,9 +19,9 @@ func newContext( timestamp time.Time, ) *builder.Context { var ( - feeCalc = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) - createSubnetFee = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, timestamp) - createChainFee = feeCalc.CalculateFee(&txs.CreateChainTx{}, timestamp) + feeCalc = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, timestamp) + createSubnetFee = feeCalc.CalculateFee(&txs.CreateSubnetTx{}) + createChainFee = feeCalc.CalculateFee(&txs.CreateChainTx{}) ) return &builder.Context{ From e2f8809364d43c2bb4c15f9af133d72a846af759 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 21 May 2024 11:38:39 -0400 Subject: [PATCH 042/100] nit --- vms/platformvm/txs/fee/calculator.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 79ff3fe2e9a7..f349f282f7ca 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -13,8 +13,8 @@ import ( var _ txs.Visitor = (*calculator)(nil) -func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config) Calculator { - return Calculator{ +func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config) *Calculator { + return &Calculator{ config: config, upgradeTimes: upgradeTimes, } From c4021716583a8d700f3b3f7560a6ab50a2e9b8c5 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 21 May 2024 16:12:41 -0400 Subject: [PATCH 043/100] nit --- vms/platformvm/block/executor/verifier.go | 2 ++ vms/platformvm/txs/executor/atomic_tx_executor.go | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 846444c4a651..5c10e8c69981 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -188,8 +188,10 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { ) } + feeCalculator := fee.NewStaticCalculator(v.txExecutorBackend.Config.StaticFeeConfig, v.txExecutorBackend.Config.UpgradeConfig, currentTimestamp) atomicExecutor := executor.AtomicTxExecutor{ Backend: v.txExecutorBackend, + FeeCalculator: feeCalculator, ParentID: parentID, StateVersions: v, Tx: b.Tx, diff --git a/vms/platformvm/txs/executor/atomic_tx_executor.go b/vms/platformvm/txs/executor/atomic_tx_executor.go index 3365a216afde..ff6d3d5be60f 100644 --- a/vms/platformvm/txs/executor/atomic_tx_executor.go +++ b/vms/platformvm/txs/executor/atomic_tx_executor.go @@ -19,6 +19,7 @@ var _ txs.Visitor = (*AtomicTxExecutor)(nil) type AtomicTxExecutor struct { // inputs, to be filled before visitor methods are called *Backend + FeeCalculator *fee.Calculator ParentID ids.ID StateVersions state.Versions Tx *txs.Tx @@ -99,11 +100,10 @@ func (e *AtomicTxExecutor) atomicTx(tx txs.UnsignedTx) error { } e.OnAccept = onAccept - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, e.OnAccept.GetTimestamp()) executor := StandardTxExecutor{ Backend: e.Backend, State: e.OnAccept, - FeeCalculator: feeCalculator, + FeeCalculator: e.FeeCalculator, Tx: e.Tx, } err = tx.Visit(&executor) From ecb90903eab70cf6db471ec619edd3bee31667a2 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 29 May 2024 11:43:20 +0200 Subject: [PATCH 044/100] nits --- vms/platformvm/block/builder/helpers_test.go | 3 ++- vms/platformvm/block/executor/helpers_test.go | 3 ++- vms/platformvm/txs/executor/create_chain_test.go | 14 +++++++++----- vms/platformvm/txs/executor/create_subnet_test.go | 2 +- vms/platformvm/txs/executor/export_test.go | 3 ++- vms/platformvm/txs/executor/helpers_test.go | 3 ++- vms/platformvm/txs/executor/import_test.go | 3 ++- .../txs/executor/standard_tx_executor_test.go | 3 ++- 8 files changed, 22 insertions(+), 12 deletions(-) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 48c516cbc479..e0baca8ad102 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -264,7 +264,8 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(genesisID, env.blkManager) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + cfg := env.config + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) executor := txexecutor.StandardTxExecutor{ Backend: &env.backend, State: stateDiff, diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index ee3ffb980e6b..ed1a0bba0452 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -279,7 +279,8 @@ func addSubnet(env *environment) { panic(err) } - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + cfg := env.config + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) executor := executor.StandardTxExecutor{ Backend: env.backend, State: stateDiff, diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 6da507b49948..0675b8095272 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -47,7 +47,8 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + cfg := env.config + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -87,7 +88,8 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + cfg := env.config + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -121,7 +123,8 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + cfg := env.config + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -152,7 +155,8 @@ func TestCreateChainTxValid(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + cfg := env.config + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -221,7 +225,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index a8b65b621a52..57053a890f03 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -76,7 +76,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index 829ad71b9b7a..cfbf1fc47f5c 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -73,7 +73,8 @@ func TestNewExportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + cfg := env.config + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) verifier := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index f85b2a56a38d..4f9159634417 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -232,7 +232,8 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, env.state.GetTimestamp()) + cfg := env.config + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index 7cf07c0022a7..757dd5efbd88 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -156,7 +156,8 @@ func TestNewImportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + cfg := env.config + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) verifier := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 149af52cf306..570ebc54939e 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -1011,7 +1011,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.DeleteUTXO(utxoID) } - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, onAcceptState.GetTimestamp()) + cfg := env.config + feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, From ac5b00cfd4e0ad7e1e4d9b82e61d91d2f2f330fb Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 24 Jun 2024 09:37:53 +0200 Subject: [PATCH 045/100] restructured p-chain calculator --- vms/platformvm/service_test.go | 4 +- .../txs/executor/staker_tx_verification.go | 82 +++++++--- .../txs/executor/standard_tx_executor.go | 67 +++++--- vms/platformvm/txs/fee/calculator.go | 144 ------------------ vms/platformvm/txs/fee/calculator_api.go | 26 ++++ vms/platformvm/txs/fee/calculator_test.go | 4 +- vms/platformvm/txs/fee/static_calculator.go | 136 +++++++++++++++++ vms/platformvm/txs/txstest/context.go | 6 +- 8 files changed, 277 insertions(+), 192 deletions(-) delete mode 100644 vms/platformvm/txs/fee/calculator.go create mode 100644 vms/platformvm/txs/fee/calculator_api.go create mode 100644 vms/platformvm/txs/fee/static_calculator.go diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index e69390d54671..d1531ea03255 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -377,8 +377,8 @@ func TestGetBalance(t *testing.T) { service, _, _ := defaultService(t) var ( - feeCalc = fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig, service.vm.clock.Time()) - createSubnetFee = feeCalc.CalculateFee(&txs.CreateSubnetTx{}) + feeCalc = fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig, service.vm.clock.Time()) + createSubnetFee, _ = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, nil) ) // Ensure GetStake is correct for each of the genesis validators diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index a31902c35b0c..3450b76f2389 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -98,8 +98,12 @@ func verifyAddValidatorTx( []*avax.TransferableOutput, error, ) { - currentTimestamp := chainState.GetTimestamp() - if backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { + var ( + currentTimestamp = chainState.GetTimestamp() + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + ) + if isDurangoActive { return nil, ErrAddValidatorTxPostDurango } @@ -108,7 +112,7 @@ func verifyAddValidatorTx( return nil, err } - if err := avax.VerifyMemoFieldLength(tx.Memo, false /*=isDurangoActive*/); err != nil { + if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return nil, err } @@ -144,7 +148,7 @@ func verifyAddValidatorTx( return outs, nil } - if err := verifyStakerStartTime(false /*=isDurangoActive*/, currentTimestamp, startTime); err != nil { + if err := verifyStakerStartTime(isDurangoActive, currentTimestamp, startTime); err != nil { return nil, err } @@ -165,7 +169,10 @@ func verifyAddValidatorTx( } // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return nil, err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -198,7 +205,8 @@ func verifyAddSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -255,7 +263,10 @@ func verifyAddSubnetValidatorTx( } // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -294,7 +305,8 @@ func verifyRemoveSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return nil, false, err @@ -332,7 +344,10 @@ func verifyRemoveSubnetValidatorTx( } // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return nil, false, err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -362,8 +377,12 @@ func verifyAddDelegatorTx( []*avax.TransferableOutput, error, ) { - currentTimestamp := chainState.GetTimestamp() - if backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { + var ( + currentTimestamp = chainState.GetTimestamp() + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + ) + if isDurangoActive { return nil, ErrAddDelegatorTxPostDurango } @@ -372,7 +391,7 @@ func verifyAddDelegatorTx( return nil, err } - if err := avax.VerifyMemoFieldLength(tx.Memo, false /*=isDurangoActive*/); err != nil { + if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return nil, err } @@ -403,7 +422,7 @@ func verifyAddDelegatorTx( return outs, nil } - if err := verifyStakerStartTime(false /*=isDurangoActive*/, currentTimestamp, startTime); err != nil { + if err := verifyStakerStartTime(isDurangoActive, currentTimestamp, startTime); err != nil { return nil, err } @@ -421,7 +440,7 @@ func verifyAddDelegatorTx( return nil, ErrStakeOverflow } - if backend.Config.UpgradeConfig.IsApricotPhase3Activated(currentTimestamp) { + if upgrades.IsApricotPhase3Activated(currentTimestamp) { maximumWeight = min(maximumWeight, backend.Config.MaxValidatorStake) } @@ -449,7 +468,10 @@ func verifyAddDelegatorTx( } // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return nil, err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -482,7 +504,8 @@ func verifyAddPermissionlessValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -568,7 +591,10 @@ func verifyAddPermissionlessValidatorTx( copy(outs[len(tx.Outs):], tx.StakeOuts) // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -601,7 +627,8 @@ func verifyAddPermissionlessDelegatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -712,7 +739,10 @@ func verifyAddPermissionlessDelegatorTx( } // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -741,8 +771,13 @@ func verifyTransferSubnetOwnershipTx( sTx *txs.Tx, tx *txs.TransferSubnetOwnershipTx, ) error { - currentTimestamp := chainState.GetTimestamp() - if !backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { + var ( + currentTimestamp = chainState.GetTimestamp() + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + ) + + if !isDurangoActive { return ErrDurangoUpgradeNotActive } @@ -766,7 +801,10 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck - fee := feeCalculator.CalculateFee(tx) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 4b4de2f10ae6..5102415d4e16 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -58,7 +58,8 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = e.Backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -70,7 +71,10 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - fee := e.FeeCalculator.CalculateFee(tx) + fee, err := e.FeeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -109,14 +113,18 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = e.Backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err } // Verify the flowcheck - fee := e.FeeCalculator.CalculateFee(tx) + fee, err := e.FeeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -149,7 +157,8 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = e.Backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -197,7 +206,10 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - fee := e.FeeCalculator.CalculateFee(tx) + fee, err := e.FeeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } if err := e.FlowChecker.VerifySpendUTXOs( tx, utxos, @@ -237,16 +249,13 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = e.Backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err } - outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.ExportedOutputs)) - copy(outs, tx.Outs) - copy(outs[len(tx.Outs):], tx.ExportedOutputs) - if e.Bootstrapped.Get() { if err := verify.SameSubnet(context.TODO(), e.Ctx, tx.DestinationChain); err != nil { return err @@ -254,7 +263,13 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - fee := e.FeeCalculator.CalculateFee(tx) + fee, err := e.FeeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } + outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.ExportedOutputs)) + copy(outs, tx.Outs) + copy(outs[len(tx.Outs):], tx.ExportedOutputs) if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -405,14 +420,13 @@ func (e *StandardTxExecutor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidat return err } + // Invariant: There are no permissioned subnet delegators to remove. if isCurrentValidator { e.State.DeleteCurrentValidator(staker) } else { e.State.DeletePendingValidator(staker) } - // Invariant: There are no permissioned subnet delegators to remove. - txID := e.Tx.ID() avax.Consume(e.State, tx.Ins) avax.Produce(e.State, txID, tx.Outs) @@ -427,7 +441,8 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = e.Backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -445,7 +460,10 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error } // Verify the flowcheck - fee := e.FeeCalculator.CalculateFee(tx) + fee, err := e.FeeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } totalRewardAmount := tx.MaximumSupply - tx.InitialSupply if err := e.Backend.FlowChecker.VerifySpend( tx, @@ -555,8 +573,13 @@ func (e *StandardTxExecutor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwn } func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { - currentTimestamp := e.State.GetTimestamp() - if !e.Backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { + var ( + currentTimestamp = e.State.GetTimestamp() + upgrades = e.Backend.Config.UpgradeConfig + IsDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + ) + + if !IsDurangoActive { return ErrDurangoUpgradeNotActive } @@ -570,7 +593,10 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { } // Verify the flowcheck - fee := e.FeeCalculator.CalculateFee(tx) + fee, err := e.FeeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -596,12 +622,13 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { func (e *StandardTxExecutor) putStaker(stakerTx txs.Staker) error { var ( chainTime = e.State.GetTimestamp() + upgrades = e.Backend.Config.UpgradeConfig txID = e.Tx.ID() staker *state.Staker err error ) - if !e.Config.UpgradeConfig.IsDurangoActivated(chainTime) { + if !upgrades.IsDurangoActivated(chainTime) { // Pre-Durango, stakers set a future [StartTime] and are added to the // pending staker set. They are promoted to the current staker set once // the chain time reaches [StartTime]. diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go deleted file mode 100644 index a4a2f3d6c216..000000000000 --- a/vms/platformvm/txs/fee/calculator.go +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package fee - -import ( - "time" - - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" -) - -var _ txs.Visitor = (*calculator)(nil) - -func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config, chainTime time.Time) *Calculator { - return &Calculator{ - config: config, - upgradeTimes: upgradeTimes, - time: chainTime, - } -} - -type Calculator struct { - config StaticConfig - upgradeTimes upgrade.Config - time time.Time -} - -// [CalculateFee] returns the minimal fee needed to accept [tx], at chain time [time] -func (c *Calculator) CalculateFee(tx txs.UnsignedTx) uint64 { - tmp := &calculator{ - upgrades: c.upgradeTimes, - staticCfg: c.config, - time: c.time, - } - - // this is guaranteed to never return an error - _ = tx.Visit(tmp) - return tmp.fee -} - -// calculator is intentionally unexported and used through Calculator to provide -// a more convenient API -type calculator struct { - // Pre E-fork inputs - upgrades upgrade.Config - staticCfg StaticConfig - time time.Time - - // outputs of visitor execution - fee uint64 -} - -func (c *calculator) AddValidatorTx(*txs.AddValidatorTx) error { - c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee - return nil -} - -func (c *calculator) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { - c.fee = c.staticCfg.AddSubnetValidatorFee - return nil -} - -func (c *calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { - c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee - return nil -} - -func (c *calculator) CreateChainTx(*txs.CreateChainTx) error { - if c.upgrades.IsApricotPhase3Activated(c.time) { - c.fee = c.staticCfg.CreateBlockchainTxFee - } else { - c.fee = c.staticCfg.CreateAssetTxFee - } - return nil -} - -func (c *calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { - if c.upgrades.IsApricotPhase3Activated(c.time) { - c.fee = c.staticCfg.CreateSubnetTxFee - } else { - c.fee = c.staticCfg.CreateAssetTxFee - } - return nil -} - -func (c *calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - c.fee = 0 // no fees - return nil -} - -func (c *calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { - c.fee = 0 // no fees - return nil -} - -func (c *calculator) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { - c.fee = c.staticCfg.TxFee - return nil -} - -func (c *calculator) TransformSubnetTx(*txs.TransformSubnetTx) error { - c.fee = c.staticCfg.TransformSubnetTxFee - return nil -} - -func (c *calculator) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { - c.fee = c.staticCfg.TxFee - return nil -} - -func (c *calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { - if tx.Subnet != constants.PrimaryNetworkID { - c.fee = c.staticCfg.AddSubnetValidatorFee - } else { - c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee - } - return nil -} - -func (c *calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { - if tx.Subnet != constants.PrimaryNetworkID { - c.fee = c.staticCfg.AddSubnetDelegatorFee - } else { - c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee - } - return nil -} - -func (c *calculator) BaseTx(*txs.BaseTx) error { - c.fee = c.staticCfg.TxFee - return nil -} - -func (c *calculator) ImportTx(*txs.ImportTx) error { - c.fee = c.staticCfg.TxFee - return nil -} - -func (c *calculator) ExportTx(*txs.ExportTx) error { - c.fee = c.staticCfg.TxFee - return nil -} diff --git a/vms/platformvm/txs/fee/calculator_api.go b/vms/platformvm/txs/fee/calculator_api.go new file mode 100644 index 000000000000..7a4ea5607b52 --- /dev/null +++ b/vms/platformvm/txs/fee/calculator_api.go @@ -0,0 +1,26 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" +) + +// Calculator is a wrapper to exposed a more user friendly API than txs.Visitor allows +// backend is not embedded to avoid exposing unnecessary methods +type Calculator struct { + b backend +} + +func (c *Calculator) CalculateFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) { + return c.b.calculateFee(tx, creds) +} + +// backend is the interfaces that any fee backend must implement +type backend interface { + txs.Visitor + + calculateFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) +} diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index a81b0c9b0e6b..02dc0e9dfc54 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -189,7 +189,9 @@ func TestTxFees(t *testing.T) { t.Run(tt.name, func(t *testing.T) { uTx := tt.unsignedTx() fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) - require.Equal(t, tt.expected, fc.CalculateFee(uTx)) + fee, err := fc.CalculateFee(uTx, nil) + require.NoError(t, err) + require.Equal(t, tt.expected, fee) }) } } diff --git a/vms/platformvm/txs/fee/static_calculator.go b/vms/platformvm/txs/fee/static_calculator.go new file mode 100644 index 000000000000..5c78a34f1a59 --- /dev/null +++ b/vms/platformvm/txs/fee/static_calculator.go @@ -0,0 +1,136 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "time" + + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" +) + +var _ backend = (*staticCalculator)(nil) + +func NewStaticCalculator( + config StaticConfig, + upgradeTimes upgrade.Config, + chainTime time.Time, +) *Calculator { + return &Calculator{ + b: &staticCalculator{ + upgrades: upgradeTimes, + staticCfg: config, + time: chainTime, + }, + } +} + +type staticCalculator struct { + // inputs + staticCfg StaticConfig + upgrades upgrade.Config + time time.Time + + // outputs of visitor execution + fee uint64 +} + +func (c *staticCalculator) AddValidatorTx(*txs.AddValidatorTx) error { + c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee + return nil +} + +func (c *staticCalculator) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { + c.fee = c.staticCfg.AddSubnetValidatorFee + return nil +} + +func (c *staticCalculator) AddDelegatorTx(*txs.AddDelegatorTx) error { + c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee + return nil +} + +func (c *staticCalculator) CreateChainTx(*txs.CreateChainTx) error { + if c.upgrades.IsApricotPhase3Activated(c.time) { + c.fee = c.staticCfg.CreateBlockchainTxFee + } else { + c.fee = c.staticCfg.CreateAssetTxFee + } + return nil +} + +func (c *staticCalculator) CreateSubnetTx(*txs.CreateSubnetTx) error { + if c.upgrades.IsApricotPhase3Activated(c.time) { + c.fee = c.staticCfg.CreateSubnetTxFee + } else { + c.fee = c.staticCfg.CreateAssetTxFee + } + return nil +} + +func (c *staticCalculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + c.fee = 0 // no fees + return nil +} + +func (c *staticCalculator) RewardValidatorTx(*txs.RewardValidatorTx) error { + c.fee = 0 // no fees + return nil +} + +func (c *staticCalculator) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { + c.fee = c.staticCfg.TxFee + return nil +} + +func (c *staticCalculator) TransformSubnetTx(*txs.TransformSubnetTx) error { + c.fee = c.staticCfg.TransformSubnetTxFee + return nil +} + +func (c *staticCalculator) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { + c.fee = c.staticCfg.TxFee + return nil +} + +func (c *staticCalculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { + if tx.Subnet != constants.PrimaryNetworkID { + c.fee = c.staticCfg.AddSubnetValidatorFee + } else { + c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee + } + return nil +} + +func (c *staticCalculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { + if tx.Subnet != constants.PrimaryNetworkID { + c.fee = c.staticCfg.AddSubnetDelegatorFee + } else { + c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee + } + return nil +} + +func (c *staticCalculator) BaseTx(*txs.BaseTx) error { + c.fee = c.staticCfg.TxFee + return nil +} + +func (c *staticCalculator) ImportTx(*txs.ImportTx) error { + c.fee = c.staticCfg.TxFee + return nil +} + +func (c *staticCalculator) ExportTx(*txs.ExportTx) error { + c.fee = c.staticCfg.TxFee + return nil +} + +func (c *staticCalculator) calculateFee(tx txs.UnsignedTx, _ []verify.Verifiable) (uint64, error) { + c.fee = 0 // zero fee among different calculateFee invocations (unlike gas which gets cumulated) + err := tx.Visit(c) + return c.fee, err +} diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index 482f4a532175..d8e24796f9fc 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -19,9 +19,9 @@ func newContext( timestamp time.Time, ) *builder.Context { var ( - feeCalc = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, timestamp) - createSubnetFee = feeCalc.CalculateFee(&txs.CreateSubnetTx{}) - createChainFee = feeCalc.CalculateFee(&txs.CreateChainTx{}) + feeCalc = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, timestamp) + createSubnetFee, _ = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, nil) + createChainFee, _ = feeCalc.CalculateFee(&txs.CreateChainTx{}, nil) ) return &builder.Context{ From e88298c660f990974c9da9dd352ddc1a771d7b55 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 24 Jun 2024 09:58:12 +0200 Subject: [PATCH 046/100] restructured fee calculator API --- vms/platformvm/service_test.go | 4 +- .../txs/executor/staker_tx_verification.go | 103 ++++++++----- .../txs/executor/standard_tx_executor.go | 85 +++++++---- vms/platformvm/txs/fee/calculator.go | 142 ------------------ vms/platformvm/txs/fee/calculator_api.go | 26 ++++ vms/platformvm/txs/fee/calculator_test.go | 6 +- vms/platformvm/txs/fee/static_calculator.go | 136 +++++++++++++++++ vms/platformvm/txs/txstest/context.go | 6 +- 8 files changed, 291 insertions(+), 217 deletions(-) delete mode 100644 vms/platformvm/txs/fee/calculator.go create mode 100644 vms/platformvm/txs/fee/calculator_api.go create mode 100644 vms/platformvm/txs/fee/static_calculator.go diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 69e94d0dee3e..d1531ea03255 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -377,8 +377,8 @@ func TestGetBalance(t *testing.T) { service, _, _ := defaultService(t) var ( - feeCalc = fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig) - createSubnetFee = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, service.vm.clock.Time()) + feeCalc = fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig, service.vm.clock.Time()) + createSubnetFee, _ = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, nil) ) // Ensure GetStake is correct for each of the genesis validators diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 0aac4ad50f64..aa32a25a076a 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -97,8 +97,12 @@ func verifyAddValidatorTx( []*avax.TransferableOutput, error, ) { - currentTimestamp := chainState.GetTimestamp() - if backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { + var ( + currentTimestamp = chainState.GetTimestamp() + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + ) + if isDurangoActive { return nil, ErrAddValidatorTxPostDurango } @@ -107,7 +111,7 @@ func verifyAddValidatorTx( return nil, err } - if err := avax.VerifyMemoFieldLength(tx.Memo, false /*=isDurangoActive*/); err != nil { + if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return nil, err } @@ -143,7 +147,7 @@ func verifyAddValidatorTx( return outs, nil } - if err := verifyStakerStartTime(false /*=isDurangoActive*/, currentTimestamp, startTime); err != nil { + if err := verifyStakerStartTime(isDurangoActive, currentTimestamp, startTime); err != nil { return nil, err } @@ -164,9 +168,11 @@ func verifyAddValidatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return nil, err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -198,7 +204,8 @@ func verifyAddSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -255,9 +262,11 @@ func verifyAddSubnetValidatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -295,7 +304,8 @@ func verifyRemoveSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return nil, false, err @@ -333,9 +343,11 @@ func verifyRemoveSubnetValidatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return nil, false, err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -364,8 +376,12 @@ func verifyAddDelegatorTx( []*avax.TransferableOutput, error, ) { - currentTimestamp := chainState.GetTimestamp() - if backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { + var ( + currentTimestamp = chainState.GetTimestamp() + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + ) + if isDurangoActive { return nil, ErrAddDelegatorTxPostDurango } @@ -374,7 +390,7 @@ func verifyAddDelegatorTx( return nil, err } - if err := avax.VerifyMemoFieldLength(tx.Memo, false /*=isDurangoActive*/); err != nil { + if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return nil, err } @@ -405,7 +421,7 @@ func verifyAddDelegatorTx( return outs, nil } - if err := verifyStakerStartTime(false /*=isDurangoActive*/, currentTimestamp, startTime); err != nil { + if err := verifyStakerStartTime(isDurangoActive, currentTimestamp, startTime); err != nil { return nil, err } @@ -423,7 +439,7 @@ func verifyAddDelegatorTx( return nil, ErrStakeOverflow } - if backend.Config.UpgradeConfig.IsApricotPhase3Activated(currentTimestamp) { + if upgrades.IsApricotPhase3Activated(currentTimestamp) { maximumWeight = min(maximumWeight, backend.Config.MaxValidatorStake) } @@ -451,9 +467,11 @@ func verifyAddDelegatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return nil, err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -485,7 +503,8 @@ func verifyAddPermissionlessValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -571,9 +590,11 @@ func verifyAddPermissionlessValidatorTx( copy(outs[len(tx.Outs):], tx.StakeOuts) // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -605,7 +626,8 @@ func verifyAddPermissionlessDelegatorTx( var ( currentTimestamp = chainState.GetTimestamp() - isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -716,9 +738,11 @@ func verifyAddPermissionlessDelegatorTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, @@ -746,7 +770,13 @@ func verifyTransferSubnetOwnershipTx( sTx *txs.Tx, tx *txs.TransferSubnetOwnershipTx, ) error { - if !backend.Config.UpgradeConfig.IsDurangoActivated(chainState.GetTimestamp()) { + var ( + currentTimestamp = chainState.GetTimestamp() + upgrades = backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + ) + + if !isDurangoActive { return ErrDurangoUpgradeNotActive } @@ -770,10 +800,11 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck - currentTimestamp := chainState.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + if err != nil { + return err + } if err := backend.FlowChecker.VerifySpend( tx, chainState, diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 2de7d3392ba8..0d416678c43b 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -57,7 +57,8 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = e.Backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -69,9 +70,11 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -110,16 +113,19 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = e.Backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -152,7 +158,8 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = e.Backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -200,9 +207,11 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } if err := e.FlowChecker.VerifySpendUTXOs( tx, utxos, @@ -242,16 +251,13 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = e.Backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err } - outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.ExportedOutputs)) - copy(outs, tx.Outs) - copy(outs[len(tx.Outs):], tx.ExportedOutputs) - if e.Bootstrapped.Get() { if err := verify.SameSubnet(context.TODO(), e.Ctx, tx.DestinationChain); err != nil { return err @@ -259,9 +265,14 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } + outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.ExportedOutputs)) + copy(outs, tx.Outs) + copy(outs[len(tx.Outs):], tx.ExportedOutputs) if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -408,14 +419,13 @@ func (e *StandardTxExecutor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidat return err } + // Invariant: There are no permissioned subnet delegators to remove. if isCurrentValidator { e.State.DeleteCurrentValidator(staker) } else { e.State.DeletePendingValidator(staker) } - // Invariant: There are no permissioned subnet delegators to remove. - txID := e.Tx.ID() avax.Consume(e.State, tx.Ins) avax.Produce(e.State, txID, tx.Outs) @@ -430,7 +440,8 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error var ( currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) + upgrades = e.Backend.Config.UpgradeConfig + isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -448,9 +459,11 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } totalRewardAmount := tx.MaximumSupply - tx.InitialSupply if err := e.Backend.FlowChecker.VerifySpend( tx, @@ -557,7 +570,13 @@ func (e *StandardTxExecutor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwn } func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { - if !e.Backend.Config.UpgradeConfig.IsDurangoActivated(e.State.GetTimestamp()) { + var ( + currentTimestamp = e.State.GetTimestamp() + upgrades = e.Backend.Config.UpgradeConfig + IsDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + ) + + if !IsDurangoActive { return ErrDurangoUpgradeNotActive } @@ -571,10 +590,11 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { } // Verify the flowcheck - currentTimestamp := e.State.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig) - fee := feeCalculator.CalculateFee(tx, currentTimestamp) - + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) + fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + if err != nil { + return err + } if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -600,12 +620,13 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { func (e *StandardTxExecutor) putStaker(stakerTx txs.Staker) error { var ( chainTime = e.State.GetTimestamp() + upgrades = e.Backend.Config.UpgradeConfig txID = e.Tx.ID() staker *state.Staker err error ) - if !e.Config.UpgradeConfig.IsDurangoActivated(chainTime) { + if !upgrades.IsDurangoActivated(chainTime) { // Pre-Durango, stakers set a future [StartTime] and are added to the // pending staker set. They are promoted to the current staker set once // the chain time reaches [StartTime]. diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go deleted file mode 100644 index f349f282f7ca..000000000000 --- a/vms/platformvm/txs/fee/calculator.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package fee - -import ( - "time" - - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" -) - -var _ txs.Visitor = (*calculator)(nil) - -func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config) *Calculator { - return &Calculator{ - config: config, - upgradeTimes: upgradeTimes, - } -} - -type Calculator struct { - config StaticConfig - upgradeTimes upgrade.Config -} - -// [CalculateFee] returns the minimal fee needed to accept [tx], at chain time [time] -func (c *Calculator) CalculateFee(tx txs.UnsignedTx, time time.Time) uint64 { - tmp := &calculator{ - upgrades: c.upgradeTimes, - staticCfg: c.config, - time: time, - } - - // this is guaranteed to never return an error - _ = tx.Visit(tmp) - return tmp.fee -} - -// calculator is intentionally unexported and used through Calculator to provide -// a more convenient API -type calculator struct { - // Pre E-fork inputs - upgrades upgrade.Config - staticCfg StaticConfig - time time.Time - - // outputs of visitor execution - fee uint64 -} - -func (c *calculator) AddValidatorTx(*txs.AddValidatorTx) error { - c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee - return nil -} - -func (c *calculator) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { - c.fee = c.staticCfg.AddSubnetValidatorFee - return nil -} - -func (c *calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { - c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee - return nil -} - -func (c *calculator) CreateChainTx(*txs.CreateChainTx) error { - if c.upgrades.IsApricotPhase3Activated(c.time) { - c.fee = c.staticCfg.CreateBlockchainTxFee - } else { - c.fee = c.staticCfg.CreateAssetTxFee - } - return nil -} - -func (c *calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { - if c.upgrades.IsApricotPhase3Activated(c.time) { - c.fee = c.staticCfg.CreateSubnetTxFee - } else { - c.fee = c.staticCfg.CreateAssetTxFee - } - return nil -} - -func (c *calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - c.fee = 0 // no fees - return nil -} - -func (c *calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { - c.fee = 0 // no fees - return nil -} - -func (c *calculator) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { - c.fee = c.staticCfg.TxFee - return nil -} - -func (c *calculator) TransformSubnetTx(*txs.TransformSubnetTx) error { - c.fee = c.staticCfg.TransformSubnetTxFee - return nil -} - -func (c *calculator) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { - c.fee = c.staticCfg.TxFee - return nil -} - -func (c *calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { - if tx.Subnet != constants.PrimaryNetworkID { - c.fee = c.staticCfg.AddSubnetValidatorFee - } else { - c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee - } - return nil -} - -func (c *calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { - if tx.Subnet != constants.PrimaryNetworkID { - c.fee = c.staticCfg.AddSubnetDelegatorFee - } else { - c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee - } - return nil -} - -func (c *calculator) BaseTx(*txs.BaseTx) error { - c.fee = c.staticCfg.TxFee - return nil -} - -func (c *calculator) ImportTx(*txs.ImportTx) error { - c.fee = c.staticCfg.TxFee - return nil -} - -func (c *calculator) ExportTx(*txs.ExportTx) error { - c.fee = c.staticCfg.TxFee - return nil -} diff --git a/vms/platformvm/txs/fee/calculator_api.go b/vms/platformvm/txs/fee/calculator_api.go new file mode 100644 index 000000000000..7a4ea5607b52 --- /dev/null +++ b/vms/platformvm/txs/fee/calculator_api.go @@ -0,0 +1,26 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" +) + +// Calculator is a wrapper to exposed a more user friendly API than txs.Visitor allows +// backend is not embedded to avoid exposing unnecessary methods +type Calculator struct { + b backend +} + +func (c *Calculator) CalculateFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) { + return c.b.calculateFee(tx, creds) +} + +// backend is the interfaces that any fee backend must implement +type backend interface { + txs.Visitor + + calculateFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) +} diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index c25fec9073e8..02dc0e9dfc54 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -188,8 +188,10 @@ func TestTxFees(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { uTx := tt.unsignedTx() - fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades) - require.Equal(t, tt.expected, fc.CalculateFee(uTx, tt.chainTime)) + fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) + fee, err := fc.CalculateFee(uTx, nil) + require.NoError(t, err) + require.Equal(t, tt.expected, fee) }) } } diff --git a/vms/platformvm/txs/fee/static_calculator.go b/vms/platformvm/txs/fee/static_calculator.go new file mode 100644 index 000000000000..5c78a34f1a59 --- /dev/null +++ b/vms/platformvm/txs/fee/static_calculator.go @@ -0,0 +1,136 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "time" + + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" +) + +var _ backend = (*staticCalculator)(nil) + +func NewStaticCalculator( + config StaticConfig, + upgradeTimes upgrade.Config, + chainTime time.Time, +) *Calculator { + return &Calculator{ + b: &staticCalculator{ + upgrades: upgradeTimes, + staticCfg: config, + time: chainTime, + }, + } +} + +type staticCalculator struct { + // inputs + staticCfg StaticConfig + upgrades upgrade.Config + time time.Time + + // outputs of visitor execution + fee uint64 +} + +func (c *staticCalculator) AddValidatorTx(*txs.AddValidatorTx) error { + c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee + return nil +} + +func (c *staticCalculator) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { + c.fee = c.staticCfg.AddSubnetValidatorFee + return nil +} + +func (c *staticCalculator) AddDelegatorTx(*txs.AddDelegatorTx) error { + c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee + return nil +} + +func (c *staticCalculator) CreateChainTx(*txs.CreateChainTx) error { + if c.upgrades.IsApricotPhase3Activated(c.time) { + c.fee = c.staticCfg.CreateBlockchainTxFee + } else { + c.fee = c.staticCfg.CreateAssetTxFee + } + return nil +} + +func (c *staticCalculator) CreateSubnetTx(*txs.CreateSubnetTx) error { + if c.upgrades.IsApricotPhase3Activated(c.time) { + c.fee = c.staticCfg.CreateSubnetTxFee + } else { + c.fee = c.staticCfg.CreateAssetTxFee + } + return nil +} + +func (c *staticCalculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + c.fee = 0 // no fees + return nil +} + +func (c *staticCalculator) RewardValidatorTx(*txs.RewardValidatorTx) error { + c.fee = 0 // no fees + return nil +} + +func (c *staticCalculator) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { + c.fee = c.staticCfg.TxFee + return nil +} + +func (c *staticCalculator) TransformSubnetTx(*txs.TransformSubnetTx) error { + c.fee = c.staticCfg.TransformSubnetTxFee + return nil +} + +func (c *staticCalculator) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { + c.fee = c.staticCfg.TxFee + return nil +} + +func (c *staticCalculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { + if tx.Subnet != constants.PrimaryNetworkID { + c.fee = c.staticCfg.AddSubnetValidatorFee + } else { + c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee + } + return nil +} + +func (c *staticCalculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { + if tx.Subnet != constants.PrimaryNetworkID { + c.fee = c.staticCfg.AddSubnetDelegatorFee + } else { + c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee + } + return nil +} + +func (c *staticCalculator) BaseTx(*txs.BaseTx) error { + c.fee = c.staticCfg.TxFee + return nil +} + +func (c *staticCalculator) ImportTx(*txs.ImportTx) error { + c.fee = c.staticCfg.TxFee + return nil +} + +func (c *staticCalculator) ExportTx(*txs.ExportTx) error { + c.fee = c.staticCfg.TxFee + return nil +} + +func (c *staticCalculator) calculateFee(tx txs.UnsignedTx, _ []verify.Verifiable) (uint64, error) { + c.fee = 0 // zero fee among different calculateFee invocations (unlike gas which gets cumulated) + err := tx.Visit(c) + return c.fee, err +} diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index ec2252a632e1..d8e24796f9fc 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -19,9 +19,9 @@ func newContext( timestamp time.Time, ) *builder.Context { var ( - feeCalc = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig) - createSubnetFee = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, timestamp) - createChainFee = feeCalc.CalculateFee(&txs.CreateChainTx{}, timestamp) + feeCalc = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, timestamp) + createSubnetFee, _ = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, nil) + createChainFee, _ = feeCalc.CalculateFee(&txs.CreateChainTx{}, nil) ) return &builder.Context{ From e65b33c0b0d723b8eb50e5534f752fdc47bd093c Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 27 Jun 2024 13:42:01 +0200 Subject: [PATCH 047/100] consolidated fee Calculator creation --- vms/platformvm/block/builder/builder.go | 9 +- vms/platformvm/block/builder/helpers_test.go | 6 +- vms/platformvm/block/executor/helpers_test.go | 9 +- vms/platformvm/block/executor/manager.go | 7 +- vms/platformvm/block/executor/verifier.go | 49 +++++-- vms/platformvm/service_test.go | 8 +- vms/platformvm/state/chain_time_helpers.go | 9 ++ .../txs/executor/advance_time_test.go | 41 ++++-- .../txs/executor/create_chain_test.go | 27 ++-- .../txs/executor/create_subnet_test.go | 5 +- vms/platformvm/txs/executor/export_test.go | 6 +- vms/platformvm/txs/executor/helpers_test.go | 5 +- vms/platformvm/txs/executor/import_test.go | 6 +- .../txs/executor/proposal_tx_executor_test.go | 49 ++++--- .../txs/executor/reward_validator_test.go | 19 ++- .../executor/staker_tx_verification_test.go | 15 +- .../txs/executor/standard_tx_executor_test.go | 130 +++++++++++------- 17 files changed, 266 insertions(+), 134 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index fcbc6c65ecc1..28fb4958bb57 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -22,7 +22,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" @@ -332,13 +331,15 @@ func packBlockTxs( return nil, err } - var ( - feeCalculator = fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, timestamp) + feeCalculator, err := state.PickFeeCalculator(backend.Config, stateDiff) + if err != nil { + return nil, err + } + var ( blockTxs []*txs.Tx inputs set.Set[ids.ID] ) - for { tx, exists := mempool.Peek() if !exists { diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 9c282c03b24d..df2d620c6eed 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -259,8 +259,9 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(genesisID, env.blkManager) require.NoError(err) - cfg := env.config - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff) + require.NoError(err) + executor := txexecutor.StandardTxExecutor{ Backend: &env.backend, State: stateDiff, @@ -271,6 +272,7 @@ func addSubnet(t *testing.T, env *environment) { stateDiff.AddTx(testSubnet1, status.Committed) require.NoError(stateDiff.Apply(env.state)) + require.NoError(env.state.Commit()) } func defaultState( diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index bf3f3dc3dbbc..80dca6745fcc 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -280,9 +280,11 @@ func addSubnet(env *environment) { if err != nil { panic(err) } + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff) + if err != nil { + panic(err) + } - cfg := env.config - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) executor := executor.StandardTxExecutor{ Backend: env.backend, State: stateDiff, @@ -298,6 +300,9 @@ func addSubnet(env *environment) { if err := stateDiff.Apply(env.state); err != nil { panic(err) } + if err := env.state.Commit(); err != nil { + panic(err) + } } func defaultState( diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index 27cb3c974871..82580c3b52b9 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -14,7 +14,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" "github.com/ava-labs/avalanchego/vms/platformvm/validators" ) @@ -143,7 +142,11 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - feeCalculator := fee.NewStaticCalculator(m.txExecutorBackend.Config.StaticFeeConfig, m.txExecutorBackend.Config.UpgradeConfig, nextBlkTime) + feeCalculator, err := state.PickFeeCalculator(m.txExecutorBackend.Config, stateDiff) + if err != nil { + return err + } + return tx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: m.txExecutorBackend, State: stateDiff, diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index a9476354e3a8..70fd8714ab28 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -67,7 +67,17 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { return err } - inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, onDecisionState, b.Parent()) + feeCalculator, err := state.PickFeeCalculator(v.txExecutorBackend.Config, onDecisionState) + if err != nil { + return err + } + + inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs( + b.Transactions, + feeCalculator, + onDecisionState, + b.Parent(), + ) if err != nil { return err } @@ -87,6 +97,7 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { onDecisionState, onCommitState, onAbortState, + feeCalculator, inputs, atomicRequests, onAcceptFunc, @@ -120,7 +131,11 @@ func (v *verifier) BanffStandardBlock(b *block.BanffStandardBlock) error { return errBanffStandardBlockWithoutChanges } - return v.standardBlock(&b.ApricotStandardBlock, onAcceptState) + feeCalculator, err := state.PickFeeCalculator(v.txExecutorBackend.Config, onAcceptState) + if err != nil { + return err + } + return v.standardBlock(&b.ApricotStandardBlock, feeCalculator, onAcceptState) } func (v *verifier) ApricotAbortBlock(b *block.ApricotAbortBlock) error { @@ -152,7 +167,12 @@ func (v *verifier) ApricotProposalBlock(b *block.ApricotProposalBlock) error { return err } - return v.proposalBlock(b, nil, onCommitState, onAbortState, nil, nil, nil) + var ( + staticFeesCfg = v.txExecutorBackend.Config.StaticFeeConfig + upgrades = v.txExecutorBackend.Config.UpgradeConfig + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, onCommitState.GetTimestamp()) + ) + return v.proposalBlock(b, nil, onCommitState, onAbortState, feeCalculator, nil, nil, nil) } func (v *verifier) ApricotStandardBlock(b *block.ApricotStandardBlock) error { @@ -166,7 +186,12 @@ func (v *verifier) ApricotStandardBlock(b *block.ApricotStandardBlock) error { return err } - return v.standardBlock(b, onAcceptState) + var ( + staticFeesCfg = v.txExecutorBackend.Config.StaticFeeConfig + upgrades = v.txExecutorBackend.Config.UpgradeConfig + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, onAcceptState.GetTimestamp()) + ) + return v.standardBlock(b, feeCalculator, onAcceptState) } func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { @@ -332,6 +357,9 @@ func (v *verifier) abortBlock(b block.Block) error { statelessBlock: b, onAcceptState: onAbortState, timestamp: onAbortState.GetTimestamp(), + + // blockComplexity not set. We'll assign same complexity + // as proposal blocks upon acceptance } return nil } @@ -349,6 +377,9 @@ func (v *verifier) commitBlock(b block.Block) error { statelessBlock: b, onAcceptState: onCommitState, timestamp: onCommitState.GetTimestamp(), + + // blockComplexity not set. We'll assign same complexity + // as proposal blocks upon acceptance } return nil } @@ -359,11 +390,11 @@ func (v *verifier) proposalBlock( onDecisionState state.Diff, onCommitState state.Diff, onAbortState state.Diff, + feeCalculator *fee.Calculator, inputs set.Set[ids.ID], atomicRequests map[ids.ID]*atomic.Requests, onAcceptFunc func(), ) error { - feeCalculator := fee.NewStaticCalculator(v.txExecutorBackend.Config.StaticFeeConfig, v.txExecutorBackend.Config.UpgradeConfig, onCommitState.GetTimestamp()) txExecutor := executor.ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -408,9 +439,10 @@ func (v *verifier) proposalBlock( // standardBlock populates the state of this block if [nil] is returned func (v *verifier) standardBlock( b *block.ApricotStandardBlock, + feeCalculator *fee.Calculator, onAcceptState state.Diff, ) error { - inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, onAcceptState, b.Parent()) + inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, feeCalculator, onAcceptState, b.Parent()) if err != nil { return err } @@ -431,20 +463,19 @@ func (v *verifier) standardBlock( return nil } -func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID ids.ID) ( +func (v *verifier) processStandardTxs(txs []*txs.Tx, feeCalculator *fee.Calculator, state state.Diff, parentID ids.ID) ( set.Set[ids.ID], map[ids.ID]*atomic.Requests, func(), error, ) { var ( - feeCalculator = fee.NewStaticCalculator(v.txExecutorBackend.Config.StaticFeeConfig, v.txExecutorBackend.Config.UpgradeConfig, state.GetTimestamp()) - onAcceptFunc func() inputs set.Set[ids.ID] funcs = make([]func(), 0, len(txs)) atomicRequests = make(map[ids.ID]*atomic.Requests) ) + for _, tx := range txs { txExecutor := executor.StandardTxExecutor{ Backend: v.txExecutorBackend, diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index d1531ea03255..913b083a6465 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -38,7 +38,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -376,10 +375,9 @@ func TestGetBalance(t *testing.T) { require := require.New(t) service, _, _ := defaultService(t) - var ( - feeCalc = fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig, service.vm.clock.Time()) - createSubnetFee, _ = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, nil) - ) + feeCalc, err := state.PickFeeCalculator(&service.vm.Config, service.vm.state) + require.NoError(err) + createSubnetFee, _ := feeCalc.CalculateFee(&txs.CreateSubnetTx{}, nil) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) diff --git a/vms/platformvm/state/chain_time_helpers.go b/vms/platformvm/state/chain_time_helpers.go index 036eb168d73d..5a5fccaed5df 100644 --- a/vms/platformvm/state/chain_time_helpers.go +++ b/vms/platformvm/state/chain_time_helpers.go @@ -9,6 +9,8 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/utils/timer/mockable" + "github.com/ava-labs/avalanchego/vms/platformvm/config" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) func NextBlockTime(state Chain, clk *mockable.Clock) (time.Time, bool, error) { @@ -68,3 +70,10 @@ func GetNextStakerChangeTime(state Chain) (time.Time, error) { return time.Time{}, database.ErrNotFound } } + +// [PickFeeCalculator] creates either a static or a dynamic fee calculator, depending on the active upgrade +// [PickFeeCalculator] does not modify [state] +func PickFeeCalculator(cfg *config.Config, state Chain) (*fee.Calculator, error) { + childBlkTime := state.GetTimestamp() + return fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, childBlkTime), nil +} diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index 0139c5d40399..0f853cebcce7 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -20,7 +20,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" @@ -67,7 +66,9 @@ func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -115,7 +116,9 @@ func TestAdvanceTimeTxTimestampTooEarly(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -152,7 +155,9 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -183,7 +188,9 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -427,7 +434,9 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -563,7 +572,9 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -644,7 +655,9 @@ func TestTrackedSubnet(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -694,7 +707,9 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -798,7 +813,9 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -898,7 +915,9 @@ func TestAdvanceTimeTxAfterBanff(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 794ac3ad282d..7f29a03f6884 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -19,7 +19,6 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -51,9 +50,9 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff) + require.NoError(err) - cfg := env.config - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -95,8 +94,8 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - cfg := env.config - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -132,8 +131,11 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - cfg := env.config - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) + builderDiff, err := state.NewDiffOn(stateDiff) + require.NoError(err) + feeCalculator, err := state.PickFeeCalculator(env.config, builderDiff) + require.NoError(err) + executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -166,8 +168,11 @@ func TestCreateChainTxValid(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - cfg := env.config - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) + builderDiff, err := state.NewDiffOn(stateDiff) + require.NoError(err) + feeCalculator, err := state.PickFeeCalculator(env.config, builderDiff) + require.NoError(err) + executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -239,7 +244,9 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff) + require.NoError(err) + executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 672560710627..9a579ec36376 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -14,7 +14,6 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/state" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -81,7 +80,9 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff) + require.NoError(err) + executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index 79082885928c..1c4dadd9002d 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -14,7 +14,6 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/state" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" @@ -78,8 +77,9 @@ func TestNewExportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) - cfg := env.config - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff) + require.NoError(err) + verifier := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index dacc3d5d910b..a3b3033df44a 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -230,8 +230,9 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - cfg := env.config - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, env.state) + require.NoError(err) + executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index 5bc5f63052fd..b972d6d240c4 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -18,7 +18,6 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/chain/p/builder" @@ -161,8 +160,9 @@ func TestNewImportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) - cfg := env.config - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff) + require.NoError(err) + verifier := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index bd050d2248ab..af249e244e9a 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -19,7 +19,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" @@ -272,7 +271,8 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -319,7 +319,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -358,7 +359,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -417,7 +419,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -471,7 +474,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -508,7 +512,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -545,7 +550,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -584,7 +590,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -655,7 +662,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -702,7 +710,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -743,7 +752,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -794,7 +804,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -842,7 +853,8 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -882,7 +894,8 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -936,7 +949,8 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -982,7 +996,8 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, diff --git a/vms/platformvm/txs/executor/reward_validator_test.go b/vms/platformvm/txs/executor/reward_validator_test.go index 4e528ad5a9f9..017aaf739290 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -21,7 +21,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" @@ -62,7 +61,8 @@ func TestRewardValidatorTxExecuteOnCommit(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAbortState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAbortState) + require.NoError(err) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -166,7 +166,8 @@ func TestRewardValidatorTxExecuteOnAbort(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAbortState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAbortState) + require.NoError(err) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -326,7 +327,8 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -471,7 +473,8 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -697,7 +700,8 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * delOnAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, delOnCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, delOnCommitState) + require.NoError(err) txExecutor := ProposalTxExecutor{ OnCommitState: delOnCommitState, OnAbortState: delOnAbortState, @@ -862,7 +866,8 @@ func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState) + require.NoError(err) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index 40e18f422b53..deaf22435f77 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -22,7 +22,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -508,14 +507,16 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { ctrl := gomock.NewController(t) var ( - backend = tt.backendF(ctrl) - state = tt.stateF(ctrl) - sTx = tt.sTxF() - tx = tt.txF() - feeCalculator = fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, state.GetTimestamp()) + backend = tt.backendF(ctrl) + chain = tt.stateF(ctrl) + sTx = tt.sTxF() + tx = tt.txF() ) - err := verifyAddPermissionlessValidatorTx(backend, feeCalculator, state, sTx, tx) + feeCalculator, err := state.PickFeeCalculator(backend.Config, chain) + require.NoError(t, err) + + err = verifyAddPermissionlessValidatorTx(backend, feeCalculator, chain, sTx, tx) require.ErrorIs(t, err, tt.expectedErr) }) } diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 7443d86a8848..b6a22a59ea13 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -33,7 +33,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -99,7 +98,8 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: stateDiff, @@ -357,7 +357,8 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { env.config.UpgradeConfig.BanffTime = onAcceptState.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -402,7 +403,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -437,7 +439,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -492,7 +495,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -542,7 +546,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -575,7 +580,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -608,7 +614,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -643,7 +650,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -711,7 +719,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -755,7 +764,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -795,7 +805,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -833,7 +844,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -881,7 +893,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -924,7 +937,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -971,7 +985,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutCurrentValidator(staker) onAcceptState.AddTx(tx, status.Committed) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1015,7 +1030,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutPendingValidator(staker) onAcceptState.AddTx(tx, status.Committed) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1058,8 +1074,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.DeleteUTXO(utxoID) } - cfg := env.config - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -1163,7 +1179,8 @@ func TestDurangoDisabledTransactions(t *testing.T) { tx := tt.buildTx(env) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(err) err = tx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1373,7 +1390,8 @@ func TestDurangoMemoField(t *testing.T) { onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState) + require.NoError(t, err) require.NoError(t, subnetValTx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1575,11 +1593,12 @@ func TestDurangoMemoField(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, env.state) + require.NoError(err) // Populated memo field should error tx, onAcceptState := tt.setupTest(env, []byte{'m', 'e', 'm', 'o'}) - err := tx.Unsigned.Visit(&StandardTxExecutor{ + err = tx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, FeeCalculator: feeCalculator, @@ -1710,7 +1729,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) // Set dependency expectations. - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil).Times(1) subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil).Times(1) @@ -1723,7 +1742,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1748,9 +1768,11 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { // Setting the subnet ID to the Primary Network ID makes the tx fail syntactic verification env.tx.Unsigned.(*txs.RemoveSubnetValidatorTx).Subnet = constants.PrimaryNetworkID env.state = state.NewMockDiff(ctrl) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.latestForkTime) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1773,12 +1795,13 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { newExecutor: func(ctrl *gomock.Controller) (*txs.RemoveSubnetValidatorTx, *StandardTxExecutor) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) env.state.EXPECT().GetPendingValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1805,11 +1828,12 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { staker.Priority = txs.SubnetPermissionlessValidatorCurrentPriority // Set dependency expectations. - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(&staker, nil).Times(1) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1834,11 +1858,12 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { // Remove credentials env.tx.Creds = nil env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1861,12 +1886,13 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { newExecutor: func(ctrl *gomock.Controller) (*txs.RemoveSubnetValidatorTx, *StandardTxExecutor) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1889,14 +1915,15 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { newExecutor: func(ctrl *gomock.Controller) (*txs.RemoveSubnetValidatorTx, *StandardTxExecutor) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil) env.fx.EXPECT().VerifyPermission(gomock.Any(), env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(errTest) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1919,7 +1946,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { newExecutor: func(ctrl *gomock.Controller) (*txs.RemoveSubnetValidatorTx, *StandardTxExecutor) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) subnetOwner := fx.NewMockOwner(ctrl) env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil) @@ -1929,7 +1956,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { ).Return(errTest) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2084,9 +2112,11 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { // Setting the tx to nil makes the tx fail syntactic verification env.tx.Unsigned = (*txs.TransformSubnetTx)(nil) env.state = state.NewMockDiff(ctrl) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.latestForkTime) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2110,10 +2140,11 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env := newValidTransformSubnetTxVerifyEnv(t, ctrl) env.unsignedTx.MaxStakeDuration = math.MaxUint32 env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2138,12 +2169,13 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { // Remove credentials env.tx.Creds = nil env.state = state.NewMockDiff(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2167,7 +2199,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env := newValidTransformSubnetTxVerifyEnv(t, ctrl) env.state = state.NewMockDiff(ctrl) subnetOwner := fx.NewMockOwner(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil) env.state.EXPECT().GetSubnetTransformation(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound).Times(1) env.fx.EXPECT().VerifyPermission(gomock.Any(), env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(nil) @@ -2178,7 +2210,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2203,7 +2236,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { // Set dependency expectations. subnetOwner := fx.NewMockOwner(ctrl) - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil).Times(1) env.state.EXPECT().GetSubnetTransformation(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound).Times(1) env.fx.EXPECT().VerifyPermission(env.unsignedTx, env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(nil).Times(1) @@ -2218,7 +2251,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, From fc9547153f23ab1c7497fdd9b076f72a4021202f Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 3 Jul 2024 10:38:56 +0200 Subject: [PATCH 048/100] nits --- vms/platformvm/service_test.go | 7 ++- .../txs/executor/staker_tx_verification.go | 52 +++++++------------ .../txs/executor/standard_tx_executor.go | 37 ++++++------- vms/platformvm/txs/fee/calculator.go | 11 ++++ vms/platformvm/txs/fee/calculator_api.go | 26 ---------- vms/platformvm/txs/fee/calculator_test.go | 2 +- vms/platformvm/txs/fee/static_calculator.go | 30 +++++------ vms/platformvm/txs/txstest/context.go | 4 +- 8 files changed, 69 insertions(+), 100 deletions(-) create mode 100644 vms/platformvm/txs/fee/calculator.go delete mode 100644 vms/platformvm/txs/fee/calculator_api.go diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index d1531ea03255..94558a75314a 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -376,10 +376,9 @@ func TestGetBalance(t *testing.T) { require := require.New(t) service, _, _ := defaultService(t) - var ( - feeCalc = fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig, service.vm.clock.Time()) - createSubnetFee, _ = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, nil) - ) + feeCalc := fee.NewStaticCalculator(service.vm.Config.StaticFeeConfig, service.vm.Config.UpgradeConfig, service.vm.clock.Time()) + createSubnetFee, err := feeCalc.CalculateFee(&txs.Tx{Unsigned: &txs.CreateSubnetTx{}}) + require.NoError(err) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index aa32a25a076a..28ba0f78d4c6 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -97,12 +97,8 @@ func verifyAddValidatorTx( []*avax.TransferableOutput, error, ) { - var ( - currentTimestamp = chainState.GetTimestamp() - upgrades = backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) - ) - if isDurangoActive { + currentTimestamp := chainState.GetTimestamp() + if backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { return nil, ErrAddValidatorTxPostDurango } @@ -111,7 +107,7 @@ func verifyAddValidatorTx( return nil, err } - if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { + if err := avax.VerifyMemoFieldLength(tx.Memo, false /*=isDurangoActive*/); err != nil { return nil, err } @@ -147,7 +143,7 @@ func verifyAddValidatorTx( return outs, nil } - if err := verifyStakerStartTime(isDurangoActive, currentTimestamp, startTime); err != nil { + if err := verifyStakerStartTime(false /*=isDurangoActive*/, currentTimestamp, startTime); err != nil { return nil, err } @@ -169,7 +165,7 @@ func verifyAddValidatorTx( // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + fee, err := feeCalculator.CalculateFee(sTx) if err != nil { return nil, err } @@ -204,8 +200,7 @@ func verifyAddSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - upgrades = backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -263,7 +258,7 @@ func verifyAddSubnetValidatorTx( // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + fee, err := feeCalculator.CalculateFee(sTx) if err != nil { return err } @@ -304,8 +299,7 @@ func verifyRemoveSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - upgrades = backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return nil, false, err @@ -344,7 +338,7 @@ func verifyRemoveSubnetValidatorTx( // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + fee, err := feeCalculator.CalculateFee(sTx) if err != nil { return nil, false, err } @@ -376,12 +370,8 @@ func verifyAddDelegatorTx( []*avax.TransferableOutput, error, ) { - var ( - currentTimestamp = chainState.GetTimestamp() - upgrades = backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) - ) - if isDurangoActive { + currentTimestamp := chainState.GetTimestamp() + if backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) { return nil, ErrAddDelegatorTxPostDurango } @@ -390,7 +380,7 @@ func verifyAddDelegatorTx( return nil, err } - if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { + if err := avax.VerifyMemoFieldLength(tx.Memo, false /*=isDurangoActive*/); err != nil { return nil, err } @@ -421,7 +411,7 @@ func verifyAddDelegatorTx( return outs, nil } - if err := verifyStakerStartTime(isDurangoActive, currentTimestamp, startTime); err != nil { + if err := verifyStakerStartTime(false /*=isDurangoActive*/, currentTimestamp, startTime); err != nil { return nil, err } @@ -439,7 +429,7 @@ func verifyAddDelegatorTx( return nil, ErrStakeOverflow } - if upgrades.IsApricotPhase3Activated(currentTimestamp) { + if backend.Config.UpgradeConfig.IsApricotPhase3Activated(currentTimestamp) { maximumWeight = min(maximumWeight, backend.Config.MaxValidatorStake) } @@ -468,7 +458,7 @@ func verifyAddDelegatorTx( // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + fee, err := feeCalculator.CalculateFee(sTx) if err != nil { return nil, err } @@ -503,8 +493,7 @@ func verifyAddPermissionlessValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - upgrades = backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -591,7 +580,7 @@ func verifyAddPermissionlessValidatorTx( // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + fee, err := feeCalculator.CalculateFee(sTx) if err != nil { return err } @@ -626,8 +615,7 @@ func verifyAddPermissionlessDelegatorTx( var ( currentTimestamp = chainState.GetTimestamp() - upgrades = backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + isDurangoActive = backend.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -739,7 +727,7 @@ func verifyAddPermissionlessDelegatorTx( // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + fee, err := feeCalculator.CalculateFee(sTx) if err != nil { return err } @@ -801,7 +789,7 @@ func verifyTransferSubnetOwnershipTx( // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, sTx.Creds) + fee, err := feeCalculator.CalculateFee(sTx) if err != nil { return err } diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 0d416678c43b..5c5e466dc049 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -57,8 +57,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { var ( currentTimestamp = e.State.GetTimestamp() - upgrades = e.Backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -71,7 +70,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + fee, err := feeCalculator.CalculateFee(e.Tx) if err != nil { return err } @@ -113,8 +112,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { var ( currentTimestamp = e.State.GetTimestamp() - upgrades = e.Backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -122,7 +120,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + fee, err := feeCalculator.CalculateFee(e.Tx) if err != nil { return err } @@ -158,8 +156,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { var ( currentTimestamp = e.State.GetTimestamp() - upgrades = e.Backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -208,7 +205,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + fee, err := feeCalculator.CalculateFee(e.Tx) if err != nil { return err } @@ -251,13 +248,16 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { var ( currentTimestamp = e.State.GetTimestamp() - upgrades = e.Backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err } + outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.ExportedOutputs)) + copy(outs, tx.Outs) + copy(outs[len(tx.Outs):], tx.ExportedOutputs) + if e.Bootstrapped.Get() { if err := verify.SameSubnet(context.TODO(), e.Ctx, tx.DestinationChain); err != nil { return err @@ -266,13 +266,10 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + fee, err := feeCalculator.CalculateFee(e.Tx) if err != nil { return err } - outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.ExportedOutputs)) - copy(outs, tx.Outs) - copy(outs[len(tx.Outs):], tx.ExportedOutputs) if err := e.FlowChecker.VerifySpend( tx, e.State, @@ -419,13 +416,14 @@ func (e *StandardTxExecutor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidat return err } - // Invariant: There are no permissioned subnet delegators to remove. if isCurrentValidator { e.State.DeleteCurrentValidator(staker) } else { e.State.DeletePendingValidator(staker) } + // Invariant: There are no permissioned subnet delegators to remove. + txID := e.Tx.ID() avax.Consume(e.State, tx.Ins) avax.Produce(e.State, txID, tx.Outs) @@ -440,8 +438,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error var ( currentTimestamp = e.State.GetTimestamp() - upgrades = e.Backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) + isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -460,7 +457,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + fee, err := feeCalculator.CalculateFee(e.Tx) if err != nil { return err } @@ -591,7 +588,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { // Verify the flowcheck feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) - fee, err := feeCalculator.CalculateFee(tx, e.Tx.Creds) + fee, err := feeCalculator.CalculateFee(e.Tx) if err != nil { return err } diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go new file mode 100644 index 000000000000..f33db9c1520f --- /dev/null +++ b/vms/platformvm/txs/fee/calculator.go @@ -0,0 +1,11 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import "github.com/ava-labs/avalanchego/vms/platformvm/txs" + +// Calculator is the interfaces that any fee Calculator must implement +type Calculator interface { + CalculateFee(tx *txs.Tx) (uint64, error) +} diff --git a/vms/platformvm/txs/fee/calculator_api.go b/vms/platformvm/txs/fee/calculator_api.go deleted file mode 100644 index 7a4ea5607b52..000000000000 --- a/vms/platformvm/txs/fee/calculator_api.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package fee - -import ( - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" -) - -// Calculator is a wrapper to exposed a more user friendly API than txs.Visitor allows -// backend is not embedded to avoid exposing unnecessary methods -type Calculator struct { - b backend -} - -func (c *Calculator) CalculateFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) { - return c.b.calculateFee(tx, creds) -} - -// backend is the interfaces that any fee backend must implement -type backend interface { - txs.Visitor - - calculateFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) -} diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 02dc0e9dfc54..454072e9df8d 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -189,7 +189,7 @@ func TestTxFees(t *testing.T) { t.Run(tt.name, func(t *testing.T) { uTx := tt.unsignedTx() fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) - fee, err := fc.CalculateFee(uTx, nil) + fee, err := fc.CalculateFee(&txs.Tx{Unsigned: uTx}) require.NoError(t, err) require.Equal(t, tt.expected, fee) }) diff --git a/vms/platformvm/txs/fee/static_calculator.go b/vms/platformvm/txs/fee/static_calculator.go index 5c78a34f1a59..7bfb5cf799a0 100644 --- a/vms/platformvm/txs/fee/static_calculator.go +++ b/vms/platformvm/txs/fee/static_calculator.go @@ -7,24 +7,24 @@ import ( "time" "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" ) -var _ backend = (*staticCalculator)(nil) +var ( + _ Calculator = (*staticCalculator)(nil) + _ txs.Visitor = (*staticCalculator)(nil) +) func NewStaticCalculator( config StaticConfig, upgradeTimes upgrade.Config, chainTime time.Time, -) *Calculator { - return &Calculator{ - b: &staticCalculator{ - upgrades: upgradeTimes, - staticCfg: config, - time: chainTime, - }, +) Calculator { + return &staticCalculator{ + upgrades: upgradeTimes, + staticCfg: config, + time: chainTime, } } @@ -38,6 +38,12 @@ type staticCalculator struct { fee uint64 } +func (c *staticCalculator) CalculateFee(tx *txs.Tx) (uint64, error) { + c.fee = 0 // zero fee among different calculateFee invocations (unlike gas which gets cumulated) + err := tx.Unsigned.Visit(c) + return c.fee, err +} + func (c *staticCalculator) AddValidatorTx(*txs.AddValidatorTx) error { c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee return nil @@ -128,9 +134,3 @@ func (c *staticCalculator) ExportTx(*txs.ExportTx) error { c.fee = c.staticCfg.TxFee return nil } - -func (c *staticCalculator) calculateFee(tx txs.UnsignedTx, _ []verify.Verifiable) (uint64, error) { - c.fee = 0 // zero fee among different calculateFee invocations (unlike gas which gets cumulated) - err := tx.Visit(c) - return c.fee, err -} diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index d8e24796f9fc..d8ca8c32853d 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -20,8 +20,8 @@ func newContext( ) *builder.Context { var ( feeCalc = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, timestamp) - createSubnetFee, _ = feeCalc.CalculateFee(&txs.CreateSubnetTx{}, nil) - createChainFee, _ = feeCalc.CalculateFee(&txs.CreateChainTx{}, nil) + createSubnetFee, _ = feeCalc.CalculateFee(&txs.Tx{Unsigned: &txs.CreateSubnetTx{}}) + createChainFee, _ = feeCalc.CalculateFee(&txs.Tx{Unsigned: &txs.CreateChainTx{}}) ) return &builder.Context{ From 270ab49229b822c629e6fee066c50a0799319093 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 15 Jul 2024 09:46:46 +0200 Subject: [PATCH 049/100] introduced dynamic fee calculator --- vms/components/fee/calculator.go | 119 +++ vms/components/fee/calculator_test.go | 125 +++ vms/components/fee/config.go | 60 ++ vms/components/fee/dimensions.go | 70 ++ vms/components/fee/helpers.go | 66 ++ vms/platformvm/txs/fee/calculator.go | 16 +- vms/platformvm/txs/fee/calculator_test.go | 979 ++++++++++++++++--- vms/platformvm/txs/fee/dynamic_calculator.go | 312 ++++++ vms/platformvm/txs/fee/dynamic_config.go | 60 ++ vms/platformvm/txs/fee/static_calculator.go | 31 + 10 files changed, 1722 insertions(+), 116 deletions(-) create mode 100644 vms/components/fee/calculator.go create mode 100644 vms/components/fee/calculator_test.go create mode 100644 vms/components/fee/config.go create mode 100644 vms/components/fee/dimensions.go create mode 100644 vms/components/fee/helpers.go create mode 100644 vms/platformvm/txs/fee/dynamic_calculator.go create mode 100644 vms/platformvm/txs/fee/dynamic_config.go diff --git a/vms/components/fee/calculator.go b/vms/components/fee/calculator.go new file mode 100644 index 000000000000..1a5fcdb2c066 --- /dev/null +++ b/vms/components/fee/calculator.go @@ -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: %w", errGasBoundBreached, err) + } + + 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)) +} diff --git a/vms/components/fee/calculator_test.go b/vms/components/fee/calculator_test.go new file mode 100644 index 000000000000..f2589fcc2ba4 --- /dev/null +++ b/vms/components/fee/calculator_test.go @@ -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) +} diff --git a/vms/components/fee/config.go b/vms/components/fee/config.go new file mode 100644 index 000000000000..28a2059b65e0 --- /dev/null +++ b/vms/components/fee/config.go @@ -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 +} diff --git a/vms/components/fee/dimensions.go b/vms/components/fee/dimensions.go new file mode 100644 index 000000000000..286dc29813f0 --- /dev/null +++ b/vms/components/fee/dimensions.go @@ -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 +} diff --git a/vms/components/fee/helpers.go b/vms/components/fee/helpers.go new file mode 100644 index 000000000000..26cc300b3cc9 --- /dev/null +++ b/vms/components/fee/helpers.go @@ -0,0 +1,66 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "fmt" + + "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/wrappers" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +func MeterInput(c codec.Manager, v uint16, in *avax.TransferableInput) (Dimensions, error) { + cost, err := in.In.Cost() + if err != nil { + return Empty, fmt.Errorf("failed retrieving cost of input %s: %w", in.ID, err) + } + + inSize, err := c.Size(v, in) + if err != nil { + return Empty, fmt.Errorf("failed retrieving size of input %s: %w", in.ID, err) + } + uInSize := uint64(inSize) + + complexity := Empty + complexity[Bandwidth] += uInSize - codec.VersionSize + complexity[DBRead] += uInSize // inputs are read + complexity[DBWrite] += uInSize // inputs are deleted + complexity[Compute] += cost + return complexity, nil +} + +func MeterOutput(c codec.Manager, v uint16, out *avax.TransferableOutput) (Dimensions, error) { + outSize, err := c.Size(v, out) + if err != nil { + return Empty, fmt.Errorf("failed retrieving size of output %s: %w", out.ID, err) + } + uOutSize := uint64(outSize) + + complexity := Empty + complexity[Bandwidth] += uOutSize - codec.VersionSize + complexity[DBWrite] += uOutSize + return complexity, nil +} + +func MeterCredential(c codec.Manager, v uint16, keysCount int) (Dimensions, error) { + // Ensure that codec picks interface instead of the pointer to evaluate size. + creds := make([]verify.Verifiable, 0, 1) + creds = append(creds, &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, keysCount), + }) + + credSize, err := c.Size(v, creds) + if err != nil { + return Empty, fmt.Errorf("failed retrieving size of credentials: %w", err) + } + credSize -= wrappers.IntLen // length of the slice, we want the single credential + + complexity := Empty + complexity[Bandwidth] += uint64(credSize) - codec.VersionSize + return complexity, nil +} diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index f33db9c1520f..1cfc62c581a7 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -3,9 +3,23 @@ package fee -import "github.com/ava-labs/avalanchego/vms/platformvm/txs" +import ( + "github.com/ava-labs/avalanchego/vms/components/fee" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" +) // Calculator is the interfaces that any fee Calculator must implement type Calculator interface { CalculateFee(tx *txs.Tx) (uint64, error) + + GetFee() uint64 + ResetFee(newFee uint64) + AddFeesFor(complexity fee.Dimensions) (uint64, error) + RemoveFeesFor(unitsToRm fee.Dimensions) (uint64, error) + GetGasPrice() fee.GasPrice + GetBlockGas() (fee.Gas, error) + GetGasCap() fee.Gas + setCredentials(creds []verify.Verifiable) + IsEActive() bool } diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 454072e9df8d..f0652a90accf 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -4,18 +4,84 @@ package fee import ( + "errors" "testing" "time" "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/fee" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) +var ( + testFeeWeights = fee.Dimensions{1, 1, 1, 1} + testGasPrice = fee.GasPrice(10 * units.NanoAvax) + testBlockMaxGas = fee.Gas(100_000) + + preFundedKeys = secp256k1.TestKeys() + feeTestSigners = [][]*secp256k1.PrivateKey{preFundedKeys} + feeTestDefaultStakeWeight = uint64(2024) + + errFailedComplexityCumulation = errors.New("failed cumulating complexity") +) + +func TestAddAndRemoveFees(t *testing.T) { + r := require.New(t) + + fc := NewDynamicCalculator(fee.NewCalculator(testFeeWeights, testGasPrice, testBlockMaxGas)) + + var ( + units = fee.Dimensions{1, 2, 3, 4} + gas = fee.Gas(1) + doubleGas = fee.Gas(2) + ) + + feeDelta, err := fc.AddFeesFor(units) + r.NoError(err) + + haveGas, err := fc.GetBlockGas() + r.NoError(err) + r.Equal(gas, haveGas) + r.NotZero(feeDelta) + r.Equal(feeDelta, fc.GetFee()) + + feeDelta2, err := fc.AddFeesFor(units) + r.NoError(err) + haveGas, err = fc.GetBlockGas() + r.NoError(err) + r.Equal(doubleGas, haveGas) + r.Equal(feeDelta, feeDelta2) + r.Equal(feeDelta+feeDelta2, fc.GetFee()) + + feeDelta3, err := fc.RemoveFeesFor(units) + r.NoError(err) + haveGas, err = fc.GetBlockGas() + r.NoError(err) + r.Equal(gas, haveGas) + r.Equal(feeDelta, feeDelta3) + r.Equal(feeDelta, fc.GetFee()) + + feeDelta4, err := fc.RemoveFeesFor(units) + r.NoError(err) + r.Zero(fc.GetBlockGas()) + r.Equal(feeDelta, feeDelta4) + r.Zero(fc.GetFee()) +} + func TestTxFees(t *testing.T) { feeTestsDefaultCfg := StaticConfig{ TxFee: 1 * units.Avax, @@ -40,214 +106,897 @@ func TestTxFees(t *testing.T) { } // chain times needed to have specific upgrades active + postEUpgradeTime := upgrades.EUpgradeTime.Add(time.Second) preEUpgradeTime := upgrades.EUpgradeTime.Add(-1 * time.Second) preApricotPhase3Time := upgrades.ApricotPhase3Time.Add(-1 * time.Second) tests := []struct { - name string - chainTime time.Time - unsignedTx func() txs.UnsignedTx - expected uint64 + name string + chainTime time.Time + signedTxF func(t *testing.T) *txs.Tx + gasCapF func() fee.Gas + expectedError error + checksF func(*testing.T, Calculator) }{ { - name: "AddValidatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: addValidatorTx, - expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, + name: "AddValidatorTx pre EUpgrade", + chainTime: preEUpgradeTime, + signedTxF: addValidatorTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, c.GetFee()) + }, + }, + { + name: "AddValidatorTx post EUpgrade", + chainTime: postEUpgradeTime, + expectedError: errFailedFeeCalculation, + signedTxF: addValidatorTx, + checksF: func(*testing.T, Calculator) {}, + }, + { + name: "AddSubnetValidatorTx pre EUpgrade", + chainTime: preEUpgradeTime, + signedTxF: addSubnetValidatorTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddSubnetValidatorFee, c.GetFee()) + }, + }, + { + name: "AddSubnetValidatorTx post EUpgrade, success", + chainTime: postEUpgradeTime, + expectedError: nil, + signedTxF: addSubnetValidatorTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 2_910*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(291), haveGas) + }, + }, + { + name: "AddSubnetValidatorTx post EUpgrade, utxos read cap breached", + chainTime: postEUpgradeTime, + gasCapF: func() fee.Gas { + return testBlockMaxGas - 1 + }, + signedTxF: addSubnetValidatorTx, + expectedError: errFailedComplexityCumulation, + checksF: func(*testing.T, Calculator) {}, + }, + { + name: "AddDelegatorTx pre EUpgrade", + chainTime: preEUpgradeTime, + signedTxF: addDelegatorTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, c.GetFee()) + }, + }, + { + name: "AddDelegatorTx post EUpgrade", + chainTime: postEUpgradeTime, + expectedError: errFailedFeeCalculation, + signedTxF: addDelegatorTx, + checksF: func(*testing.T, Calculator) {}, + }, + { + name: "CreateChainTx pre ApricotPhase3", + chainTime: preApricotPhase3Time, + signedTxF: createChainTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.CreateAssetTxFee, c.GetFee()) + }, + }, + { + name: "CreateChainTx pre EUpgrade", + chainTime: preEUpgradeTime, + signedTxF: createChainTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.CreateBlockchainTxFee, c.GetFee()) + }, + }, + { + name: "CreateChainTx post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: createChainTx, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 1_950*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(195), haveGas) + }, + }, + { + name: "CreateChainTx post EUpgrade, utxos read cap breached", + chainTime: postEUpgradeTime, + signedTxF: createChainTx, + gasCapF: func() fee.Gas { + return testBlockMaxGas - 1 + }, + expectedError: errFailedComplexityCumulation, + checksF: func(*testing.T, Calculator) {}, + }, + { + name: "CreateSubnetTx pre ApricotPhase3", + chainTime: preApricotPhase3Time, + signedTxF: createSubnetTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.CreateAssetTxFee, c.GetFee()) + }, + }, + { + name: "CreateSubnetTx pre EUpgrade", + chainTime: preEUpgradeTime, + signedTxF: createSubnetTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.CreateSubnetTxFee, c.GetFee()) + }, + }, + { + name: "CreateSubnetTx post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: createSubnetTx, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 1_850*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(185), haveGas) + }, }, { - name: "AddSubnetValidatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: addSubnetValidatorTx, - expected: feeTestsDefaultCfg.AddSubnetValidatorFee, + name: "CreateSubnetTx post EUpgrade, utxos read cap breached", + chainTime: postEUpgradeTime, + signedTxF: createSubnetTx, + gasCapF: func() fee.Gas { + return testBlockMaxGas - 1 + }, + expectedError: errFailedComplexityCumulation, + checksF: func(*testing.T, Calculator) {}, }, { - name: "AddDelegatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: addDelegatorTx, - expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, + name: "RemoveSubnetValidatorTx pre EUpgrade", + chainTime: preEUpgradeTime, + signedTxF: removeSubnetValidatorTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) + }, }, { - name: "CreateChainTx pre ApricotPhase3", - chainTime: preApricotPhase3Time, - unsignedTx: createChainTx, - expected: feeTestsDefaultCfg.CreateAssetTxFee, + name: "RemoveSubnetValidatorTx post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: removeSubnetValidatorTx, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 2_880*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(288), haveGas) + }, }, { - name: "CreateChainTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: createChainTx, - expected: feeTestsDefaultCfg.CreateBlockchainTxFee, + name: "RemoveSubnetValidatorTx post EUpgrade, utxos read cap breached", + chainTime: postEUpgradeTime, + gasCapF: func() fee.Gas { + return testBlockMaxGas - 1 + }, + signedTxF: removeSubnetValidatorTx, + expectedError: errFailedComplexityCumulation, + checksF: func(*testing.T, Calculator) {}, }, { - name: "CreateSubnetTx pre ApricotPhase3", - chainTime: preApricotPhase3Time, - unsignedTx: createSubnetTx, - expected: feeTestsDefaultCfg.CreateAssetTxFee, + name: "TransformSubnetTx pre EUpgrade", + chainTime: preEUpgradeTime, + signedTxF: transformSubnetTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.TransformSubnetTxFee, c.GetFee()) + }, }, { - name: "CreateSubnetTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: createSubnetTx, - expected: feeTestsDefaultCfg.CreateSubnetTxFee, + name: "TransformSubnetTx post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: transformSubnetTx, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 1_970*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(197), haveGas) + }, }, { - name: "RemoveSubnetValidatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: removeSubnetValidatorTx, - expected: feeTestsDefaultCfg.TxFee, + name: "TransformSubnetTx post EUpgrade, utxos read cap breached", + chainTime: postEUpgradeTime, + gasCapF: func() fee.Gas { + return testBlockMaxGas - 1 + }, + signedTxF: transformSubnetTx, + expectedError: errFailedComplexityCumulation, + checksF: func(*testing.T, Calculator) {}, + }, + { + name: "TransferSubnetOwnershipTx pre EUpgrade", + chainTime: preEUpgradeTime, + signedTxF: transferSubnetOwnershipTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) + }, }, { - name: "TransformSubnetTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: transformSubnetTx, - expected: feeTestsDefaultCfg.TransformSubnetTxFee, + name: "TransferSubnetOwnershipTx post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: transferSubnetOwnershipTx, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 1_900*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(190), haveGas) + }, }, { - name: "TransferSubnetOwnershipTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: transferSubnetOwnershipTx, - expected: feeTestsDefaultCfg.TxFee, + name: "TransferSubnetOwnershipTx post EUpgrade, utxos read cap breached", + chainTime: postEUpgradeTime, + gasCapF: func() fee.Gas { + return testBlockMaxGas - 1 + }, + signedTxF: transferSubnetOwnershipTx, + expectedError: errFailedComplexityCumulation, + checksF: func(*testing.T, Calculator) {}, }, { name: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { - return addPermissionlessValidatorTx(constants.PrimaryNetworkID) + chainTime: preEUpgradeTime, + signedTxF: func(t *testing.T) *txs.Tx { + return addPermissionlessValidatorTx(t, constants.PrimaryNetworkID) + }, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, c.GetFee()) }, - expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, }, { name: "AddPermissionlessValidatorTx Subnet pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { + chainTime: preEUpgradeTime, + signedTxF: func(t *testing.T) *txs.Tx { + subnetID := ids.GenerateTestID() + require.NotEqual(t, constants.PrimaryNetworkID, subnetID) + return addPermissionlessValidatorTx(t, subnetID) + }, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddSubnetValidatorFee, c.GetFee()) + }, + }, + { + name: "AddPermissionlessValidatorTx Primary Network post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: func(t *testing.T) *txs.Tx { + return addPermissionlessValidatorTx(t, constants.PrimaryNetworkID) + }, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 3_310*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(331), haveGas) + }, + }, + { + name: "AddPermissionlessValidatorTx Subnet post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: func(t *testing.T) *txs.Tx { subnetID := ids.GenerateTestID() require.NotEqual(t, constants.PrimaryNetworkID, subnetID) - return addPermissionlessValidatorTx(subnetID) + return addPermissionlessValidatorTx(t, subnetID) + }, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 3_310*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(331), haveGas) }, - expected: feeTestsDefaultCfg.AddSubnetValidatorFee, + }, + { + name: "AddPermissionlessValidatorTx post EUpgrade, utxos read cap breached", + chainTime: postEUpgradeTime, + gasCapF: func() fee.Gas { + return testBlockMaxGas - 1 + }, + signedTxF: func(t *testing.T) *txs.Tx { + subnetID := ids.GenerateTestID() + return addPermissionlessValidatorTx(t, subnetID) + }, + expectedError: errFailedComplexityCumulation, + checksF: func(*testing.T, Calculator) {}, }, { name: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { - return addPermissionlessDelegatorTx(constants.PrimaryNetworkID) + chainTime: preEUpgradeTime, + signedTxF: func(t *testing.T) *txs.Tx { + return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) + }, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, c.GetFee()) }, - expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, }, { name: "AddPermissionlessDelegatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { + chainTime: preEUpgradeTime, + signedTxF: func(t *testing.T) *txs.Tx { subnetID := ids.GenerateTestID() require.NotEqual(t, constants.PrimaryNetworkID, subnetID) - return addPermissionlessDelegatorTx(subnetID) + return addPermissionlessDelegatorTx(t, subnetID) + }, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddSubnetDelegatorFee, c.GetFee()) }, - expected: feeTestsDefaultCfg.AddSubnetDelegatorFee, }, { - name: "BaseTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: baseTx, - expected: feeTestsDefaultCfg.TxFee, + name: "AddPermissionlessDelegatorTx Primary Network post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: func(t *testing.T) *txs.Tx { + return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) + }, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 3_120*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(312), haveGas) + }, }, { - name: "ImportTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: importTx, - expected: feeTestsDefaultCfg.TxFee, + name: "AddPermissionlessDelegatorTx Subnet post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: func(t *testing.T) *txs.Tx { + return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) + }, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 3_120*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(312), haveGas) + }, }, { - name: "ExportTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: exportTx, - expected: feeTestsDefaultCfg.TxFee, + name: "AddPermissionlessDelegatorTx Subnet post EUpgrade, utxos read cap breached", + chainTime: postEUpgradeTime, + gasCapF: func() fee.Gas { + return testBlockMaxGas - 1 + }, + signedTxF: func(t *testing.T) *txs.Tx { + subnetID := ids.GenerateTestID() + require.NotEqual(t, constants.PrimaryNetworkID, subnetID) + return addPermissionlessValidatorTx(t, subnetID) + }, + expectedError: errFailedComplexityCumulation, + checksF: func(*testing.T, Calculator) {}, + }, + { + name: "BaseTx pre EUpgrade", + chainTime: preEUpgradeTime, + signedTxF: baseTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) + }, + }, + { + name: "BaseTx post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: baseTx, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 1_810*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(181), haveGas) + }, + }, + { + name: "BaseTx post EUpgrade, utxos read cap breached", + chainTime: postEUpgradeTime, + gasCapF: func() fee.Gas { + return testBlockMaxGas - 1 + }, + signedTxF: baseTx, + expectedError: errFailedComplexityCumulation, + checksF: func(*testing.T, Calculator) {}, + }, + { + name: "ImportTx pre EUpgrade", + chainTime: preEUpgradeTime, + signedTxF: importTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) + }, + }, + { + name: "ImportTx post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: importTx, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 3_120*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(312), haveGas) + }, + }, + { + name: "ImportTx post EUpgrade, utxos read cap breached", + chainTime: postEUpgradeTime, + gasCapF: func() fee.Gas { + return testBlockMaxGas - 1 + }, + signedTxF: importTx, + expectedError: errFailedComplexityCumulation, + checksF: func(*testing.T, Calculator) {}, + }, + { + name: "ExportTx pre EUpgrade", + chainTime: preEUpgradeTime, + signedTxF: exportTx, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) + }, + }, + { + name: "ExportTx post EUpgrade, success", + chainTime: postEUpgradeTime, + signedTxF: exportTx, + expectedError: nil, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, 2_040*units.NanoAvax, c.GetFee()) + haveGas, err := c.GetBlockGas() + require.NoError(t, err) + require.Equal(t, fee.Gas(204), haveGas) + }, + }, + { + name: "ExportTx post EUpgrade, utxos read cap breached", + chainTime: postEUpgradeTime, + gasCapF: func() fee.Gas { + return testBlockMaxGas - 1 + }, + signedTxF: exportTx, + expectedError: errFailedComplexityCumulation, + checksF: func(*testing.T, Calculator) {}, }, { name: "RewardValidatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { - return &txs.RewardValidatorTx{ - TxID: ids.GenerateTestID(), + chainTime: preEUpgradeTime, + signedTxF: func(_ *testing.T) *txs.Tx { + return &txs.Tx{ + Unsigned: &txs.RewardValidatorTx{ + TxID: ids.GenerateTestID(), + }, + } + }, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, uint64(0), c.GetFee()) + }, + }, + { + name: "RewardValidatorTx post EUpgrade", + chainTime: postEUpgradeTime, + signedTxF: func(_ *testing.T) *txs.Tx { + return &txs.Tx{ + Unsigned: &txs.RewardValidatorTx{ + TxID: ids.GenerateTestID(), + }, } }, - expected: 0, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, uint64(0), c.GetFee()) + }, }, { name: "AdvanceTimeTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { - return &txs.AdvanceTimeTx{ - Time: uint64(time.Now().Unix()), + chainTime: preEUpgradeTime, + signedTxF: func(_ *testing.T) *txs.Tx { + return &txs.Tx{ + Unsigned: &txs.AdvanceTimeTx{ + Time: uint64(time.Now().Unix()), + }, + } + }, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, uint64(0), c.GetFee()) + }, + }, + { + name: "AdvanceTimeTx post EUpgrade", + chainTime: postEUpgradeTime, + signedTxF: func(_ *testing.T) *txs.Tx { + return &txs.Tx{ + Unsigned: &txs.AdvanceTimeTx{ + Time: uint64(time.Now().Unix()), + }, } }, - expected: 0, + checksF: func(t *testing.T, c Calculator) { + require.Equal(t, uint64(0), c.GetFee()) + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - uTx := tt.unsignedTx() - fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) - fee, err := fc.CalculateFee(&txs.Tx{Unsigned: uTx}) - require.NoError(t, err) - require.Equal(t, tt.expected, fee) + gasCap := testBlockMaxGas + if tt.gasCapF != nil { + gasCap = tt.gasCapF() + } + + var c Calculator + if !upgrades.IsEActivated(tt.chainTime) { + c = NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) + } else { + c = NewDynamicCalculator(fee.NewCalculator(testFeeWeights, testGasPrice, gasCap)) + } + + sTx := tt.signedTxF(t) + _, _ = c.CalculateFee(sTx) + tt.checksF(t, c) }) } } -func addValidatorTx() txs.UnsignedTx { - return &txs.AddValidatorTx{} +func addValidatorTx(t *testing.T) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, stakes, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.AddValidatorTx{ + BaseTx: baseTx, + Validator: txs.Validator{ + NodeID: defaultCtx.NodeID, + Start: uint64(time.Now().Truncate(time.Second).Unix()), + End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), + Wght: feeTestDefaultStakeWeight, + }, + StakeOuts: stakes, + RewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + DelegationShares: reward.PercentDenominator, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + + return sTx } -func addSubnetValidatorTx() txs.UnsignedTx { - return &txs.AddSubnetValidatorTx{} +func addSubnetValidatorTx(t *testing.T) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + subnetID := ids.GenerateTestID() + baseTx, _, subnetAuth := txsCreationHelpers(defaultCtx) + uTx := &txs.AddSubnetValidatorTx{ + BaseTx: baseTx, + SubnetValidator: txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: defaultCtx.NodeID, + Start: uint64(time.Now().Truncate(time.Second).Unix()), + End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), + Wght: feeTestDefaultStakeWeight, + }, + Subnet: subnetID, + }, + SubnetAuth: subnetAuth, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx } -func addDelegatorTx() txs.UnsignedTx { - return &txs.AddDelegatorTx{} +func addDelegatorTx(t *testing.T) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, stakes, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.AddDelegatorTx{ + BaseTx: baseTx, + Validator: txs.Validator{ + NodeID: defaultCtx.NodeID, + Start: uint64(time.Now().Truncate(time.Second).Unix()), + End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), + Wght: feeTestDefaultStakeWeight, + }, + StakeOuts: stakes, + DelegationRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx } -func createChainTx() txs.UnsignedTx { - return &txs.CreateChainTx{} +func createChainTx(t *testing.T) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, subnetAuth := txsCreationHelpers(defaultCtx) + uTx := &txs.CreateChainTx{ + BaseTx: baseTx, + SubnetID: ids.GenerateTestID(), + ChainName: "testingStuff", + VMID: ids.GenerateTestID(), + FxIDs: []ids.ID{ids.GenerateTestID()}, + GenesisData: []byte{0xff}, + SubnetAuth: subnetAuth, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx } -func createSubnetTx() txs.UnsignedTx { - return &txs.CreateSubnetTx{} +func createSubnetTx(t *testing.T) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.CreateSubnetTx{ + BaseTx: baseTx, + Owner: &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx } -func removeSubnetValidatorTx() txs.UnsignedTx { - return &txs.RemoveSubnetValidatorTx{} +func removeSubnetValidatorTx(t *testing.T) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, auth := txsCreationHelpers(defaultCtx) + uTx := &txs.RemoveSubnetValidatorTx{ + BaseTx: baseTx, + NodeID: ids.GenerateTestNodeID(), + Subnet: ids.GenerateTestID(), + SubnetAuth: auth, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx } -func transformSubnetTx() txs.UnsignedTx { - return &txs.TransformSubnetTx{} +func transformSubnetTx(t *testing.T) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, auth := txsCreationHelpers(defaultCtx) + uTx := &txs.TransformSubnetTx{ + BaseTx: baseTx, + Subnet: ids.GenerateTestID(), + AssetID: ids.GenerateTestID(), + InitialSupply: 0x1000000000000000, + MaximumSupply: 0x1000000000000000, + MinConsumptionRate: 0, + MaxConsumptionRate: 0, + MinValidatorStake: 1, + MaxValidatorStake: 0x1000000000000000, + MinStakeDuration: 1, + MaxStakeDuration: 1, + MinDelegationFee: 0, + MinDelegatorStake: 0xffffffffffffffff, + MaxValidatorWeightFactor: 255, + UptimeRequirement: 0, + SubnetAuth: auth, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx } -func transferSubnetOwnershipTx() txs.UnsignedTx { - return &txs.TransferSubnetOwnershipTx{} +func transferSubnetOwnershipTx(t *testing.T) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.TransferSubnetOwnershipTx{ + BaseTx: baseTx, + Subnet: ids.GenerateTestID(), + SubnetAuth: &secp256k1fx.Input{ + SigIndices: []uint32{3}, + }, + Owner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx } -func addPermissionlessValidatorTx(subnetID ids.ID) txs.UnsignedTx { - return &txs.AddPermissionlessValidatorTx{ - Subnet: subnetID, +func addPermissionlessValidatorTx(t *testing.T, subnetID ids.ID) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, stakes, _ := txsCreationHelpers(defaultCtx) + sk, err := bls.NewSecretKey() + r.NoError(err) + uTx := &txs.AddPermissionlessValidatorTx{ + BaseTx: baseTx, + Subnet: subnetID, + Signer: signer.NewProofOfPossession(sk), + StakeOuts: stakes, + ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + DelegationShares: reward.PercentDenominator, } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx } -func addPermissionlessDelegatorTx(subnetID ids.ID) txs.UnsignedTx { - return &txs.AddPermissionlessDelegatorTx{ - Subnet: subnetID, +func addPermissionlessDelegatorTx(t *testing.T, subnetID ids.ID) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, stakes, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.AddPermissionlessDelegatorTx{ + BaseTx: baseTx, + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: 12345, + End: 12345 + 200*24*60*60, + Wght: 2 * units.KiloAvax, + }, + Subnet: subnetID, + StakeOuts: stakes, + DelegationRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx +} + +func baseTx(t *testing.T) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, _ := txsCreationHelpers(defaultCtx) + uTx := &baseTx + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx } -func baseTx() txs.UnsignedTx { - return &txs.BaseTx{} +func importTx(t *testing.T) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, _, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.ImportTx{ + BaseTx: baseTx, + SourceChain: ids.GenerateTestID(), + ImportedInputs: []*avax.TransferableInput{{ + UTXOID: avax.UTXOID{ + TxID: ids.Empty.Prefix(1), + OutputIndex: 1, + }, + Asset: avax.Asset{ID: ids.ID{'a', 's', 's', 'e', 'r', 't'}}, + In: &secp256k1fx.TransferInput{ + Amt: 50000, + Input: secp256k1fx.Input{SigIndices: []uint32{0}}, + }, + }}, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx } -func importTx() txs.UnsignedTx { - return &txs.ImportTx{} +func exportTx(t *testing.T) *txs.Tx { + r := require.New(t) + + defaultCtx := snowtest.Context(t, snowtest.PChainID) + + baseTx, outputs, _ := txsCreationHelpers(defaultCtx) + uTx := &txs.ExportTx{ + BaseTx: baseTx, + DestinationChain: ids.GenerateTestID(), + ExportedOutputs: outputs, + } + sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) + r.NoError(err) + return sTx } -func exportTx() txs.UnsignedTx { - return &txs.ExportTx{} +func txsCreationHelpers(defaultCtx *snow.Context) ( + baseTx txs.BaseTx, + stakes []*avax.TransferableOutput, + auth *secp256k1fx.Input, +) { + inputs := []*avax.TransferableInput{{ + UTXOID: avax.UTXOID{ + TxID: ids.ID{'t', 'x', 'I', 'D'}, + OutputIndex: 2, + }, + Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, + In: &secp256k1fx.TransferInput{ + Amt: uint64(5678), + Input: secp256k1fx.Input{SigIndices: []uint32{0}}, + }, + }} + outputs := []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: uint64(1234), + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + }, + }} + stakes = []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, + Out: &stakeable.LockOut{ + Locktime: uint64(time.Now().Add(time.Second).Unix()), + TransferableOut: &secp256k1fx.TransferOutput{ + Amt: feeTestDefaultStakeWeight, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + }, + }, + }} + auth = &secp256k1fx.Input{ + SigIndices: []uint32{0, 1}, + } + baseTx = txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: defaultCtx.NetworkID, + BlockchainID: defaultCtx.ChainID, + Ins: inputs, + Outs: outputs, + }, + } + + return baseTx, stakes, auth } diff --git a/vms/platformvm/txs/fee/dynamic_calculator.go b/vms/platformvm/txs/fee/dynamic_calculator.go new file mode 100644 index 000000000000..3b28858733a0 --- /dev/null +++ b/vms/platformvm/txs/fee/dynamic_calculator.go @@ -0,0 +1,312 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "errors" + "fmt" + + "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/utils/wrappers" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/fee" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +const StakerLookupCost uint64 = 1000 // equal to secp256k1fx.CostPerSignature + +var ( + _ Calculator = (*dynamicCalculator)(nil) + _ txs.Visitor = (*staticCalculator)(nil) + + errFailedFeeCalculation = errors.New("failed fee calculation") +) + +func NewDynamicCalculator(fc *fee.Calculator) Calculator { + return &dynamicCalculator{ + fc: fc, + buildingTx: false, + // credentials are set when computeFee is called + } +} + +func NewBuildingDynamicCalculator(fc *fee.Calculator) Calculator { + return &dynamicCalculator{ + fc: fc, + buildingTx: true, + // credentials are set when computeFee is called + } +} + +type dynamicCalculator struct { + // inputs + fc *fee.Calculator + cred []verify.Verifiable + + buildingTx bool + + // outputs of visitor execution + fee uint64 +} + +func (c *dynamicCalculator) CalculateFee(tx *txs.Tx) (uint64, error) { + c.setCredentials(tx.Creds) + c.fee = 0 // zero fee among different calculateFee invocations (unlike gas which gets cumulated) + err := tx.Unsigned.Visit(c) + if !c.buildingTx { + err = errors.Join(err, c.fc.DoneWithLatestTx()) + } + return c.fee, err +} + +func (c *dynamicCalculator) AddFeesFor(complexity fee.Dimensions) (uint64, error) { + fee, err := c.fc.AddFeesFor(complexity) + if err != nil { + return 0, fmt.Errorf("failed cumulating complexity: %w", err) + } + + extraFee := fee - c.fee + c.fee = fee + return extraFee, nil +} + +func (c *dynamicCalculator) RemoveFeesFor(unitsToRm fee.Dimensions) (uint64, error) { + fee, err := c.fc.RemoveFeesFor(unitsToRm) + if err != nil { + return 0, fmt.Errorf("failed removing complexity: %w", err) + } + + removedFee := c.fee - fee + c.fee = fee + return removedFee, nil +} + +func (c *dynamicCalculator) GetFee() uint64 { return c.fee } + +func (c *dynamicCalculator) ResetFee(newFee uint64) { + c.fee = newFee +} + +func (c *dynamicCalculator) GetGasPrice() fee.GasPrice { return c.fc.GetGasPrice() } + +func (c *dynamicCalculator) GetBlockGas() (fee.Gas, error) { return c.fc.GetBlockGas() } + +func (c *dynamicCalculator) GetGasCap() fee.Gas { return c.fc.GetGasCap() } + +func (c *dynamicCalculator) setCredentials(creds []verify.Verifiable) { + c.cred = creds +} + +func (*dynamicCalculator) IsEActive() bool { return true } + +func (*dynamicCalculator) AddValidatorTx(*txs.AddValidatorTx) error { + // AddValidatorTx is banned following Durango activation + return errFailedFeeCalculation +} + +func (c *dynamicCalculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { + complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + complexity[fee.Compute] += StakerLookupCost + + _, err = c.AddFeesFor(complexity) + return err +} + +func (*dynamicCalculator) AddDelegatorTx(*txs.AddDelegatorTx) error { + // AddDelegatorTx is banned following Durango activation + return errFailedFeeCalculation +} + +func (c *dynamicCalculator) CreateChainTx(tx *txs.CreateChainTx) error { + complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = c.AddFeesFor(complexity) + return err +} + +func (c *dynamicCalculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { + complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = c.AddFeesFor(complexity) + return err +} + +func (c *dynamicCalculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + c.fee = 0 // no fees + return nil +} + +func (c *dynamicCalculator) RewardValidatorTx(*txs.RewardValidatorTx) error { + c.fee = 0 // no fees + return nil +} + +func (c *dynamicCalculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { + complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + complexity[fee.Compute] += StakerLookupCost + + _, err = c.AddFeesFor(complexity) + return err +} + +func (c *dynamicCalculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { + complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = c.AddFeesFor(complexity) + return err +} + +func (c *dynamicCalculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { + complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = c.AddFeesFor(complexity) + return err +} + +func (c *dynamicCalculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { + outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.StakeOuts)) + copy(outs, tx.Outs) + copy(outs[len(tx.Outs):], tx.StakeOuts) + + complexity, err := c.meterTx(tx, outs, tx.Ins) + if err != nil { + return err + } + complexity[fee.Compute] += StakerLookupCost + + _, err = c.AddFeesFor(complexity) + return err +} + +func (c *dynamicCalculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { + outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.StakeOuts)) + copy(outs, tx.Outs) + copy(outs[len(tx.Outs):], tx.StakeOuts) + + complexity, err := c.meterTx(tx, outs, tx.Ins) + if err != nil { + return err + } + complexity[fee.Compute] += StakerLookupCost + + _, err = c.AddFeesFor(complexity) + return err +} + +func (c *dynamicCalculator) BaseTx(tx *txs.BaseTx) error { + complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = c.AddFeesFor(complexity) + return err +} + +func (c *dynamicCalculator) ImportTx(tx *txs.ImportTx) error { + ins := make([]*avax.TransferableInput, len(tx.Ins)+len(tx.ImportedInputs)) + copy(ins, tx.Ins) + copy(ins[len(tx.Ins):], tx.ImportedInputs) + + complexity, err := c.meterTx(tx, tx.Outs, ins) + if err != nil { + return err + } + + _, err = c.AddFeesFor(complexity) + return err +} + +func (c *dynamicCalculator) ExportTx(tx *txs.ExportTx) error { + outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.ExportedOutputs)) + copy(outs, tx.Outs) + copy(outs[len(tx.Outs):], tx.ExportedOutputs) + + complexity, err := c.meterTx(tx, outs, tx.Ins) + if err != nil { + return err + } + + _, err = c.AddFeesFor(complexity) + return err +} + +func (c *dynamicCalculator) meterTx( + uTx txs.UnsignedTx, + allOuts []*avax.TransferableOutput, + allIns []*avax.TransferableInput, +) (fee.Dimensions, error) { + var complexity fee.Dimensions + + uTxSize, err := txs.Codec.Size(txs.CodecVersion, uTx) + if err != nil { + return complexity, fmt.Errorf("couldn't calculate UnsignedTx marshal length: %w", err) + } + complexity[fee.Bandwidth] = uint64(uTxSize) + + // meter credentials, one by one. Then account for the extra bytes needed to + // serialize a slice of credentials (codec version bytes + slice size bytes) + for i, cred := range c.cred { + c, ok := cred.(*secp256k1fx.Credential) + if !ok { + return complexity, fmt.Errorf("don't know how to calculate complexity of %T", cred) + } + credDimensions, err := fee.MeterCredential(txs.Codec, txs.CodecVersion, len(c.Sigs)) + if err != nil { + return complexity, fmt.Errorf("failed adding credential %d: %w", i, err) + } + complexity, err = fee.Add(complexity, credDimensions) + if err != nil { + return complexity, fmt.Errorf("failed adding credentials: %w", err) + } + } + complexity[fee.Bandwidth] += wrappers.IntLen // length of the credentials slice + complexity[fee.Bandwidth] += codec.VersionSize + + for _, in := range allIns { + inputDimensions, err := fee.MeterInput(txs.Codec, txs.CodecVersion, in) + if err != nil { + return complexity, fmt.Errorf("failed retrieving size of inputs: %w", err) + } + inputDimensions[fee.Bandwidth] = 0 // inputs bandwidth is already accounted for above, so we zero it + complexity, err = fee.Add(complexity, inputDimensions) + if err != nil { + return complexity, fmt.Errorf("failed adding inputs: %w", err) + } + } + + for _, out := range allOuts { + outputDimensions, err := fee.MeterOutput(txs.Codec, txs.CodecVersion, out) + if err != nil { + return complexity, fmt.Errorf("failed retrieving size of outputs: %w", err) + } + outputDimensions[fee.Bandwidth] = 0 // outputs bandwidth is already accounted for above, so we zero it + complexity, err = fee.Add(complexity, outputDimensions) + if err != nil { + return complexity, fmt.Errorf("failed adding outputs: %w", err) + } + } + + return complexity, nil +} diff --git a/vms/platformvm/txs/fee/dynamic_config.go b/vms/platformvm/txs/fee/dynamic_config.go new file mode 100644 index 000000000000..94372c9a19f1 --- /dev/null +++ b/vms/platformvm/txs/fee/dynamic_config.go @@ -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" + + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/units" + + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" +) + +var ( + errDynamicFeeConfigNotAvailable = errors.New("dynamic fee config not available") + + eUpgradeDynamicFeesConfig = commonfee.DynamicFeesConfig{ + GasPrice: commonfee.GasPrice(10 * units.NanoAvax), + FeeDimensionWeights: commonfee.Dimensions{1, 1, 1, 1}, + MaxGasPerSecond: commonfee.Gas(1_000_000), + LeakGasCoeff: commonfee.Gas(1), + } + + customDynamicFeesConfig *commonfee.DynamicFeesConfig +) + +func init() { + if err := eUpgradeDynamicFeesConfig.Validate(); err != nil { + panic(err) + } +} + +func GetDynamicConfig(isEActive bool) (commonfee.DynamicFeesConfig, error) { + if !isEActive { + return commonfee.DynamicFeesConfig{}, errDynamicFeeConfigNotAvailable + } + + if customDynamicFeesConfig != nil { + return *customDynamicFeesConfig, nil + } + return eUpgradeDynamicFeesConfig, nil +} + +func ResetDynamicConfig(ctx *snow.Context, customFeesConfig *commonfee.DynamicFeesConfig) error { + if customFeesConfig == nil { + return nil // nothing to do + } + if ctx.NetworkID == constants.MainnetID || ctx.NetworkID == constants.FujiID { + return fmt.Errorf("forbidden resetting dynamic fee rates config for network %s", constants.NetworkName(ctx.NetworkID)) + } + if err := customFeesConfig.Validate(); err != nil { + return fmt.Errorf("invalid custom fee config: %w", err) + } + + customDynamicFeesConfig = customFeesConfig + return nil +} diff --git a/vms/platformvm/txs/fee/static_calculator.go b/vms/platformvm/txs/fee/static_calculator.go index 7bfb5cf799a0..601ff27dd620 100644 --- a/vms/platformvm/txs/fee/static_calculator.go +++ b/vms/platformvm/txs/fee/static_calculator.go @@ -4,9 +4,12 @@ package fee import ( + "errors" "time" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/vms/components/fee" + "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" ) @@ -14,6 +17,8 @@ import ( var ( _ Calculator = (*staticCalculator)(nil) _ txs.Visitor = (*staticCalculator)(nil) + + errComplexityNotPriced = errors.New("complexity not priced") ) func NewStaticCalculator( @@ -44,6 +49,32 @@ func (c *staticCalculator) CalculateFee(tx *txs.Tx) (uint64, error) { return c.fee, err } +func (c *staticCalculator) GetFee() uint64 { + return c.fee +} + +func (c *staticCalculator) ResetFee(newFee uint64) { + c.fee = newFee +} + +func (*staticCalculator) AddFeesFor(fee.Dimensions) (uint64, error) { + return 0, errComplexityNotPriced +} + +func (*staticCalculator) RemoveFeesFor(fee.Dimensions) (uint64, error) { + return 0, errComplexityNotPriced +} + +func (*staticCalculator) GetGasPrice() fee.GasPrice { return fee.ZeroGasPrice } + +func (*staticCalculator) GetBlockGas() (fee.Gas, error) { return fee.ZeroGas, nil } + +func (*staticCalculator) GetGasCap() fee.Gas { return fee.ZeroGas } + +func (*staticCalculator) setCredentials([]verify.Verifiable) {} + +func (*staticCalculator) IsEActive() bool { return false } + func (c *staticCalculator) AddValidatorTx(*txs.AddValidatorTx) error { c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee return nil From b96c57263e92820bcbce7cc0379aa311949f4905 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 15 Jul 2024 13:15:39 +0200 Subject: [PATCH 050/100] nit --- vms/components/fee/calculator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/components/fee/calculator.go b/vms/components/fee/calculator.go index 1a5fcdb2c066..903638495961 100644 --- a/vms/components/fee/calculator.go +++ b/vms/components/fee/calculator.go @@ -77,7 +77,7 @@ func (c *Calculator) AddFeesFor(complexity Dimensions) (uint64, error) { return 0, fmt.Errorf("%w: %w", errGasBoundBreached, err) } if totalGas > c.gasCap { - return 0, fmt.Errorf("%w: %w", errGasBoundBreached, err) + return 0, fmt.Errorf("%w: total gas %d, gas cap %d", errGasBoundBreached, totalGas, c.gasCap) } return c.GetLatestTxFee() From 0a2715f2178e429090a10ba6c503bb7107963ce9 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 15 Jul 2024 10:49:48 -0400 Subject: [PATCH 051/100] reduce diff --- vms/platformvm/txs/executor/staker_tx_verification.go | 6 ++---- vms/platformvm/txs/executor/standard_tx_executor.go | 9 +++------ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 28ba0f78d4c6..eb50d200b3da 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -761,10 +761,8 @@ func verifyTransferSubnetOwnershipTx( var ( currentTimestamp = chainState.GetTimestamp() upgrades = backend.Config.UpgradeConfig - isDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) - - if !isDurangoActive { + if !upgrades.IsDurangoActivated(currentTimestamp) { return ErrDurangoUpgradeNotActive } @@ -788,7 +786,7 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, backend.Config.UpgradeConfig, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(backend.Config.StaticFeeConfig, upgrades, currentTimestamp) fee, err := feeCalculator.CalculateFee(sTx) if err != nil { return err diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 5c5e466dc049..8de6893cba03 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -570,10 +570,8 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { var ( currentTimestamp = e.State.GetTimestamp() upgrades = e.Backend.Config.UpgradeConfig - IsDurangoActive = upgrades.IsDurangoActivated(currentTimestamp) ) - - if !IsDurangoActive { + if !upgrades.IsDurangoActivated(currentTimestamp) { return ErrDurangoUpgradeNotActive } @@ -587,7 +585,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { } // Verify the flowcheck - feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, e.Backend.Config.UpgradeConfig, currentTimestamp) + feeCalculator := fee.NewStaticCalculator(e.Backend.Config.StaticFeeConfig, upgrades, currentTimestamp) fee, err := feeCalculator.CalculateFee(e.Tx) if err != nil { return err @@ -617,13 +615,12 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { func (e *StandardTxExecutor) putStaker(stakerTx txs.Staker) error { var ( chainTime = e.State.GetTimestamp() - upgrades = e.Backend.Config.UpgradeConfig txID = e.Tx.ID() staker *state.Staker err error ) - if !upgrades.IsDurangoActivated(chainTime) { + if !e.Config.UpgradeConfig.IsDurangoActivated(chainTime) { // Pre-Durango, stakers set a future [StartTime] and are added to the // pending staker set. They are promoted to the current staker set once // the chain time reaches [StartTime]. From 46442c91435ed594d65adead34232dddc3250f12 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 15 Jul 2024 12:28:45 -0400 Subject: [PATCH 052/100] nits --- vms/platformvm/block/executor/verifier.go | 7 ------- vms/platformvm/service_test.go | 4 ++-- vms/platformvm/state/chain_time_helpers.go | 10 ++++++---- vms/platformvm/txs/txstest/context.go | 6 +++--- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index b4f5d366bef4..2e5626a76d14 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -357,9 +357,6 @@ func (v *verifier) abortBlock(b block.Block) error { statelessBlock: b, onAcceptState: onAbortState, timestamp: onAbortState.GetTimestamp(), - - // blockComplexity not set. We'll assign same complexity - // as proposal blocks upon acceptance } return nil } @@ -377,9 +374,6 @@ func (v *verifier) commitBlock(b block.Block) error { statelessBlock: b, onAcceptState: onCommitState, timestamp: onCommitState.GetTimestamp(), - - // blockComplexity not set. We'll assign same complexity - // as proposal blocks upon acceptance } return nil } @@ -475,7 +469,6 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, feeCalculator fee.Calculato funcs = make([]func(), 0, len(txs)) atomicRequests = make(map[ids.ID]*atomic.Requests) ) - for _, tx := range txs { txExecutor := executor.StandardTxExecutor{ Backend: v.txExecutorBackend, diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 377e0fce9c4a..ccda2c6c054b 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -375,9 +375,9 @@ func TestGetBalance(t *testing.T) { require := require.New(t) service, _, _ := defaultService(t) - feeCalc, err := state.PickFeeCalculator(&service.vm.Config, service.vm.state) + feeCalculator, err := state.PickFeeCalculator(&service.vm.Config, service.vm.state) require.NoError(err) - createSubnetFee, err := feeCalc.CalculateFee(&txs.Tx{Unsigned: &txs.CreateSubnetTx{}}) + createSubnetFee, err := feeCalculator.CalculateFee(&txs.Tx{Unsigned: &txs.CreateSubnetTx{}}) require.NoError(err) // Ensure GetStake is correct for each of the genesis validators diff --git a/vms/platformvm/state/chain_time_helpers.go b/vms/platformvm/state/chain_time_helpers.go index 9ac7a6c7c1f2..22fa97a7ac3c 100644 --- a/vms/platformvm/state/chain_time_helpers.go +++ b/vms/platformvm/state/chain_time_helpers.go @@ -71,9 +71,11 @@ func GetNextStakerChangeTime(state Chain) (time.Time, error) { } } -// [PickFeeCalculator] creates either a static or a dynamic fee calculator, depending on the active upgrade -// [PickFeeCalculator] does not modify [state] +// PickFeeCalculator creates either a static or a dynamic fee calculator, +// depending on the active upgrade. +// +// PickFeeCalculator does not modify [state]. func PickFeeCalculator(cfg *config.Config, state Chain) (fee.Calculator, error) { - childBlkTime := state.GetTimestamp() - return fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, childBlkTime), nil + timestamp := state.GetTimestamp() + return fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, timestamp), nil } diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index d8ca8c32853d..fb8181f7e39c 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -19,9 +19,9 @@ func newContext( timestamp time.Time, ) *builder.Context { var ( - feeCalc = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, timestamp) - createSubnetFee, _ = feeCalc.CalculateFee(&txs.Tx{Unsigned: &txs.CreateSubnetTx{}}) - createChainFee, _ = feeCalc.CalculateFee(&txs.Tx{Unsigned: &txs.CreateChainTx{}}) + feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, timestamp) + createSubnetFee, _ = feeCalculator.CalculateFee(&txs.Tx{Unsigned: &txs.CreateSubnetTx{}}) + createChainFee, _ = feeCalculator.CalculateFee(&txs.Tx{Unsigned: &txs.CreateChainTx{}}) ) return &builder.Context{ From d288bb5798c427717bd1cb90a02fe875a8a623da Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 15 Jul 2024 12:30:06 -0400 Subject: [PATCH 053/100] nit --- vms/platformvm/block/executor/verifier.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 2e5626a76d14..9824289329b5 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -168,9 +168,9 @@ func (v *verifier) ApricotProposalBlock(b *block.ApricotProposalBlock) error { } var ( - staticFeesCfg = v.txExecutorBackend.Config.StaticFeeConfig - upgrades = v.txExecutorBackend.Config.UpgradeConfig - feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, onCommitState.GetTimestamp()) + staticFeeConfig = v.txExecutorBackend.Config.StaticFeeConfig + upgradeConfig = v.txExecutorBackend.Config.UpgradeConfig + feeCalculator = fee.NewStaticCalculator(staticFeeConfig, upgradeConfig, onCommitState.GetTimestamp()) ) return v.proposalBlock(b, nil, onCommitState, onAbortState, feeCalculator, nil, nil, nil) } @@ -187,9 +187,9 @@ func (v *verifier) ApricotStandardBlock(b *block.ApricotStandardBlock) error { } var ( - staticFeesCfg = v.txExecutorBackend.Config.StaticFeeConfig - upgrades = v.txExecutorBackend.Config.UpgradeConfig - feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, onAcceptState.GetTimestamp()) + staticFeeConfig = v.txExecutorBackend.Config.StaticFeeConfig + upgradeConfig = v.txExecutorBackend.Config.UpgradeConfig + feeCalculator = fee.NewStaticCalculator(staticFeeConfig, upgradeConfig, onAcceptState.GetTimestamp()) ) return v.standardBlock(b, feeCalculator, onAcceptState) } From 885bea03f91661181af8a0addbb4ac8c6f7cefc5 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 15 Jul 2024 12:31:44 -0400 Subject: [PATCH 054/100] nit --- vms/platformvm/block/executor/verifier.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 9824289329b5..85e71dd3d973 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -170,7 +170,8 @@ func (v *verifier) ApricotProposalBlock(b *block.ApricotProposalBlock) error { var ( staticFeeConfig = v.txExecutorBackend.Config.StaticFeeConfig upgradeConfig = v.txExecutorBackend.Config.UpgradeConfig - feeCalculator = fee.NewStaticCalculator(staticFeeConfig, upgradeConfig, onCommitState.GetTimestamp()) + timestamp = onCommitState.GetTimestamp() // Equal to parent timestamp + feeCalculator = fee.NewStaticCalculator(staticFeeConfig, upgradeConfig, timestamp) ) return v.proposalBlock(b, nil, onCommitState, onAbortState, feeCalculator, nil, nil, nil) } @@ -189,7 +190,8 @@ func (v *verifier) ApricotStandardBlock(b *block.ApricotStandardBlock) error { var ( staticFeeConfig = v.txExecutorBackend.Config.StaticFeeConfig upgradeConfig = v.txExecutorBackend.Config.UpgradeConfig - feeCalculator = fee.NewStaticCalculator(staticFeeConfig, upgradeConfig, onAcceptState.GetTimestamp()) + timestamp = onAcceptState.GetTimestamp() + feeCalculator = fee.NewStaticCalculator(staticFeeConfig, upgradeConfig, timestamp) ) return v.standardBlock(b, feeCalculator, onAcceptState) } From 0941ecbb3d5aa40476c0ae37cb46ef4dad492ab4 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 15 Jul 2024 12:33:03 -0400 Subject: [PATCH 055/100] nit --- vms/platformvm/block/executor/verifier.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 85e71dd3d973..fcd38a9d72be 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -190,7 +190,7 @@ func (v *verifier) ApricotStandardBlock(b *block.ApricotStandardBlock) error { var ( staticFeeConfig = v.txExecutorBackend.Config.StaticFeeConfig upgradeConfig = v.txExecutorBackend.Config.UpgradeConfig - timestamp = onAcceptState.GetTimestamp() + timestamp = onAcceptState.GetTimestamp() // Equal to parent timestamp feeCalculator = fee.NewStaticCalculator(staticFeeConfig, upgradeConfig, timestamp) ) return v.standardBlock(b, feeCalculator, onAcceptState) From c7f7600dd9aec689e49d644afb03ab0b75593d3c Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 16 Jul 2024 20:26:27 -0400 Subject: [PATCH 056/100] wip --- vms/components/fee/calculator.go | 22 +++---- vms/components/fee/calculator_test.go | 21 +++--- vms/components/fee/config.go | 68 ++++---------------- vms/components/fee/dimensions.go | 67 +++++++++---------- vms/components/fee/gas.go | 48 ++++++++++++++ vms/components/fee/helpers.go | 44 ++++++------- vms/components/fee/state.go | 19 ++++++ vms/components/fee/update.go | 35 ++++++++++ vms/platformvm/txs/fee/dynamic_calculator.go | 6 +- vms/platformvm/txs/fee/dynamic_config.go | 60 ----------------- vms/platformvm/txs/fee/static_calculator.go | 6 +- 11 files changed, 195 insertions(+), 201 deletions(-) create mode 100644 vms/components/fee/gas.go create mode 100644 vms/components/fee/state.go create mode 100644 vms/components/fee/update.go delete mode 100644 vms/platformvm/txs/fee/dynamic_config.go diff --git a/vms/components/fee/calculator.go b/vms/components/fee/calculator.go index 903638495961..33d1caa23a76 100644 --- a/vms/components/fee/calculator.go +++ b/vms/components/fee/calculator.go @@ -7,7 +7,7 @@ import ( "errors" "fmt" - safemath "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/math" ) var errGasBoundBreached = errors.New("gas bound breached") @@ -46,9 +46,9 @@ func (c *Calculator) GetGasPrice() GasPrice { } func (c *Calculator) GetBlockGas() (Gas, error) { - txGas, err := ToGas(c.feeWeights, c.latestTxComplexity) + txGas, err := c.latestTxComplexity.ToGas(c.feeWeights) if err != nil { - return ZeroGas, err + return 0, err } return c.cumulatedGas + txGas, nil } @@ -61,12 +61,12 @@ func (c *Calculator) GetGasCap() Gas { // 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 { + if complexity == (Dimensions{}) { return c.GetLatestTxFee() } // Ensure we can consume (don't want partial update of values) - uc, err := Add(c.latestTxComplexity, complexity) + uc, err := c.latestTxComplexity.Add(complexity) if err != nil { return 0, fmt.Errorf("%w: %w", errGasBoundBreached, err) } @@ -86,11 +86,11 @@ func (c *Calculator) AddFeesFor(complexity Dimensions) (uint64, error) { // 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 { + if complexity == (Dimensions{}) { return c.GetLatestTxFee() } - rc, err := Remove(c.latestTxComplexity, complexity) + rc, err := c.latestTxComplexity.Sub(complexity) if err != nil { return 0, fmt.Errorf("%w: current Gas %d, gas to revert %d", err, c.cumulatedGas, complexity) } @@ -100,20 +100,20 @@ func (c *Calculator) RemoveFeesFor(complexity Dimensions) (uint64, error) { // 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) + txGas, err := c.latestTxComplexity.ToGas(c.feeWeights) if err != nil { return err } c.cumulatedGas += txGas - c.latestTxComplexity = Empty + c.latestTxComplexity = Dimensions{} return nil } // CalculateFee must be a stateless method func (c *Calculator) GetLatestTxFee() (uint64, error) { - gas, err := ToGas(c.feeWeights, c.latestTxComplexity) + gas, err := c.latestTxComplexity.ToGas(c.feeWeights) if err != nil { return 0, err } - return safemath.Mul64(uint64(c.gasPrice), uint64(gas)) + return math.Mul64(uint64(c.gasPrice), uint64(gas)) } diff --git a/vms/components/fee/calculator_test.go b/vms/components/fee/calculator_test.go index f2589fcc2ba4..1b43dc686f57 100644 --- a/vms/components/fee/calculator_test.go +++ b/vms/components/fee/calculator_test.go @@ -10,15 +10,18 @@ import ( "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}, + testDynamicConfig = DynamicConfig{ + GasPrice: 10, + FeeDimensionWeights: Dimensions{ + Bandwidth: 6, + DBRead: 10, + DBWrite: 10, + Compute: 1, + }, } testGasCap = Gas(math.MaxUint64) ) @@ -27,7 +30,7 @@ func TestAddAndRemoveFees(t *testing.T) { require := require.New(t) var ( - fc = NewCalculator(testDynamicFeeCfg.FeeDimensionWeights, testDynamicFeeCfg.GasPrice, testGasCap) + fc = NewCalculator(testDynamicConfig.FeeDimensionWeights, testDynamicConfig.GasPrice, testGasCap) complexity = Dimensions{1, 2, 3, 4} extraComplexity = Dimensions{2, 3, 4, 5} @@ -80,7 +83,7 @@ func TestGasCap(t *testing.T) { // childBlkTime = parentBlkTime.Add(time.Second) // grandChildBlkTime = childBlkTime.Add(5 * time.Second) - cfg = DynamicFeesConfig{ + cfg = DynamicConfig{ MaxGasPerSecond: Gas(1_000), LeakGasCoeff: Gas(5), } @@ -91,7 +94,7 @@ func TestGasCap(t *testing.T) { // A block whose gas matches cap, will consume full available cap blkGas := cfg.MaxGasPerSecond currCap = UpdateGasCap(currCap, blkGas) - require.Equal(ZeroGas, currCap) + require.Zero(currCap) // capacity grows linearly in time till MaxGas for i := 1; i <= 5; i++ { @@ -121,5 +124,5 @@ func TestGasCap(t *testing.T) { // time can only grow forward with capacity childBlkTime = parentBlkTime.Add(-1 * time.Second) _, err = GasCap(cfg, currCap, parentBlkTime, childBlkTime) - require.ErrorIs(err, errUnexpectedBlockTimes) + require.ErrorIs(err, errChildTimeBeforeParent) } diff --git a/vms/components/fee/config.go b/vms/components/fee/config.go index 28a2059b65e0..c1cf61478489 100644 --- a/vms/components/fee/config.go +++ b/vms/components/fee/config.go @@ -3,58 +3,18 @@ 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 +type Config struct { + // Weights to merge fees dimensions complexities into a single gas value + Weights Dimensions `json:"weights"` + // Target amount of gas the chain should consume per second to keep the fees + // stable. + TargetGasPerSecond Gas `json:"targetGasPerSecond"` + // Maximum amount of gas the chain is allowed to consume per second. + MaxGasPerSecond Gas `json:"maxGasPerSecond"` + // Maximum amount of gas the chain is allowed to store for future use. + MaxGasCapacity Gas `json:"maxGasCapacity"` + // Minimum price in nAVAX per unit of gas. + MinGasPrice GasPrice `json:"minGasPrice"` + // Constant used to + GasConversionConstant Gas `json:"gasConversionConstant"` } diff --git a/vms/components/fee/dimensions.go b/vms/components/fee/dimensions.go index 286dc29813f0..21427af9821e 100644 --- a/vms/components/fee/dimensions.go +++ b/vms/components/fee/dimensions.go @@ -3,68 +3,61 @@ package fee -import ( - safemath "github.com/ava-labs/avalanchego/utils/math" -) +import "github.com/ava-labs/avalanchego/utils/math" const ( - Bandwidth Dimension = 0 - DBRead Dimension = 1 - DBWrite Dimension = 2 // includes deletes - Compute Dimension = 3 - - FeeDimensions = 4 -) + Bandwidth Dimension = iota + DBRead + DBWrite // includes deletes + Compute -var ( - ZeroGas = Gas(0) - ZeroGasPrice = GasPrice(0) - Empty = Dimensions{} + NumDimensions = iota ) type ( - GasPrice uint64 - Gas uint64 - - Dimension int - Dimensions [FeeDimensions]uint64 + Dimension uint + Dimensions [NumDimensions]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]) +func (d Dimensions) Add(o Dimensions) (Dimensions, error) { + var ( + res Dimensions + err error + ) + for i := range d { + res[i], err = math.Add64(d[i], o[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]) +func (d Dimensions) Sub(o Dimensions) (Dimensions, error) { + var ( + res Dimensions + err error + ) + for i := range d { + res[i], err = math.Sub(d[i], o[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]) +func (d Dimensions) ToGas(weights Dimensions) (Gas, error) { + var res uint64 + for i := range d { + v, err := math.Mul64(d[i], weights[i]) if err != nil { - return ZeroGas, err + return 0, err } - res, err = safemath.Add64(res, v) + res, err = math.Add64(res, v) if err != nil { - return ZeroGas, err + return 0, err } } - return Gas(res) / 10, nil + return Gas(res), nil } diff --git a/vms/components/fee/gas.go b/vms/components/fee/gas.go new file mode 100644 index 000000000000..c113573713f1 --- /dev/null +++ b/vms/components/fee/gas.go @@ -0,0 +1,48 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "math" + + safemath "github.com/ava-labs/avalanchego/utils/math" +) + +type ( + Gas uint64 + GasPrice uint64 +) + +func (g Gas) AddPerSecond(gasPerSecond Gas, seconds uint64) Gas { + newGas, err := safemath.Mul64(uint64(gasPerSecond), seconds) + if err != nil { + return math.MaxUint64 + } + totalGas, err := safemath.Add64(uint64(g), newGas) + if err != nil { + return math.MaxUint64 + } + return Gas(totalGas) +} + +func (g Gas) SubPerSecond(gasPerSecond Gas, seconds uint64) Gas { + gasToRemove, err := safemath.Mul64(uint64(gasPerSecond), seconds) + if err != nil { + return 0 + } + totalGas, err := safemath.Sub(uint64(g), gasToRemove) + if err != nil { + return 0 + } + return Gas(totalGas) +} + +// MulExp returns g*e^(excess / gasConversionConstant) +func (g GasPrice) MulExp( + excess Gas, + gasConversionConstant Gas, +) GasPrice { + // TODO: Implement this + return 0 +} diff --git a/vms/components/fee/helpers.go b/vms/components/fee/helpers.go index 26cc300b3cc9..ca075afc1715 100644 --- a/vms/components/fee/helpers.go +++ b/vms/components/fee/helpers.go @@ -8,7 +8,6 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -17,50 +16,47 @@ import ( func MeterInput(c codec.Manager, v uint16, in *avax.TransferableInput) (Dimensions, error) { cost, err := in.In.Cost() if err != nil { - return Empty, fmt.Errorf("failed retrieving cost of input %s: %w", in.ID, err) + return Dimensions{}, fmt.Errorf("failed retrieving cost of input %s: %w", in.ID, err) } inSize, err := c.Size(v, in) if err != nil { - return Empty, fmt.Errorf("failed retrieving size of input %s: %w", in.ID, err) + return Dimensions{}, fmt.Errorf("failed retrieving size of input %s: %w", in.ID, err) } uInSize := uint64(inSize) - complexity := Empty - complexity[Bandwidth] += uInSize - codec.VersionSize - complexity[DBRead] += uInSize // inputs are read - complexity[DBWrite] += uInSize // inputs are deleted - complexity[Compute] += cost - return complexity, nil + return Dimensions{ + Bandwidth: uInSize - codec.VersionSize, + DBRead: uInSize, // inputs are read + DBWrite: uInSize, // inputs are deleted + Compute: cost, + }, nil } func MeterOutput(c codec.Manager, v uint16, out *avax.TransferableOutput) (Dimensions, error) { outSize, err := c.Size(v, out) if err != nil { - return Empty, fmt.Errorf("failed retrieving size of output %s: %w", out.ID, err) + return Dimensions{}, fmt.Errorf("failed retrieving size of output %s: %w", out.ID, err) } uOutSize := uint64(outSize) - complexity := Empty - complexity[Bandwidth] += uOutSize - codec.VersionSize - complexity[DBWrite] += uOutSize - return complexity, nil + return Dimensions{ + Bandwidth: uOutSize - codec.VersionSize, + DBWrite: uOutSize, + }, nil } func MeterCredential(c codec.Manager, v uint16, keysCount int) (Dimensions, error) { // Ensure that codec picks interface instead of the pointer to evaluate size. - creds := make([]verify.Verifiable, 0, 1) - creds = append(creds, &secp256k1fx.Credential{ + var cred verify.Verifiable = &secp256k1fx.Credential{ Sigs: make([][secp256k1.SignatureLen]byte, keysCount), - }) - - credSize, err := c.Size(v, creds) + } + credSize, err := c.Size(v, &cred) if err != nil { - return Empty, fmt.Errorf("failed retrieving size of credentials: %w", err) + return Dimensions{}, fmt.Errorf("failed retrieving size of credentials: %w", err) } - credSize -= wrappers.IntLen // length of the slice, we want the single credential - complexity := Empty - complexity[Bandwidth] += uint64(credSize) - codec.VersionSize - return complexity, nil + return Dimensions{ + Bandwidth: uint64(credSize) - codec.VersionSize, + }, nil } diff --git a/vms/components/fee/state.go b/vms/components/fee/state.go new file mode 100644 index 000000000000..75f3b698822b --- /dev/null +++ b/vms/components/fee/state.go @@ -0,0 +1,19 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +type State struct { + Capacity Gas + Excess Gas +} + +func (s State) AdvanceTime(c Config, duration uint64) State { + return State{ + Capacity: min( + s.Capacity.AddPerSecond(c.MaxGasPerSecond, duration), + c.MaxGasCapacity, + ), + Excess: s.Excess.SubPerSecond(c.TargetGasPerSecond, duration), + } +} diff --git a/vms/components/fee/update.go b/vms/components/fee/update.go new file mode 100644 index 000000000000..e1513a15f374 --- /dev/null +++ b/vms/components/fee/update.go @@ -0,0 +1,35 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "errors" + "fmt" + "time" +) + +var errChildTimeBeforeParent = errors.New("child block time before parent block time") + +// We cap the maximum gas consumed by time with a leaky bucket approach +// GasCap = min (GasCap + MaxGasPerSecond/LeakGasCoeff*ElapsedTime, MaxGasPerSecond) +func GasCap(cfg DynamicConfig, currentGasCapacity Gas, parentBlkTime, childBlkTime time.Time) (Gas, error) { + if childBlkTime.Before(parentBlkTime) { + return 0, fmt.Errorf("%w, parentBlkTim %v, childBlkTime %v", errChildTimeBeforeParent, 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 +} diff --git a/vms/platformvm/txs/fee/dynamic_calculator.go b/vms/platformvm/txs/fee/dynamic_calculator.go index 3b28858733a0..f16a56122837 100644 --- a/vms/platformvm/txs/fee/dynamic_calculator.go +++ b/vms/platformvm/txs/fee/dynamic_calculator.go @@ -276,7 +276,7 @@ func (c *dynamicCalculator) meterTx( if err != nil { return complexity, fmt.Errorf("failed adding credential %d: %w", i, err) } - complexity, err = fee.Add(complexity, credDimensions) + complexity, err = complexity.Add(credDimensions) if err != nil { return complexity, fmt.Errorf("failed adding credentials: %w", err) } @@ -290,7 +290,7 @@ func (c *dynamicCalculator) meterTx( return complexity, fmt.Errorf("failed retrieving size of inputs: %w", err) } inputDimensions[fee.Bandwidth] = 0 // inputs bandwidth is already accounted for above, so we zero it - complexity, err = fee.Add(complexity, inputDimensions) + complexity, err = complexity.Add(inputDimensions) if err != nil { return complexity, fmt.Errorf("failed adding inputs: %w", err) } @@ -302,7 +302,7 @@ func (c *dynamicCalculator) meterTx( return complexity, fmt.Errorf("failed retrieving size of outputs: %w", err) } outputDimensions[fee.Bandwidth] = 0 // outputs bandwidth is already accounted for above, so we zero it - complexity, err = fee.Add(complexity, outputDimensions) + complexity, err = complexity.Add(outputDimensions) if err != nil { return complexity, fmt.Errorf("failed adding outputs: %w", err) } diff --git a/vms/platformvm/txs/fee/dynamic_config.go b/vms/platformvm/txs/fee/dynamic_config.go deleted file mode 100644 index 94372c9a19f1..000000000000 --- a/vms/platformvm/txs/fee/dynamic_config.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package fee - -import ( - "errors" - "fmt" - - "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - - commonfee "github.com/ava-labs/avalanchego/vms/components/fee" -) - -var ( - errDynamicFeeConfigNotAvailable = errors.New("dynamic fee config not available") - - eUpgradeDynamicFeesConfig = commonfee.DynamicFeesConfig{ - GasPrice: commonfee.GasPrice(10 * units.NanoAvax), - FeeDimensionWeights: commonfee.Dimensions{1, 1, 1, 1}, - MaxGasPerSecond: commonfee.Gas(1_000_000), - LeakGasCoeff: commonfee.Gas(1), - } - - customDynamicFeesConfig *commonfee.DynamicFeesConfig -) - -func init() { - if err := eUpgradeDynamicFeesConfig.Validate(); err != nil { - panic(err) - } -} - -func GetDynamicConfig(isEActive bool) (commonfee.DynamicFeesConfig, error) { - if !isEActive { - return commonfee.DynamicFeesConfig{}, errDynamicFeeConfigNotAvailable - } - - if customDynamicFeesConfig != nil { - return *customDynamicFeesConfig, nil - } - return eUpgradeDynamicFeesConfig, nil -} - -func ResetDynamicConfig(ctx *snow.Context, customFeesConfig *commonfee.DynamicFeesConfig) error { - if customFeesConfig == nil { - return nil // nothing to do - } - if ctx.NetworkID == constants.MainnetID || ctx.NetworkID == constants.FujiID { - return fmt.Errorf("forbidden resetting dynamic fee rates config for network %s", constants.NetworkName(ctx.NetworkID)) - } - if err := customFeesConfig.Validate(); err != nil { - return fmt.Errorf("invalid custom fee config: %w", err) - } - - customDynamicFeesConfig = customFeesConfig - return nil -} diff --git a/vms/platformvm/txs/fee/static_calculator.go b/vms/platformvm/txs/fee/static_calculator.go index 601ff27dd620..c4e029d5a149 100644 --- a/vms/platformvm/txs/fee/static_calculator.go +++ b/vms/platformvm/txs/fee/static_calculator.go @@ -65,11 +65,11 @@ func (*staticCalculator) RemoveFeesFor(fee.Dimensions) (uint64, error) { return 0, errComplexityNotPriced } -func (*staticCalculator) GetGasPrice() fee.GasPrice { return fee.ZeroGasPrice } +func (*staticCalculator) GetGasPrice() fee.GasPrice { return 0 } -func (*staticCalculator) GetBlockGas() (fee.Gas, error) { return fee.ZeroGas, nil } +func (*staticCalculator) GetBlockGas() (fee.Gas, error) { return 0, nil } -func (*staticCalculator) GetGasCap() fee.Gas { return fee.ZeroGas } +func (*staticCalculator) GetGasCap() fee.Gas { return 0 } func (*staticCalculator) setCredentials([]verify.Verifiable) {} From a7a962968e13d7d7e75590df81c2836362097a9f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 17 Jul 2024 11:17:12 -0400 Subject: [PATCH 057/100] wip --- vms/components/fee/config.go | 4 ++-- vms/components/fee/gas.go | 27 +++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/vms/components/fee/config.go b/vms/components/fee/config.go index c1cf61478489..926c25868ee6 100644 --- a/vms/components/fee/config.go +++ b/vms/components/fee/config.go @@ -15,6 +15,6 @@ type Config struct { MaxGasCapacity Gas `json:"maxGasCapacity"` // Minimum price in nAVAX per unit of gas. MinGasPrice GasPrice `json:"minGasPrice"` - // Constant used to - GasConversionConstant Gas `json:"gasConversionConstant"` + // Constant used to convert excess gas to a gas price. + GasConversionConstant GasPrice `json:"gasConversionConstant"` } diff --git a/vms/components/fee/gas.go b/vms/components/fee/gas.go index c113573713f1..bcaa6c0b70c1 100644 --- a/vms/components/fee/gas.go +++ b/vms/components/fee/gas.go @@ -38,11 +38,30 @@ func (g Gas) SubPerSecond(gasPerSecond Gas, seconds uint64) Gas { return Gas(totalGas) } -// MulExp returns g*e^(excess / gasConversionConstant) +// MulExp returns an approximation of g*e^(excess / gasConversionConstant) func (g GasPrice) MulExp( excess Gas, - gasConversionConstant Gas, + gasConversionConstant GasPrice, ) GasPrice { - // TODO: Implement this - return 0 + var ( + iteration GasPrice = 1 + output GasPrice + numeratorAccum = g * gasConversionConstant + ) + for numeratorAccum > 0 { + output += numeratorAccum + numeratorAccum = (numeratorAccum * GasPrice(excess)) / (gasConversionConstant * iteration) + iteration++ + } + return output / gasConversionConstant } + +// def fake_exponential(factor: int, numerator: int, denominator: int) -> int: +// i = 1 +// output = 0 +// numerator_accum = factor * denominator +// while numerator_accum > 0: +// output += numerator_accum +// numerator_accum = (numerator_accum * numerator) // (denominator * i) +// i += 1 +// return output // denominator From 1ac003e36e07dc86f84052bc038c03bd8705f24c Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 17 Jul 2024 15:45:49 -0400 Subject: [PATCH 058/100] wip --- vms/components/fee/calculator.go | 221 ++++++++++++------------ vms/components/fee/calculator_test.go | 236 ++++++++++++-------------- vms/components/fee/gas_test.go | 51 ++++++ vms/components/fee/update.go | 46 +++-- 4 files changed, 291 insertions(+), 263 deletions(-) create mode 100644 vms/components/fee/gas_test.go diff --git a/vms/components/fee/calculator.go b/vms/components/fee/calculator.go index 33d1caa23a76..8944b1a7828e 100644 --- a/vms/components/fee/calculator.go +++ b/vms/components/fee/calculator.go @@ -3,117 +3,110 @@ package fee -import ( - "errors" - "fmt" - - "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 := c.latestTxComplexity.ToGas(c.feeWeights) - if err != nil { - return 0, 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 == (Dimensions{}) { - return c.GetLatestTxFee() - } - - // Ensure we can consume (don't want partial update of values) - uc, err := c.latestTxComplexity.Add(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 == (Dimensions{}) { - return c.GetLatestTxFee() - } - - rc, err := c.latestTxComplexity.Sub(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 := c.latestTxComplexity.ToGas(c.feeWeights) - if err != nil { - return err - } - c.cumulatedGas += txGas - c.latestTxComplexity = Dimensions{} - return nil -} - -// CalculateFee must be a stateless method -func (c *Calculator) GetLatestTxFee() (uint64, error) { - gas, err := c.latestTxComplexity.ToGas(c.feeWeights) - if err != nil { - return 0, err - } - return math.Mul64(uint64(c.gasPrice), uint64(gas)) -} +// 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 := c.latestTxComplexity.ToGas(c.feeWeights) +// if err != nil { +// return 0, 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 == (Dimensions{}) { +// return c.GetLatestTxFee() +// } + +// // Ensure we can consume (don't want partial update of values) +// uc, err := c.latestTxComplexity.Add(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 == (Dimensions{}) { +// return c.GetLatestTxFee() +// } + +// rc, err := c.latestTxComplexity.Sub(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 := c.latestTxComplexity.ToGas(c.feeWeights) +// if err != nil { +// return err +// } +// c.cumulatedGas += txGas +// c.latestTxComplexity = Dimensions{} +// return nil +// } + +// // CalculateFee must be a stateless method +// func (c *Calculator) GetLatestTxFee() (uint64, error) { +// gas, err := c.latestTxComplexity.ToGas(c.feeWeights) +// if err != nil { +// return 0, err +// } +// return math.Mul64(uint64(c.gasPrice), uint64(gas)) +// } diff --git a/vms/components/fee/calculator_test.go b/vms/components/fee/calculator_test.go index 1b43dc686f57..dc67fe8acadb 100644 --- a/vms/components/fee/calculator_test.go +++ b/vms/components/fee/calculator_test.go @@ -3,126 +3,116 @@ package fee -import ( - "math" - "testing" - "time" - - "github.com/stretchr/testify/require" - - safemath "github.com/ava-labs/avalanchego/utils/math" -) - -var ( - testDynamicConfig = DynamicConfig{ - GasPrice: 10, - FeeDimensionWeights: Dimensions{ - Bandwidth: 6, - DBRead: 10, - DBWrite: 10, - Compute: 1, - }, - } - testGasCap = Gas(math.MaxUint64) -) - -func TestAddAndRemoveFees(t *testing.T) { - require := require.New(t) - - var ( - fc = NewCalculator(testDynamicConfig.FeeDimensionWeights, testDynamicConfig.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 = DynamicConfig{ - 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.Zero(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, errChildTimeBeforeParent) -} +// var ( +// testDynamicConfig = DynamicConfig{ +// GasPrice: 10, +// FeeDimensionWeights: Dimensions{ +// Bandwidth: 6, +// DBRead: 10, +// DBWrite: 10, +// Compute: 1, +// }, +// } +// testGasCap = Gas(math.MaxUint64) +// ) + +// func TestAddAndRemoveFees(t *testing.T) { +// require := require.New(t) + +// var ( +// fc = NewCalculator(testDynamicConfig.FeeDimensionWeights, testDynamicConfig.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 = DynamicConfig{ +// 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.Zero(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, errChildTimeBeforeParent) +// } diff --git a/vms/components/fee/gas_test.go b/vms/components/fee/gas_test.go new file mode 100644 index 000000000000..61b2a61a62c8 --- /dev/null +++ b/vms/components/fee/gas_test.go @@ -0,0 +1,51 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestT(t *testing.T) { + tests := []struct { + minPrice GasPrice + excess Gas + gasConversionConstant GasPrice + expectedPrice GasPrice + }{ + { + minPrice: 1, + excess: 0, + gasConversionConstant: 1, + expectedPrice: 1, + }, + { + minPrice: 1, + excess: 1, + gasConversionConstant: 1, + expectedPrice: 2, + }, + { + minPrice: 1, + excess: 2, + gasConversionConstant: 1, + expectedPrice: 6, + }, + { + minPrice: 1, + excess: 10_000, + gasConversionConstant: 10_000, + expectedPrice: 2, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d*e^(%d/%d)=%d", test.minPrice, test.excess, test.gasConversionConstant, test.expectedPrice), func(t *testing.T) { + outputPrice := test.minPrice.MulExp(test.excess, test.gasConversionConstant) + require.Equal(t, test.expectedPrice, outputPrice) + }) + } +} diff --git a/vms/components/fee/update.go b/vms/components/fee/update.go index e1513a15f374..8c005cdca584 100644 --- a/vms/components/fee/update.go +++ b/vms/components/fee/update.go @@ -3,33 +3,27 @@ package fee -import ( - "errors" - "fmt" - "time" -) +// var errChildTimeBeforeParent = errors.New("child block time before parent block time") -var errChildTimeBeforeParent = errors.New("child block time before parent block time") +// // We cap the maximum gas consumed by time with a leaky bucket approach +// // GasCap = min (GasCap + MaxGasPerSecond/LeakGasCoeff*ElapsedTime, MaxGasPerSecond) +// func GasCap(cfg Config, currentGasCapacity Gas, parentBlkTime, childBlkTime time.Time) (Gas, error) { +// if childBlkTime.Before(parentBlkTime) { +// return 0, fmt.Errorf("%w, parentBlkTim %v, childBlkTime %v", errChildTimeBeforeParent, parentBlkTime, childBlkTime) +// } -// We cap the maximum gas consumed by time with a leaky bucket approach -// GasCap = min (GasCap + MaxGasPerSecond/LeakGasCoeff*ElapsedTime, MaxGasPerSecond) -func GasCap(cfg DynamicConfig, currentGasCapacity Gas, parentBlkTime, childBlkTime time.Time) (Gas, error) { - if childBlkTime.Before(parentBlkTime) { - return 0, fmt.Errorf("%w, parentBlkTim %v, childBlkTime %v", errChildTimeBeforeParent, parentBlkTime, childBlkTime) - } +// elapsedTime := uint64(childBlkTime.Unix() - parentBlkTime.Unix()) +// if elapsedTime > uint64(cfg.LeakGasCoeff) { +// return cfg.MaxGasPerSecond, nil +// } - 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 +// } - 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 -} +// func UpdateGasCap(currentGasCap, blkGas Gas) Gas { +// nextGasCap := Gas(0) +// if currentGasCap > blkGas { +// nextGasCap = currentGasCap - blkGas +// } +// return nextGasCap +// } From 5509e9cdb5fe8b07b18933399359e9658ecd9d34 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jul 2024 11:35:50 -0400 Subject: [PATCH 059/100] Implement ACP-103 fee calculations --- vms/components/fee/calculator.go | 112 ----------- vms/components/fee/calculator_test.go | 118 ------------ vms/components/fee/config.go | 16 +- vms/components/fee/dimensions_test.go | 260 ++++++++++++++++++++++++++ vms/components/fee/gas.go | 75 ++++++-- vms/components/fee/gas_test.go | 176 ++++++++++++++--- vms/components/fee/helpers.go | 62 ------ vms/components/fee/state.go | 42 ++++- vms/components/fee/state_test.go | 162 ++++++++++++++++ vms/components/fee/update.go | 29 --- 10 files changed, 676 insertions(+), 376 deletions(-) delete mode 100644 vms/components/fee/calculator.go delete mode 100644 vms/components/fee/calculator_test.go create mode 100644 vms/components/fee/dimensions_test.go delete mode 100644 vms/components/fee/helpers.go create mode 100644 vms/components/fee/state_test.go delete mode 100644 vms/components/fee/update.go diff --git a/vms/components/fee/calculator.go b/vms/components/fee/calculator.go deleted file mode 100644 index 8944b1a7828e..000000000000 --- a/vms/components/fee/calculator.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package fee - -// 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 := c.latestTxComplexity.ToGas(c.feeWeights) -// if err != nil { -// return 0, 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 == (Dimensions{}) { -// return c.GetLatestTxFee() -// } - -// // Ensure we can consume (don't want partial update of values) -// uc, err := c.latestTxComplexity.Add(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 == (Dimensions{}) { -// return c.GetLatestTxFee() -// } - -// rc, err := c.latestTxComplexity.Sub(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 := c.latestTxComplexity.ToGas(c.feeWeights) -// if err != nil { -// return err -// } -// c.cumulatedGas += txGas -// c.latestTxComplexity = Dimensions{} -// return nil -// } - -// // CalculateFee must be a stateless method -// func (c *Calculator) GetLatestTxFee() (uint64, error) { -// gas, err := c.latestTxComplexity.ToGas(c.feeWeights) -// if err != nil { -// return 0, err -// } -// return math.Mul64(uint64(c.gasPrice), uint64(gas)) -// } diff --git a/vms/components/fee/calculator_test.go b/vms/components/fee/calculator_test.go deleted file mode 100644 index dc67fe8acadb..000000000000 --- a/vms/components/fee/calculator_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package fee - -// var ( -// testDynamicConfig = DynamicConfig{ -// GasPrice: 10, -// FeeDimensionWeights: Dimensions{ -// Bandwidth: 6, -// DBRead: 10, -// DBWrite: 10, -// Compute: 1, -// }, -// } -// testGasCap = Gas(math.MaxUint64) -// ) - -// func TestAddAndRemoveFees(t *testing.T) { -// require := require.New(t) - -// var ( -// fc = NewCalculator(testDynamicConfig.FeeDimensionWeights, testDynamicConfig.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 = DynamicConfig{ -// 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.Zero(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, errChildTimeBeforeParent) -// } diff --git a/vms/components/fee/config.go b/vms/components/fee/config.go index 926c25868ee6..ab22958126d5 100644 --- a/vms/components/fee/config.go +++ b/vms/components/fee/config.go @@ -1,20 +1,22 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. +// The fee package implements the fee logic specified in ACP-103: +// https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/103-dynamic-fees package fee type Config struct { - // Weights to merge fees dimensions complexities into a single gas value + // Weights to merge fee dimensions into a single gas value. Weights Dimensions `json:"weights"` + // Maximum amount of gas the chain is allowed to store for future use. + MaxGasCapacity Gas `json:"maxGasCapacity"` + // Maximum amount of gas the chain is allowed to consume per second. + MaxGasPerSecond Gas `json:"maxGasPerSecond"` // Target amount of gas the chain should consume per second to keep the fees // stable. TargetGasPerSecond Gas `json:"targetGasPerSecond"` - // Maximum amount of gas the chain is allowed to consume per second. - MaxGasPerSecond Gas `json:"maxGasPerSecond"` - // Maximum amount of gas the chain is allowed to store for future use. - MaxGasCapacity Gas `json:"maxGasCapacity"` - // Minimum price in nAVAX per unit of gas. + // Minimum price per unit of gas. MinGasPrice GasPrice `json:"minGasPrice"` // Constant used to convert excess gas to a gas price. - GasConversionConstant GasPrice `json:"gasConversionConstant"` + ExcessConversionConstant Gas `json:"excessConversionConstant"` } diff --git a/vms/components/fee/dimensions_test.go b/vms/components/fee/dimensions_test.go new file mode 100644 index 000000000000..22579b696d46 --- /dev/null +++ b/vms/components/fee/dimensions_test.go @@ -0,0 +1,260 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "math" + "testing" + + "github.com/stretchr/testify/require" + + safemath "github.com/ava-labs/avalanchego/utils/math" +) + +func Test_Dimensions_Add(t *testing.T) { + tests := []struct { + name string + lhs Dimensions + rhs Dimensions + expected Dimensions + expectedErr error + }{ + { + name: "no error", + lhs: Dimensions{ + Bandwidth: 1, + DBRead: 2, + DBWrite: 3, + Compute: 4, + }, + rhs: Dimensions{ + Bandwidth: 10, + DBRead: 20, + DBWrite: 30, + Compute: 40, + }, + expected: Dimensions{ + Bandwidth: 11, + DBRead: 22, + DBWrite: 33, + Compute: 44, + }, + expectedErr: nil, + }, + { + name: "bandwidth overflow", + lhs: Dimensions{ + Bandwidth: math.MaxUint64, + DBRead: 2, + DBWrite: 3, + Compute: 4, + }, + rhs: Dimensions{ + Bandwidth: 10, + DBRead: 20, + DBWrite: 30, + Compute: 40, + }, + expected: Dimensions{ + Bandwidth: 0, + DBRead: 0, + DBWrite: 0, + Compute: 0, + }, + expectedErr: safemath.ErrOverflow, + }, + { + name: "compute overflow", + lhs: Dimensions{ + Bandwidth: 1, + DBRead: 2, + DBWrite: 3, + Compute: math.MaxUint64, + }, + rhs: Dimensions{ + Bandwidth: 10, + DBRead: 20, + DBWrite: 30, + Compute: 40, + }, + expected: Dimensions{ + Bandwidth: 11, + DBRead: 22, + DBWrite: 33, + Compute: 0, + }, + expectedErr: safemath.ErrOverflow, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + actual, err := test.lhs.Add(test.rhs) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + }) + } +} + +func Test_Dimensions_Sub(t *testing.T) { + tests := []struct { + name string + lhs Dimensions + rhs Dimensions + expected Dimensions + expectedErr error + }{ + { + name: "no error", + lhs: Dimensions{ + Bandwidth: 11, + DBRead: 22, + DBWrite: 33, + Compute: 44, + }, + rhs: Dimensions{ + Bandwidth: 1, + DBRead: 2, + DBWrite: 3, + Compute: 4, + }, + expected: Dimensions{ + Bandwidth: 10, + DBRead: 20, + DBWrite: 30, + Compute: 40, + }, + expectedErr: nil, + }, + { + name: "bandwidth underflow", + lhs: Dimensions{ + Bandwidth: 11, + DBRead: 22, + DBWrite: 33, + Compute: 44, + }, + rhs: Dimensions{ + Bandwidth: math.MaxUint64, + DBRead: 2, + DBWrite: 3, + Compute: 4, + }, + expected: Dimensions{ + Bandwidth: 0, + DBRead: 0, + DBWrite: 0, + Compute: 0, + }, + expectedErr: safemath.ErrUnderflow, + }, + { + name: "compute underflow", + lhs: Dimensions{ + Bandwidth: 11, + DBRead: 22, + DBWrite: 33, + Compute: 44, + }, + rhs: Dimensions{ + Bandwidth: 1, + DBRead: 2, + DBWrite: 3, + Compute: math.MaxUint64, + }, + expected: Dimensions{ + Bandwidth: 10, + DBRead: 20, + DBWrite: 30, + Compute: 0, + }, + expectedErr: safemath.ErrUnderflow, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + actual, err := test.lhs.Sub(test.rhs) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + }) + } +} + +func Test_Dimensions_ToGas(t *testing.T) { + tests := []struct { + name string + units Dimensions + weights Dimensions + expected Gas + expectedErr error + }{ + { + name: "no error", + units: Dimensions{ + Bandwidth: 1, + DBRead: 2, + DBWrite: 3, + Compute: 4, + }, + weights: Dimensions{ + Bandwidth: 1000, + DBRead: 100, + DBWrite: 10, + Compute: 1, + }, + expected: 1*1000 + 2*100 + 3*10 + 4*1, + expectedErr: nil, + }, + { + name: "multiplication overflow", + units: Dimensions{ + Bandwidth: 2, + DBRead: 1, + DBWrite: 1, + Compute: 1, + }, + weights: Dimensions{ + Bandwidth: math.MaxUint64, + DBRead: 1, + DBWrite: 1, + Compute: 1, + }, + expected: 0, + expectedErr: safemath.ErrOverflow, + }, + { + name: "addition overflow", + units: Dimensions{ + Bandwidth: 1, + DBRead: 1, + DBWrite: 0, + Compute: 0, + }, + weights: Dimensions{ + Bandwidth: math.MaxUint64, + DBRead: math.MaxUint64, + DBWrite: 1, + Compute: 1, + }, + expected: 0, + expectedErr: safemath.ErrOverflow, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + actual, err := test.units.ToGas(test.weights) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + + actual, err = test.weights.ToGas(test.units) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + }) + } +} diff --git a/vms/components/fee/gas.go b/vms/components/fee/gas.go index bcaa6c0b70c1..743327088857 100644 --- a/vms/components/fee/gas.go +++ b/vms/components/fee/gas.go @@ -6,9 +6,13 @@ package fee import ( "math" + "github.com/holiman/uint256" + safemath "github.com/ava-labs/avalanchego/utils/math" ) +var maxUint64 = new(uint256.Int).SetUint64(math.MaxUint64) + type ( Gas uint64 GasPrice uint64 @@ -38,30 +42,61 @@ func (g Gas) SubPerSecond(gasPerSecond Gas, seconds uint64) Gas { return Gas(totalGas) } -// MulExp returns an approximation of g*e^(excess / gasConversionConstant) +// MulExp returns an approximation of g*e^(excess / excessConversionConstant) +// +// This implements the EIP-4844 fake exponential formula: +// +// def fake_exponential(factor: int, numerator: int, denominator: int) -> int: +// i = 1 +// output = 0 +// numerator_accum = factor * denominator +// while numerator_accum > 0: +// output += numerator_accum +// numerator_accum = (numerator_accum * numerator) // (denominator * i) +// i += 1 +// return output // denominator +// +// This implementation is optimized with the knowledge that any value greater +// than MaxUint64 gets returned as MaxUint64. This means that every intermediate +// value is guaranteed to be at most MaxUint192. So, we can safely use +// uint256.Int. +// +// This function does not perform any memory allocations. +// +//nolint:dupword // This comment is copied from the EIP-4844 specification func (g GasPrice) MulExp( excess Gas, - gasConversionConstant GasPrice, + excessConversionConstant Gas, ) GasPrice { var ( - iteration GasPrice = 1 - output GasPrice - numeratorAccum = g * gasConversionConstant + numerator uint256.Int + denominator uint256.Int + + i uint256.Int + output uint256.Int + numeratorAccum uint256.Int + + maxOutput uint256.Int // range is [0, MaxUint128] ) - for numeratorAccum > 0 { - output += numeratorAccum - numeratorAccum = (numeratorAccum * GasPrice(excess)) / (gasConversionConstant * iteration) - iteration++ + numerator.SetUint64(uint64(excess)) // range is [0, MaxUint64] + denominator.SetUint64(uint64(excessConversionConstant)) // range is [0, MaxUint64] + + i.SetOne() + numeratorAccum.SetUint64(uint64(g)) // range is [0, MaxUint64] + numeratorAccum.Mul(&numeratorAccum, &denominator) // range is [0, MaxUint128] + + maxOutput.Mul(&denominator, maxUint64) // range is [0, MaxUint128] + for numeratorAccum.Sign() > 0 { + output.Add(&output, &numeratorAccum) // range is [0, MaxUint192+MaxUint128] + if output.Cmp(&maxOutput) >= 0 { + return math.MaxUint64 + } + // maxOutput < MaxUint128 so numeratorAccum < MaxUint128. + numeratorAccum.Mul(&numeratorAccum, &numerator) // range is [0, MaxUint192] + numeratorAccum.Div(&numeratorAccum, &denominator) + numeratorAccum.Div(&numeratorAccum, &i) + + i.AddUint64(&i, 1) } - return output / gasConversionConstant + return GasPrice(output.Div(&output, &denominator).Uint64()) } - -// def fake_exponential(factor: int, numerator: int, denominator: int) -> int: -// i = 1 -// output = 0 -// numerator_accum = factor * denominator -// while numerator_accum > 0: -// output += numerator_accum -// numerator_accum = (numerator_accum * numerator) // (denominator * i) -// i += 1 -// return output // denominator diff --git a/vms/components/fee/gas_test.go b/vms/components/fee/gas_test.go index 61b2a61a62c8..3e62cdec819b 100644 --- a/vms/components/fee/gas_test.go +++ b/vms/components/fee/gas_test.go @@ -5,47 +5,175 @@ package fee import ( "fmt" + "math" "testing" "github.com/stretchr/testify/require" ) -func TestT(t *testing.T) { +var gasPriceMulExpTests = []struct { + minPrice GasPrice + excess Gas + excessConversionConstant Gas + expected GasPrice +}{ + { + minPrice: 1, + excess: 0, + excessConversionConstant: 1, + expected: 1, + }, + { + minPrice: 1, + excess: 1, + excessConversionConstant: 1, + expected: 2, + }, + { + minPrice: 1, + excess: 2, + excessConversionConstant: 1, + expected: 6, + }, + { + minPrice: 1, + excess: 10_000, + excessConversionConstant: 10_000, + expected: 2, + }, + { + minPrice: 1, + excess: 1_000_000, + excessConversionConstant: 10_000, + expected: math.MaxUint64, + }, + { + minPrice: 10, + excess: 10_000_000, + excessConversionConstant: 1_000_000, + expected: 220_264, + }, + { + minPrice: math.MaxUint64, + excess: math.MaxUint64, + excessConversionConstant: 1, + expected: math.MaxUint64, + }, + { + minPrice: math.MaxUint32, + excess: 1, + excessConversionConstant: 1, + expected: 11_674_931_546, + }, + { + minPrice: 6_786_177_901_268_885_274, // ~ MaxUint64 / e + excess: 1, + excessConversionConstant: 1, + expected: math.MaxUint64 - 11, + }, + { + minPrice: 6_786_177_901_268_885_274, // ~ MaxUint64 / e + excess: math.MaxUint64, + excessConversionConstant: math.MaxUint64, + expected: math.MaxUint64 - 1, + }, +} + +func Test_Gas_AddPerSecond(t *testing.T) { + tests := []struct { + initial Gas + gasPerSecond Gas + seconds uint64 + expected Gas + }{ + { + initial: 5, + gasPerSecond: 1, + seconds: 2, + expected: 7, + }, + { + initial: 5, + gasPerSecond: math.MaxUint64, + seconds: 2, + expected: math.MaxUint64, + }, + { + initial: math.MaxUint64, + gasPerSecond: 1, + seconds: 2, + expected: math.MaxUint64, + }, + { + initial: math.MaxUint64, + gasPerSecond: math.MaxUint64, + seconds: math.MaxUint64, + expected: math.MaxUint64, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d+%d*%d=%d", test.initial, test.gasPerSecond, test.seconds, test.expected), func(t *testing.T) { + actual := test.initial.AddPerSecond(test.gasPerSecond, test.seconds) + require.Equal(t, test.expected, actual) + }) + } +} + +func Test_Gas_SubPerSecond(t *testing.T) { tests := []struct { - minPrice GasPrice - excess Gas - gasConversionConstant GasPrice - expectedPrice GasPrice + initial Gas + gasPerSecond Gas + seconds uint64 + expected Gas }{ { - minPrice: 1, - excess: 0, - gasConversionConstant: 1, - expectedPrice: 1, + initial: 5, + gasPerSecond: 1, + seconds: 2, + expected: 3, }, { - minPrice: 1, - excess: 1, - gasConversionConstant: 1, - expectedPrice: 2, + initial: 5, + gasPerSecond: math.MaxUint64, + seconds: 2, + expected: 0, }, { - minPrice: 1, - excess: 2, - gasConversionConstant: 1, - expectedPrice: 6, + initial: 1, + gasPerSecond: 1, + seconds: 2, + expected: 0, }, { - minPrice: 1, - excess: 10_000, - gasConversionConstant: 10_000, - expectedPrice: 2, + initial: math.MaxUint64, + gasPerSecond: math.MaxUint64, + seconds: math.MaxUint64, + expected: 0, }, } for _, test := range tests { - t.Run(fmt.Sprintf("%d*e^(%d/%d)=%d", test.minPrice, test.excess, test.gasConversionConstant, test.expectedPrice), func(t *testing.T) { - outputPrice := test.minPrice.MulExp(test.excess, test.gasConversionConstant) - require.Equal(t, test.expectedPrice, outputPrice) + t.Run(fmt.Sprintf("%d-%d*%d=%d", test.initial, test.gasPerSecond, test.seconds, test.expected), func(t *testing.T) { + actual := test.initial.SubPerSecond(test.gasPerSecond, test.seconds) + require.Equal(t, test.expected, actual) + }) + } +} + +func Test_GasPrice_MulExp(t *testing.T) { + for _, test := range gasPriceMulExpTests { + t.Run(fmt.Sprintf("%d*e^(%d/%d)=%d", test.minPrice, test.excess, test.excessConversionConstant, test.expected), func(t *testing.T) { + actual := test.minPrice.MulExp(test.excess, test.excessConversionConstant) + require.Equal(t, test.expected, actual) + }) + } +} + +func Benchmark_GasPrice_MulExp(b *testing.B) { + for _, test := range gasPriceMulExpTests { + b.Run(fmt.Sprintf("%d*e^(%d/%d)=%d", test.minPrice, test.excess, test.excessConversionConstant, test.expected), func(b *testing.B) { + for i := 0; i < b.N; i++ { + test.minPrice.MulExp(test.excess, test.excessConversionConstant) + } }) } } diff --git a/vms/components/fee/helpers.go b/vms/components/fee/helpers.go deleted file mode 100644 index ca075afc1715..000000000000 --- a/vms/components/fee/helpers.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package fee - -import ( - "fmt" - - "github.com/ava-labs/avalanchego/codec" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" -) - -func MeterInput(c codec.Manager, v uint16, in *avax.TransferableInput) (Dimensions, error) { - cost, err := in.In.Cost() - if err != nil { - return Dimensions{}, fmt.Errorf("failed retrieving cost of input %s: %w", in.ID, err) - } - - inSize, err := c.Size(v, in) - if err != nil { - return Dimensions{}, fmt.Errorf("failed retrieving size of input %s: %w", in.ID, err) - } - uInSize := uint64(inSize) - - return Dimensions{ - Bandwidth: uInSize - codec.VersionSize, - DBRead: uInSize, // inputs are read - DBWrite: uInSize, // inputs are deleted - Compute: cost, - }, nil -} - -func MeterOutput(c codec.Manager, v uint16, out *avax.TransferableOutput) (Dimensions, error) { - outSize, err := c.Size(v, out) - if err != nil { - return Dimensions{}, fmt.Errorf("failed retrieving size of output %s: %w", out.ID, err) - } - uOutSize := uint64(outSize) - - return Dimensions{ - Bandwidth: uOutSize - codec.VersionSize, - DBWrite: uOutSize, - }, nil -} - -func MeterCredential(c codec.Manager, v uint16, keysCount int) (Dimensions, error) { - // Ensure that codec picks interface instead of the pointer to evaluate size. - var cred verify.Verifiable = &secp256k1fx.Credential{ - Sigs: make([][secp256k1.SignatureLen]byte, keysCount), - } - credSize, err := c.Size(v, &cred) - if err != nil { - return Dimensions{}, fmt.Errorf("failed retrieving size of credentials: %w", err) - } - - return Dimensions{ - Bandwidth: uint64(credSize) - codec.VersionSize, - }, nil -} diff --git a/vms/components/fee/state.go b/vms/components/fee/state.go index 75f3b698822b..0d454b2c7b8d 100644 --- a/vms/components/fee/state.go +++ b/vms/components/fee/state.go @@ -3,17 +3,51 @@ package fee +import ( + "errors" + "math" + + safemath "github.com/ava-labs/avalanchego/utils/math" +) + +var ErrInsufficientCapacity = errors.New("insufficient capacity") + type State struct { Capacity Gas Excess Gas } -func (s State) AdvanceTime(c Config, duration uint64) State { +func (s State) AdvanceTime( + maxGasCapacity Gas, + maxGasPerSecond Gas, + targetGasPerSecond Gas, + duration uint64, +) State { return State{ Capacity: min( - s.Capacity.AddPerSecond(c.MaxGasPerSecond, duration), - c.MaxGasCapacity, + s.Capacity.AddPerSecond(maxGasPerSecond, duration), + maxGasCapacity, ), - Excess: s.Excess.SubPerSecond(c.TargetGasPerSecond, duration), + Excess: s.Excess.SubPerSecond(targetGasPerSecond, duration), + } +} + +func (s State) ConsumeGas(gas Gas) (State, error) { + newCapacity, err := safemath.Sub(uint64(s.Capacity), uint64(gas)) + if err != nil { + return State{}, ErrInsufficientCapacity + } + + newExcess, err := safemath.Add64(uint64(s.Excess), uint64(gas)) + if err != nil { + return State{ + Capacity: Gas(newCapacity), + Excess: math.MaxUint64, + }, nil } + + return State{ + Capacity: Gas(newCapacity), + Excess: Gas(newExcess), + }, nil } diff --git a/vms/components/fee/state_test.go b/vms/components/fee/state_test.go new file mode 100644 index 000000000000..d688acd745d9 --- /dev/null +++ b/vms/components/fee/state_test.go @@ -0,0 +1,162 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "math" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_State_AdvanceTime(t *testing.T) { + tests := []struct { + name string + initial State + maxGasCapacity Gas + maxGasPerSecond Gas + targetGasPerSecond Gas + duration uint64 + expected State + }{ + { + name: "cap capacity", + initial: State{ + Capacity: 10, + Excess: 0, + }, + maxGasCapacity: 20, + maxGasPerSecond: 10, + targetGasPerSecond: 0, + duration: 2, + expected: State{ + Capacity: 20, + Excess: 0, + }, + }, + { + name: "increase capacity", + initial: State{ + Capacity: 10, + Excess: 0, + }, + maxGasCapacity: 30, + maxGasPerSecond: 10, + targetGasPerSecond: 0, + duration: 1, + expected: State{ + Capacity: 20, + Excess: 0, + }, + }, + { + name: "avoid excess underflow", + initial: State{ + Capacity: 10, + Excess: 10, + }, + maxGasCapacity: 20, + maxGasPerSecond: 10, + targetGasPerSecond: 10, + duration: 2, + expected: State{ + Capacity: 20, + Excess: 0, + }, + }, + { + name: "reduce excess", + initial: State{ + Capacity: 10, + Excess: 10, + }, + maxGasCapacity: 20, + maxGasPerSecond: 10, + targetGasPerSecond: 5, + duration: 1, + expected: State{ + Capacity: 20, + Excess: 5, + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + actual := test.initial.AdvanceTime(test.maxGasCapacity, test.maxGasPerSecond, test.targetGasPerSecond, test.duration) + require.Equal(t, test.expected, actual) + }) + } +} + +func Test_State_ConsumeGas(t *testing.T) { + tests := []struct { + name string + initial State + gas Gas + expected State + expectedErr error + }{ + { + name: "consume some gas", + initial: State{ + Capacity: 10, + Excess: 10, + }, + gas: 5, + expected: State{ + Capacity: 5, + Excess: 15, + }, + expectedErr: nil, + }, + { + name: "consume all gas", + initial: State{ + Capacity: 10, + Excess: 10, + }, + gas: 10, + expected: State{ + Capacity: 0, + Excess: 20, + }, + expectedErr: nil, + }, + { + name: "consume too much gas", + initial: State{ + Capacity: 10, + Excess: 10, + }, + gas: 11, + expected: State{ + Capacity: 0, + Excess: 0, + }, + expectedErr: ErrInsufficientCapacity, + }, + { + name: "maximum excess", + initial: State{ + Capacity: 10, + Excess: math.MaxUint64, + }, + gas: 1, + expected: State{ + Capacity: 9, + Excess: math.MaxUint64, + }, + expectedErr: nil, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + actual, err := test.initial.ConsumeGas(test.gas) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + }) + } +} diff --git a/vms/components/fee/update.go b/vms/components/fee/update.go deleted file mode 100644 index 8c005cdca584..000000000000 --- a/vms/components/fee/update.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package fee - -// var errChildTimeBeforeParent = errors.New("child block time before parent block time") - -// // We cap the maximum gas consumed by time with a leaky bucket approach -// // GasCap = min (GasCap + MaxGasPerSecond/LeakGasCoeff*ElapsedTime, MaxGasPerSecond) -// func GasCap(cfg Config, currentGasCapacity Gas, parentBlkTime, childBlkTime time.Time) (Gas, error) { -// if childBlkTime.Before(parentBlkTime) { -// return 0, fmt.Errorf("%w, parentBlkTim %v, childBlkTime %v", errChildTimeBeforeParent, 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 -// } From eb9ff58cec4605fcfe863729a33705d186a6b3c1 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jul 2024 11:39:24 -0400 Subject: [PATCH 060/100] reduce diff --- vms/platformvm/txs/fee/calculator.go | 16 +- vms/platformvm/txs/fee/calculator_test.go | 979 +++---------------- vms/platformvm/txs/fee/dynamic_calculator.go | 312 ------ vms/platformvm/txs/fee/static_calculator.go | 31 - 4 files changed, 116 insertions(+), 1222 deletions(-) delete mode 100644 vms/platformvm/txs/fee/dynamic_calculator.go diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 1cfc62c581a7..f33db9c1520f 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -3,23 +3,9 @@ package fee -import ( - "github.com/ava-labs/avalanchego/vms/components/fee" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" -) +import "github.com/ava-labs/avalanchego/vms/platformvm/txs" // Calculator is the interfaces that any fee Calculator must implement type Calculator interface { CalculateFee(tx *txs.Tx) (uint64, error) - - GetFee() uint64 - ResetFee(newFee uint64) - AddFeesFor(complexity fee.Dimensions) (uint64, error) - RemoveFeesFor(unitsToRm fee.Dimensions) (uint64, error) - GetGasPrice() fee.GasPrice - GetBlockGas() (fee.Gas, error) - GetGasCap() fee.Gas - setCredentials(creds []verify.Verifiable) - IsEActive() bool } diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index f0652a90accf..454072e9df8d 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -4,84 +4,18 @@ package fee import ( - "errors" "testing" "time" "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/fee" - "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/signer" - "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) -var ( - testFeeWeights = fee.Dimensions{1, 1, 1, 1} - testGasPrice = fee.GasPrice(10 * units.NanoAvax) - testBlockMaxGas = fee.Gas(100_000) - - preFundedKeys = secp256k1.TestKeys() - feeTestSigners = [][]*secp256k1.PrivateKey{preFundedKeys} - feeTestDefaultStakeWeight = uint64(2024) - - errFailedComplexityCumulation = errors.New("failed cumulating complexity") -) - -func TestAddAndRemoveFees(t *testing.T) { - r := require.New(t) - - fc := NewDynamicCalculator(fee.NewCalculator(testFeeWeights, testGasPrice, testBlockMaxGas)) - - var ( - units = fee.Dimensions{1, 2, 3, 4} - gas = fee.Gas(1) - doubleGas = fee.Gas(2) - ) - - feeDelta, err := fc.AddFeesFor(units) - r.NoError(err) - - haveGas, err := fc.GetBlockGas() - r.NoError(err) - r.Equal(gas, haveGas) - r.NotZero(feeDelta) - r.Equal(feeDelta, fc.GetFee()) - - feeDelta2, err := fc.AddFeesFor(units) - r.NoError(err) - haveGas, err = fc.GetBlockGas() - r.NoError(err) - r.Equal(doubleGas, haveGas) - r.Equal(feeDelta, feeDelta2) - r.Equal(feeDelta+feeDelta2, fc.GetFee()) - - feeDelta3, err := fc.RemoveFeesFor(units) - r.NoError(err) - haveGas, err = fc.GetBlockGas() - r.NoError(err) - r.Equal(gas, haveGas) - r.Equal(feeDelta, feeDelta3) - r.Equal(feeDelta, fc.GetFee()) - - feeDelta4, err := fc.RemoveFeesFor(units) - r.NoError(err) - r.Zero(fc.GetBlockGas()) - r.Equal(feeDelta, feeDelta4) - r.Zero(fc.GetFee()) -} - func TestTxFees(t *testing.T) { feeTestsDefaultCfg := StaticConfig{ TxFee: 1 * units.Avax, @@ -106,897 +40,214 @@ func TestTxFees(t *testing.T) { } // chain times needed to have specific upgrades active - postEUpgradeTime := upgrades.EUpgradeTime.Add(time.Second) preEUpgradeTime := upgrades.EUpgradeTime.Add(-1 * time.Second) preApricotPhase3Time := upgrades.ApricotPhase3Time.Add(-1 * time.Second) tests := []struct { - name string - chainTime time.Time - signedTxF func(t *testing.T) *txs.Tx - gasCapF func() fee.Gas - expectedError error - checksF func(*testing.T, Calculator) + name string + chainTime time.Time + unsignedTx func() txs.UnsignedTx + expected uint64 }{ { - name: "AddValidatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: addValidatorTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, c.GetFee()) - }, - }, - { - name: "AddValidatorTx post EUpgrade", - chainTime: postEUpgradeTime, - expectedError: errFailedFeeCalculation, - signedTxF: addValidatorTx, - checksF: func(*testing.T, Calculator) {}, - }, - { - name: "AddSubnetValidatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: addSubnetValidatorTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.AddSubnetValidatorFee, c.GetFee()) - }, - }, - { - name: "AddSubnetValidatorTx post EUpgrade, success", - chainTime: postEUpgradeTime, - expectedError: nil, - signedTxF: addSubnetValidatorTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 2_910*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(291), haveGas) - }, - }, - { - name: "AddSubnetValidatorTx post EUpgrade, utxos read cap breached", - chainTime: postEUpgradeTime, - gasCapF: func() fee.Gas { - return testBlockMaxGas - 1 - }, - signedTxF: addSubnetValidatorTx, - expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, Calculator) {}, - }, - { - name: "AddDelegatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: addDelegatorTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, c.GetFee()) - }, - }, - { - name: "AddDelegatorTx post EUpgrade", - chainTime: postEUpgradeTime, - expectedError: errFailedFeeCalculation, - signedTxF: addDelegatorTx, - checksF: func(*testing.T, Calculator) {}, - }, - { - name: "CreateChainTx pre ApricotPhase3", - chainTime: preApricotPhase3Time, - signedTxF: createChainTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.CreateAssetTxFee, c.GetFee()) - }, - }, - { - name: "CreateChainTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: createChainTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.CreateBlockchainTxFee, c.GetFee()) - }, - }, - { - name: "CreateChainTx post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: createChainTx, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 1_950*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(195), haveGas) - }, - }, - { - name: "CreateChainTx post EUpgrade, utxos read cap breached", - chainTime: postEUpgradeTime, - signedTxF: createChainTx, - gasCapF: func() fee.Gas { - return testBlockMaxGas - 1 - }, - expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, Calculator) {}, - }, - { - name: "CreateSubnetTx pre ApricotPhase3", - chainTime: preApricotPhase3Time, - signedTxF: createSubnetTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.CreateAssetTxFee, c.GetFee()) - }, - }, - { - name: "CreateSubnetTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: createSubnetTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.CreateSubnetTxFee, c.GetFee()) - }, - }, - { - name: "CreateSubnetTx post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: createSubnetTx, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 1_850*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(185), haveGas) - }, + name: "AddValidatorTx pre EUpgrade", + chainTime: preEUpgradeTime, + unsignedTx: addValidatorTx, + expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, }, { - name: "CreateSubnetTx post EUpgrade, utxos read cap breached", - chainTime: postEUpgradeTime, - signedTxF: createSubnetTx, - gasCapF: func() fee.Gas { - return testBlockMaxGas - 1 - }, - expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, Calculator) {}, + name: "AddSubnetValidatorTx pre EUpgrade", + chainTime: preEUpgradeTime, + unsignedTx: addSubnetValidatorTx, + expected: feeTestsDefaultCfg.AddSubnetValidatorFee, }, { - name: "RemoveSubnetValidatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: removeSubnetValidatorTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) - }, + name: "AddDelegatorTx pre EUpgrade", + chainTime: preEUpgradeTime, + unsignedTx: addDelegatorTx, + expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, }, { - name: "RemoveSubnetValidatorTx post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: removeSubnetValidatorTx, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 2_880*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(288), haveGas) - }, + name: "CreateChainTx pre ApricotPhase3", + chainTime: preApricotPhase3Time, + unsignedTx: createChainTx, + expected: feeTestsDefaultCfg.CreateAssetTxFee, }, { - name: "RemoveSubnetValidatorTx post EUpgrade, utxos read cap breached", - chainTime: postEUpgradeTime, - gasCapF: func() fee.Gas { - return testBlockMaxGas - 1 - }, - signedTxF: removeSubnetValidatorTx, - expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, Calculator) {}, + name: "CreateChainTx pre EUpgrade", + chainTime: preEUpgradeTime, + unsignedTx: createChainTx, + expected: feeTestsDefaultCfg.CreateBlockchainTxFee, }, { - name: "TransformSubnetTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: transformSubnetTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.TransformSubnetTxFee, c.GetFee()) - }, + name: "CreateSubnetTx pre ApricotPhase3", + chainTime: preApricotPhase3Time, + unsignedTx: createSubnetTx, + expected: feeTestsDefaultCfg.CreateAssetTxFee, }, { - name: "TransformSubnetTx post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: transformSubnetTx, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 1_970*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(197), haveGas) - }, + name: "CreateSubnetTx pre EUpgrade", + chainTime: preEUpgradeTime, + unsignedTx: createSubnetTx, + expected: feeTestsDefaultCfg.CreateSubnetTxFee, }, { - name: "TransformSubnetTx post EUpgrade, utxos read cap breached", - chainTime: postEUpgradeTime, - gasCapF: func() fee.Gas { - return testBlockMaxGas - 1 - }, - signedTxF: transformSubnetTx, - expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, Calculator) {}, - }, - { - name: "TransferSubnetOwnershipTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: transferSubnetOwnershipTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) - }, + name: "RemoveSubnetValidatorTx pre EUpgrade", + chainTime: preEUpgradeTime, + unsignedTx: removeSubnetValidatorTx, + expected: feeTestsDefaultCfg.TxFee, }, { - name: "TransferSubnetOwnershipTx post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: transferSubnetOwnershipTx, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 1_900*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(190), haveGas) - }, + name: "TransformSubnetTx pre EUpgrade", + chainTime: preEUpgradeTime, + unsignedTx: transformSubnetTx, + expected: feeTestsDefaultCfg.TransformSubnetTxFee, }, { - name: "TransferSubnetOwnershipTx post EUpgrade, utxos read cap breached", - chainTime: postEUpgradeTime, - gasCapF: func() fee.Gas { - return testBlockMaxGas - 1 - }, - signedTxF: transferSubnetOwnershipTx, - expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, Calculator) {}, + name: "TransferSubnetOwnershipTx pre EUpgrade", + chainTime: preEUpgradeTime, + unsignedTx: transferSubnetOwnershipTx, + expected: feeTestsDefaultCfg.TxFee, }, { name: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: func(t *testing.T) *txs.Tx { - return addPermissionlessValidatorTx(t, constants.PrimaryNetworkID) - }, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, c.GetFee()) + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func() txs.UnsignedTx { + return addPermissionlessValidatorTx(constants.PrimaryNetworkID) }, + expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, }, { name: "AddPermissionlessValidatorTx Subnet pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: func(t *testing.T) *txs.Tx { - subnetID := ids.GenerateTestID() - require.NotEqual(t, constants.PrimaryNetworkID, subnetID) - return addPermissionlessValidatorTx(t, subnetID) - }, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.AddSubnetValidatorFee, c.GetFee()) - }, - }, - { - name: "AddPermissionlessValidatorTx Primary Network post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: func(t *testing.T) *txs.Tx { - return addPermissionlessValidatorTx(t, constants.PrimaryNetworkID) - }, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 3_310*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(331), haveGas) - }, - }, - { - name: "AddPermissionlessValidatorTx Subnet post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: func(t *testing.T) *txs.Tx { + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func() txs.UnsignedTx { subnetID := ids.GenerateTestID() require.NotEqual(t, constants.PrimaryNetworkID, subnetID) - return addPermissionlessValidatorTx(t, subnetID) - }, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 3_310*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(331), haveGas) + return addPermissionlessValidatorTx(subnetID) }, - }, - { - name: "AddPermissionlessValidatorTx post EUpgrade, utxos read cap breached", - chainTime: postEUpgradeTime, - gasCapF: func() fee.Gas { - return testBlockMaxGas - 1 - }, - signedTxF: func(t *testing.T) *txs.Tx { - subnetID := ids.GenerateTestID() - return addPermissionlessValidatorTx(t, subnetID) - }, - expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, Calculator) {}, + expected: feeTestsDefaultCfg.AddSubnetValidatorFee, }, { name: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: func(t *testing.T) *txs.Tx { - return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) - }, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, c.GetFee()) + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func() txs.UnsignedTx { + return addPermissionlessDelegatorTx(constants.PrimaryNetworkID) }, + expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, }, { name: "AddPermissionlessDelegatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: func(t *testing.T) *txs.Tx { + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func() txs.UnsignedTx { subnetID := ids.GenerateTestID() require.NotEqual(t, constants.PrimaryNetworkID, subnetID) - return addPermissionlessDelegatorTx(t, subnetID) - }, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.AddSubnetDelegatorFee, c.GetFee()) + return addPermissionlessDelegatorTx(subnetID) }, + expected: feeTestsDefaultCfg.AddSubnetDelegatorFee, }, { - name: "AddPermissionlessDelegatorTx Primary Network post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: func(t *testing.T) *txs.Tx { - return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) - }, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 3_120*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(312), haveGas) - }, + name: "BaseTx pre EUpgrade", + chainTime: preEUpgradeTime, + unsignedTx: baseTx, + expected: feeTestsDefaultCfg.TxFee, }, { - name: "AddPermissionlessDelegatorTx Subnet post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: func(t *testing.T) *txs.Tx { - return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) - }, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 3_120*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(312), haveGas) - }, + name: "ImportTx pre EUpgrade", + chainTime: preEUpgradeTime, + unsignedTx: importTx, + expected: feeTestsDefaultCfg.TxFee, }, { - name: "AddPermissionlessDelegatorTx Subnet post EUpgrade, utxos read cap breached", - chainTime: postEUpgradeTime, - gasCapF: func() fee.Gas { - return testBlockMaxGas - 1 - }, - signedTxF: func(t *testing.T) *txs.Tx { - subnetID := ids.GenerateTestID() - require.NotEqual(t, constants.PrimaryNetworkID, subnetID) - return addPermissionlessValidatorTx(t, subnetID) - }, - expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, Calculator) {}, - }, - { - name: "BaseTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: baseTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) - }, - }, - { - name: "BaseTx post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: baseTx, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 1_810*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(181), haveGas) - }, - }, - { - name: "BaseTx post EUpgrade, utxos read cap breached", - chainTime: postEUpgradeTime, - gasCapF: func() fee.Gas { - return testBlockMaxGas - 1 - }, - signedTxF: baseTx, - expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, Calculator) {}, - }, - { - name: "ImportTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: importTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) - }, - }, - { - name: "ImportTx post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: importTx, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 3_120*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(312), haveGas) - }, - }, - { - name: "ImportTx post EUpgrade, utxos read cap breached", - chainTime: postEUpgradeTime, - gasCapF: func() fee.Gas { - return testBlockMaxGas - 1 - }, - signedTxF: importTx, - expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, Calculator) {}, - }, - { - name: "ExportTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: exportTx, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) - }, - }, - { - name: "ExportTx post EUpgrade, success", - chainTime: postEUpgradeTime, - signedTxF: exportTx, - expectedError: nil, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, 2_040*units.NanoAvax, c.GetFee()) - haveGas, err := c.GetBlockGas() - require.NoError(t, err) - require.Equal(t, fee.Gas(204), haveGas) - }, - }, - { - name: "ExportTx post EUpgrade, utxos read cap breached", - chainTime: postEUpgradeTime, - gasCapF: func() fee.Gas { - return testBlockMaxGas - 1 - }, - signedTxF: exportTx, - expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, Calculator) {}, + name: "ExportTx pre EUpgrade", + chainTime: preEUpgradeTime, + unsignedTx: exportTx, + expected: feeTestsDefaultCfg.TxFee, }, { name: "RewardValidatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: func(_ *testing.T) *txs.Tx { - return &txs.Tx{ - Unsigned: &txs.RewardValidatorTx{ - TxID: ids.GenerateTestID(), - }, - } - }, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, uint64(0), c.GetFee()) - }, - }, - { - name: "RewardValidatorTx post EUpgrade", - chainTime: postEUpgradeTime, - signedTxF: func(_ *testing.T) *txs.Tx { - return &txs.Tx{ - Unsigned: &txs.RewardValidatorTx{ - TxID: ids.GenerateTestID(), - }, + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func() txs.UnsignedTx { + return &txs.RewardValidatorTx{ + TxID: ids.GenerateTestID(), } }, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, uint64(0), c.GetFee()) - }, + expected: 0, }, { name: "AdvanceTimeTx pre EUpgrade", - chainTime: preEUpgradeTime, - signedTxF: func(_ *testing.T) *txs.Tx { - return &txs.Tx{ - Unsigned: &txs.AdvanceTimeTx{ - Time: uint64(time.Now().Unix()), - }, - } - }, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, uint64(0), c.GetFee()) - }, - }, - { - name: "AdvanceTimeTx post EUpgrade", - chainTime: postEUpgradeTime, - signedTxF: func(_ *testing.T) *txs.Tx { - return &txs.Tx{ - Unsigned: &txs.AdvanceTimeTx{ - Time: uint64(time.Now().Unix()), - }, + chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), + unsignedTx: func() txs.UnsignedTx { + return &txs.AdvanceTimeTx{ + Time: uint64(time.Now().Unix()), } }, - checksF: func(t *testing.T, c Calculator) { - require.Equal(t, uint64(0), c.GetFee()) - }, + expected: 0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - gasCap := testBlockMaxGas - if tt.gasCapF != nil { - gasCap = tt.gasCapF() - } - - var c Calculator - if !upgrades.IsEActivated(tt.chainTime) { - c = NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) - } else { - c = NewDynamicCalculator(fee.NewCalculator(testFeeWeights, testGasPrice, gasCap)) - } - - sTx := tt.signedTxF(t) - _, _ = c.CalculateFee(sTx) - tt.checksF(t, c) + uTx := tt.unsignedTx() + fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) + fee, err := fc.CalculateFee(&txs.Tx{Unsigned: uTx}) + require.NoError(t, err) + require.Equal(t, tt.expected, fee) }) } } -func addValidatorTx(t *testing.T) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, stakes, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.AddValidatorTx{ - BaseTx: baseTx, - Validator: txs.Validator{ - NodeID: defaultCtx.NodeID, - Start: uint64(time.Now().Truncate(time.Second).Unix()), - End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), - Wght: feeTestDefaultStakeWeight, - }, - StakeOuts: stakes, - RewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ids.GenerateTestShortID()}, - }, - DelegationShares: reward.PercentDenominator, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - - return sTx +func addValidatorTx() txs.UnsignedTx { + return &txs.AddValidatorTx{} } -func addSubnetValidatorTx(t *testing.T) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - subnetID := ids.GenerateTestID() - baseTx, _, subnetAuth := txsCreationHelpers(defaultCtx) - uTx := &txs.AddSubnetValidatorTx{ - BaseTx: baseTx, - SubnetValidator: txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: defaultCtx.NodeID, - Start: uint64(time.Now().Truncate(time.Second).Unix()), - End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), - Wght: feeTestDefaultStakeWeight, - }, - Subnet: subnetID, - }, - SubnetAuth: subnetAuth, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx +func addSubnetValidatorTx() txs.UnsignedTx { + return &txs.AddSubnetValidatorTx{} } -func addDelegatorTx(t *testing.T) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, stakes, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.AddDelegatorTx{ - BaseTx: baseTx, - Validator: txs.Validator{ - NodeID: defaultCtx.NodeID, - Start: uint64(time.Now().Truncate(time.Second).Unix()), - End: uint64(time.Now().Truncate(time.Second).Add(time.Hour).Unix()), - Wght: feeTestDefaultStakeWeight, - }, - StakeOuts: stakes, - DelegationRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, - }, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx +func addDelegatorTx() txs.UnsignedTx { + return &txs.AddDelegatorTx{} } -func createChainTx(t *testing.T) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, subnetAuth := txsCreationHelpers(defaultCtx) - uTx := &txs.CreateChainTx{ - BaseTx: baseTx, - SubnetID: ids.GenerateTestID(), - ChainName: "testingStuff", - VMID: ids.GenerateTestID(), - FxIDs: []ids.ID{ids.GenerateTestID()}, - GenesisData: []byte{0xff}, - SubnetAuth: subnetAuth, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx +func createChainTx() txs.UnsignedTx { + return &txs.CreateChainTx{} } -func createSubnetTx(t *testing.T) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.CreateSubnetTx{ - BaseTx: baseTx, - Owner: &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, - }, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx +func createSubnetTx() txs.UnsignedTx { + return &txs.CreateSubnetTx{} } -func removeSubnetValidatorTx(t *testing.T) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, auth := txsCreationHelpers(defaultCtx) - uTx := &txs.RemoveSubnetValidatorTx{ - BaseTx: baseTx, - NodeID: ids.GenerateTestNodeID(), - Subnet: ids.GenerateTestID(), - SubnetAuth: auth, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx +func removeSubnetValidatorTx() txs.UnsignedTx { + return &txs.RemoveSubnetValidatorTx{} } -func transformSubnetTx(t *testing.T) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, auth := txsCreationHelpers(defaultCtx) - uTx := &txs.TransformSubnetTx{ - BaseTx: baseTx, - Subnet: ids.GenerateTestID(), - AssetID: ids.GenerateTestID(), - InitialSupply: 0x1000000000000000, - MaximumSupply: 0x1000000000000000, - MinConsumptionRate: 0, - MaxConsumptionRate: 0, - MinValidatorStake: 1, - MaxValidatorStake: 0x1000000000000000, - MinStakeDuration: 1, - MaxStakeDuration: 1, - MinDelegationFee: 0, - MinDelegatorStake: 0xffffffffffffffff, - MaxValidatorWeightFactor: 255, - UptimeRequirement: 0, - SubnetAuth: auth, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx +func transformSubnetTx() txs.UnsignedTx { + return &txs.TransformSubnetTx{} } -func transferSubnetOwnershipTx(t *testing.T) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.TransferSubnetOwnershipTx{ - BaseTx: baseTx, - Subnet: ids.GenerateTestID(), - SubnetAuth: &secp256k1fx.Input{ - SigIndices: []uint32{3}, - }, - Owner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - ids.GenerateTestShortID(), - }, - }, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx +func transferSubnetOwnershipTx() txs.UnsignedTx { + return &txs.TransferSubnetOwnershipTx{} } -func addPermissionlessValidatorTx(t *testing.T, subnetID ids.ID) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, stakes, _ := txsCreationHelpers(defaultCtx) - sk, err := bls.NewSecretKey() - r.NoError(err) - uTx := &txs.AddPermissionlessValidatorTx{ - BaseTx: baseTx, - Subnet: subnetID, - Signer: signer.NewProofOfPossession(sk), - StakeOuts: stakes, - ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - ids.GenerateTestShortID(), - }, - }, - DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - ids.GenerateTestShortID(), - }, - }, - DelegationShares: reward.PercentDenominator, +func addPermissionlessValidatorTx(subnetID ids.ID) txs.UnsignedTx { + return &txs.AddPermissionlessValidatorTx{ + Subnet: subnetID, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx } -func addPermissionlessDelegatorTx(t *testing.T, subnetID ids.ID) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, stakes, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.AddPermissionlessDelegatorTx{ - BaseTx: baseTx, - Validator: txs.Validator{ - NodeID: ids.GenerateTestNodeID(), - Start: 12345, - End: 12345 + 200*24*60*60, - Wght: 2 * units.KiloAvax, - }, - Subnet: subnetID, - StakeOuts: stakes, - DelegationRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - ids.GenerateTestShortID(), - }, - }, +func addPermissionlessDelegatorTx(subnetID ids.ID) txs.UnsignedTx { + return &txs.AddPermissionlessDelegatorTx{ + Subnet: subnetID, } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx -} - -func baseTx(t *testing.T) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, _ := txsCreationHelpers(defaultCtx) - uTx := &baseTx - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx } -func importTx(t *testing.T) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, _, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.ImportTx{ - BaseTx: baseTx, - SourceChain: ids.GenerateTestID(), - ImportedInputs: []*avax.TransferableInput{{ - UTXOID: avax.UTXOID{ - TxID: ids.Empty.Prefix(1), - OutputIndex: 1, - }, - Asset: avax.Asset{ID: ids.ID{'a', 's', 's', 'e', 'r', 't'}}, - In: &secp256k1fx.TransferInput{ - Amt: 50000, - Input: secp256k1fx.Input{SigIndices: []uint32{0}}, - }, - }}, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx +func baseTx() txs.UnsignedTx { + return &txs.BaseTx{} } -func exportTx(t *testing.T) *txs.Tx { - r := require.New(t) - - defaultCtx := snowtest.Context(t, snowtest.PChainID) - - baseTx, outputs, _ := txsCreationHelpers(defaultCtx) - uTx := &txs.ExportTx{ - BaseTx: baseTx, - DestinationChain: ids.GenerateTestID(), - ExportedOutputs: outputs, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - return sTx +func importTx() txs.UnsignedTx { + return &txs.ImportTx{} } -func txsCreationHelpers(defaultCtx *snow.Context) ( - baseTx txs.BaseTx, - stakes []*avax.TransferableOutput, - auth *secp256k1fx.Input, -) { - inputs := []*avax.TransferableInput{{ - UTXOID: avax.UTXOID{ - TxID: ids.ID{'t', 'x', 'I', 'D'}, - OutputIndex: 2, - }, - Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, - In: &secp256k1fx.TransferInput{ - Amt: uint64(5678), - Input: secp256k1fx.Input{SigIndices: []uint32{0}}, - }, - }} - outputs := []*avax.TransferableOutput{{ - Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: uint64(1234), - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, - }, - }, - }} - stakes = []*avax.TransferableOutput{{ - Asset: avax.Asset{ID: defaultCtx.AVAXAssetID}, - Out: &stakeable.LockOut{ - Locktime: uint64(time.Now().Add(time.Second).Unix()), - TransferableOut: &secp256k1fx.TransferOutput{ - Amt: feeTestDefaultStakeWeight, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, - }, - }, - }, - }} - auth = &secp256k1fx.Input{ - SigIndices: []uint32{0, 1}, - } - baseTx = txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: defaultCtx.NetworkID, - BlockchainID: defaultCtx.ChainID, - Ins: inputs, - Outs: outputs, - }, - } - - return baseTx, stakes, auth +func exportTx() txs.UnsignedTx { + return &txs.ExportTx{} } diff --git a/vms/platformvm/txs/fee/dynamic_calculator.go b/vms/platformvm/txs/fee/dynamic_calculator.go deleted file mode 100644 index f16a56122837..000000000000 --- a/vms/platformvm/txs/fee/dynamic_calculator.go +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package fee - -import ( - "errors" - "fmt" - - "github.com/ava-labs/avalanchego/codec" - "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/fee" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" -) - -const StakerLookupCost uint64 = 1000 // equal to secp256k1fx.CostPerSignature - -var ( - _ Calculator = (*dynamicCalculator)(nil) - _ txs.Visitor = (*staticCalculator)(nil) - - errFailedFeeCalculation = errors.New("failed fee calculation") -) - -func NewDynamicCalculator(fc *fee.Calculator) Calculator { - return &dynamicCalculator{ - fc: fc, - buildingTx: false, - // credentials are set when computeFee is called - } -} - -func NewBuildingDynamicCalculator(fc *fee.Calculator) Calculator { - return &dynamicCalculator{ - fc: fc, - buildingTx: true, - // credentials are set when computeFee is called - } -} - -type dynamicCalculator struct { - // inputs - fc *fee.Calculator - cred []verify.Verifiable - - buildingTx bool - - // outputs of visitor execution - fee uint64 -} - -func (c *dynamicCalculator) CalculateFee(tx *txs.Tx) (uint64, error) { - c.setCredentials(tx.Creds) - c.fee = 0 // zero fee among different calculateFee invocations (unlike gas which gets cumulated) - err := tx.Unsigned.Visit(c) - if !c.buildingTx { - err = errors.Join(err, c.fc.DoneWithLatestTx()) - } - return c.fee, err -} - -func (c *dynamicCalculator) AddFeesFor(complexity fee.Dimensions) (uint64, error) { - fee, err := c.fc.AddFeesFor(complexity) - if err != nil { - return 0, fmt.Errorf("failed cumulating complexity: %w", err) - } - - extraFee := fee - c.fee - c.fee = fee - return extraFee, nil -} - -func (c *dynamicCalculator) RemoveFeesFor(unitsToRm fee.Dimensions) (uint64, error) { - fee, err := c.fc.RemoveFeesFor(unitsToRm) - if err != nil { - return 0, fmt.Errorf("failed removing complexity: %w", err) - } - - removedFee := c.fee - fee - c.fee = fee - return removedFee, nil -} - -func (c *dynamicCalculator) GetFee() uint64 { return c.fee } - -func (c *dynamicCalculator) ResetFee(newFee uint64) { - c.fee = newFee -} - -func (c *dynamicCalculator) GetGasPrice() fee.GasPrice { return c.fc.GetGasPrice() } - -func (c *dynamicCalculator) GetBlockGas() (fee.Gas, error) { return c.fc.GetBlockGas() } - -func (c *dynamicCalculator) GetGasCap() fee.Gas { return c.fc.GetGasCap() } - -func (c *dynamicCalculator) setCredentials(creds []verify.Verifiable) { - c.cred = creds -} - -func (*dynamicCalculator) IsEActive() bool { return true } - -func (*dynamicCalculator) AddValidatorTx(*txs.AddValidatorTx) error { - // AddValidatorTx is banned following Durango activation - return errFailedFeeCalculation -} - -func (c *dynamicCalculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { - complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) - if err != nil { - return err - } - complexity[fee.Compute] += StakerLookupCost - - _, err = c.AddFeesFor(complexity) - return err -} - -func (*dynamicCalculator) AddDelegatorTx(*txs.AddDelegatorTx) error { - // AddDelegatorTx is banned following Durango activation - return errFailedFeeCalculation -} - -func (c *dynamicCalculator) CreateChainTx(tx *txs.CreateChainTx) error { - complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) - if err != nil { - return err - } - - _, err = c.AddFeesFor(complexity) - return err -} - -func (c *dynamicCalculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { - complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) - if err != nil { - return err - } - - _, err = c.AddFeesFor(complexity) - return err -} - -func (c *dynamicCalculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - c.fee = 0 // no fees - return nil -} - -func (c *dynamicCalculator) RewardValidatorTx(*txs.RewardValidatorTx) error { - c.fee = 0 // no fees - return nil -} - -func (c *dynamicCalculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { - complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) - if err != nil { - return err - } - complexity[fee.Compute] += StakerLookupCost - - _, err = c.AddFeesFor(complexity) - return err -} - -func (c *dynamicCalculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { - complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) - if err != nil { - return err - } - - _, err = c.AddFeesFor(complexity) - return err -} - -func (c *dynamicCalculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { - complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) - if err != nil { - return err - } - - _, err = c.AddFeesFor(complexity) - return err -} - -func (c *dynamicCalculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { - outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.StakeOuts)) - copy(outs, tx.Outs) - copy(outs[len(tx.Outs):], tx.StakeOuts) - - complexity, err := c.meterTx(tx, outs, tx.Ins) - if err != nil { - return err - } - complexity[fee.Compute] += StakerLookupCost - - _, err = c.AddFeesFor(complexity) - return err -} - -func (c *dynamicCalculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { - outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.StakeOuts)) - copy(outs, tx.Outs) - copy(outs[len(tx.Outs):], tx.StakeOuts) - - complexity, err := c.meterTx(tx, outs, tx.Ins) - if err != nil { - return err - } - complexity[fee.Compute] += StakerLookupCost - - _, err = c.AddFeesFor(complexity) - return err -} - -func (c *dynamicCalculator) BaseTx(tx *txs.BaseTx) error { - complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) - if err != nil { - return err - } - - _, err = c.AddFeesFor(complexity) - return err -} - -func (c *dynamicCalculator) ImportTx(tx *txs.ImportTx) error { - ins := make([]*avax.TransferableInput, len(tx.Ins)+len(tx.ImportedInputs)) - copy(ins, tx.Ins) - copy(ins[len(tx.Ins):], tx.ImportedInputs) - - complexity, err := c.meterTx(tx, tx.Outs, ins) - if err != nil { - return err - } - - _, err = c.AddFeesFor(complexity) - return err -} - -func (c *dynamicCalculator) ExportTx(tx *txs.ExportTx) error { - outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.ExportedOutputs)) - copy(outs, tx.Outs) - copy(outs[len(tx.Outs):], tx.ExportedOutputs) - - complexity, err := c.meterTx(tx, outs, tx.Ins) - if err != nil { - return err - } - - _, err = c.AddFeesFor(complexity) - return err -} - -func (c *dynamicCalculator) meterTx( - uTx txs.UnsignedTx, - allOuts []*avax.TransferableOutput, - allIns []*avax.TransferableInput, -) (fee.Dimensions, error) { - var complexity fee.Dimensions - - uTxSize, err := txs.Codec.Size(txs.CodecVersion, uTx) - if err != nil { - return complexity, fmt.Errorf("couldn't calculate UnsignedTx marshal length: %w", err) - } - complexity[fee.Bandwidth] = uint64(uTxSize) - - // meter credentials, one by one. Then account for the extra bytes needed to - // serialize a slice of credentials (codec version bytes + slice size bytes) - for i, cred := range c.cred { - c, ok := cred.(*secp256k1fx.Credential) - if !ok { - return complexity, fmt.Errorf("don't know how to calculate complexity of %T", cred) - } - credDimensions, err := fee.MeterCredential(txs.Codec, txs.CodecVersion, len(c.Sigs)) - if err != nil { - return complexity, fmt.Errorf("failed adding credential %d: %w", i, err) - } - complexity, err = complexity.Add(credDimensions) - if err != nil { - return complexity, fmt.Errorf("failed adding credentials: %w", err) - } - } - complexity[fee.Bandwidth] += wrappers.IntLen // length of the credentials slice - complexity[fee.Bandwidth] += codec.VersionSize - - for _, in := range allIns { - inputDimensions, err := fee.MeterInput(txs.Codec, txs.CodecVersion, in) - if err != nil { - return complexity, fmt.Errorf("failed retrieving size of inputs: %w", err) - } - inputDimensions[fee.Bandwidth] = 0 // inputs bandwidth is already accounted for above, so we zero it - complexity, err = complexity.Add(inputDimensions) - if err != nil { - return complexity, fmt.Errorf("failed adding inputs: %w", err) - } - } - - for _, out := range allOuts { - outputDimensions, err := fee.MeterOutput(txs.Codec, txs.CodecVersion, out) - if err != nil { - return complexity, fmt.Errorf("failed retrieving size of outputs: %w", err) - } - outputDimensions[fee.Bandwidth] = 0 // outputs bandwidth is already accounted for above, so we zero it - complexity, err = complexity.Add(outputDimensions) - if err != nil { - return complexity, fmt.Errorf("failed adding outputs: %w", err) - } - } - - return complexity, nil -} diff --git a/vms/platformvm/txs/fee/static_calculator.go b/vms/platformvm/txs/fee/static_calculator.go index c4e029d5a149..7bfb5cf799a0 100644 --- a/vms/platformvm/txs/fee/static_calculator.go +++ b/vms/platformvm/txs/fee/static_calculator.go @@ -4,12 +4,9 @@ package fee import ( - "errors" "time" "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/vms/components/fee" - "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" ) @@ -17,8 +14,6 @@ import ( var ( _ Calculator = (*staticCalculator)(nil) _ txs.Visitor = (*staticCalculator)(nil) - - errComplexityNotPriced = errors.New("complexity not priced") ) func NewStaticCalculator( @@ -49,32 +44,6 @@ func (c *staticCalculator) CalculateFee(tx *txs.Tx) (uint64, error) { return c.fee, err } -func (c *staticCalculator) GetFee() uint64 { - return c.fee -} - -func (c *staticCalculator) ResetFee(newFee uint64) { - c.fee = newFee -} - -func (*staticCalculator) AddFeesFor(fee.Dimensions) (uint64, error) { - return 0, errComplexityNotPriced -} - -func (*staticCalculator) RemoveFeesFor(fee.Dimensions) (uint64, error) { - return 0, errComplexityNotPriced -} - -func (*staticCalculator) GetGasPrice() fee.GasPrice { return 0 } - -func (*staticCalculator) GetBlockGas() (fee.Gas, error) { return 0, nil } - -func (*staticCalculator) GetGasCap() fee.Gas { return 0 } - -func (*staticCalculator) setCredentials([]verify.Verifiable) {} - -func (*staticCalculator) IsEActive() bool { return false } - func (c *staticCalculator) AddValidatorTx(*txs.AddValidatorTx) error { c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee return nil From 66af837060879cf199c8d803bcb3813209278fb1 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jul 2024 11:51:24 -0400 Subject: [PATCH 061/100] tidy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 52c55810d0f9..eaedf707a300 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( github.com/gorilla/rpc v1.2.0 github.com/gorilla/websocket v1.4.2 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 + github.com/holiman/uint256 v1.2.4 github.com/huin/goupnp v1.3.0 github.com/jackpal/gateway v1.0.6 github.com/jackpal/go-nat-pmp v1.0.2 @@ -117,7 +118,6 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.2.4 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect From 7a8f88375406c4e46efcda1e1710a7771599f459 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jul 2024 11:53:28 -0400 Subject: [PATCH 062/100] nit --- vms/components/fee/gas.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/components/fee/gas.go b/vms/components/fee/gas.go index 743327088857..5d4644567dcd 100644 --- a/vms/components/fee/gas.go +++ b/vms/components/fee/gas.go @@ -76,7 +76,7 @@ func (g GasPrice) MulExp( output uint256.Int numeratorAccum uint256.Int - maxOutput uint256.Int // range is [0, MaxUint128] + maxOutput uint256.Int ) numerator.SetUint64(uint64(excess)) // range is [0, MaxUint64] denominator.SetUint64(uint64(excessConversionConstant)) // range is [0, MaxUint64] From b37440f0b6acfe9b48022a6a7c1d0811dc680831 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jul 2024 11:55:01 -0400 Subject: [PATCH 063/100] lint --- vms/components/fee/state.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/components/fee/state.go b/vms/components/fee/state.go index 0d454b2c7b8d..c8b3037f188d 100644 --- a/vms/components/fee/state.go +++ b/vms/components/fee/state.go @@ -43,7 +43,7 @@ func (s State) ConsumeGas(gas Gas) (State, error) { return State{ Capacity: Gas(newCapacity), Excess: math.MaxUint64, - }, nil + }, nil //nolint:nilerr // excess is capped at math.MaxUint64 } return State{ From 9914a19a84141f0946b42e868551eac7c776f85e Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jul 2024 11:55:28 -0400 Subject: [PATCH 064/100] fix nolint --- vms/components/fee/state.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vms/components/fee/state.go b/vms/components/fee/state.go index c8b3037f188d..622f233552e7 100644 --- a/vms/components/fee/state.go +++ b/vms/components/fee/state.go @@ -40,10 +40,11 @@ func (s State) ConsumeGas(gas Gas) (State, error) { newExcess, err := safemath.Add64(uint64(s.Excess), uint64(gas)) if err != nil { + //nolint:nilerr // excess is capped at math.MaxUint64 return State{ Capacity: Gas(newCapacity), Excess: math.MaxUint64, - }, nil //nolint:nilerr // excess is capped at math.MaxUint64 + }, nil } return State{ From c8b2895afb10c19d4e11325208663463ad5a4d79 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jul 2024 11:56:34 -0400 Subject: [PATCH 065/100] nit --- vms/components/fee/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/components/fee/config.go b/vms/components/fee/config.go index ab22958126d5..ca56f872b627 100644 --- a/vms/components/fee/config.go +++ b/vms/components/fee/config.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -// The fee package implements the fee logic specified in ACP-103: +// The fee package implements dynamic gas pricing specified in ACP-103: // https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/103-dynamic-fees package fee From 113c28cb5a58c6a63951b11a985d81a60fd23b27 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jul 2024 11:58:45 -0400 Subject: [PATCH 066/100] nit --- vms/components/fee/gas.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/components/fee/gas.go b/vms/components/fee/gas.go index 5d4644567dcd..1e5023945957 100644 --- a/vms/components/fee/gas.go +++ b/vms/components/fee/gas.go @@ -58,7 +58,7 @@ func (g Gas) SubPerSecond(gasPerSecond Gas, seconds uint64) Gas { // // This implementation is optimized with the knowledge that any value greater // than MaxUint64 gets returned as MaxUint64. This means that every intermediate -// value is guaranteed to be at most MaxUint192. So, we can safely use +// value is guaranteed to be at most MaxUint193. So, we can safely use // uint256.Int. // // This function does not perform any memory allocations. From 7dab6c850e305380a938f76681b6aed29939ab52 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jul 2024 17:56:41 -0400 Subject: [PATCH 067/100] wip --- .vscode/settings.json | 3 + vms/components/fee/dimensions.go | 8 +- vms/platformvm/txs/fee/calculator_test.go | 4 +- vms/platformvm/txs/fee/dynamic_calculator.go | 535 ++++++++++++++++++ .../txs/fee/dynamic_calculator_test.go | 262 +++++++++ 5 files changed, 806 insertions(+), 6 deletions(-) create mode 100644 vms/platformvm/txs/fee/dynamic_calculator.go create mode 100644 vms/platformvm/txs/fee/dynamic_calculator_test.go diff --git a/.vscode/settings.json b/.vscode/settings.json index 0abd38ef2982..44fc7c3d9475 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,4 +8,7 @@ ], }, "go.testTags": "test", + "cSpell.words": [ + "Stakeable" + ], } \ No newline at end of file diff --git a/vms/components/fee/dimensions.go b/vms/components/fee/dimensions.go index 21427af9821e..fab0d167ed86 100644 --- a/vms/components/fee/dimensions.go +++ b/vms/components/fee/dimensions.go @@ -6,10 +6,10 @@ package fee import "github.com/ava-labs/avalanchego/utils/math" const ( - Bandwidth Dimension = iota - DBRead - DBWrite // includes deletes - Compute + Bandwidth Dimension = iota // bytes + DBRead // num reads + DBWrite // num writes (includes deletes) + Compute // time NumDimensions = iota ) diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 454072e9df8d..fa5c4371add9 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -148,7 +148,7 @@ func TestTxFees(t *testing.T) { { name: "BaseTx pre EUpgrade", chainTime: preEUpgradeTime, - unsignedTx: baseTx, + unsignedTx: baseTxT, expected: feeTestsDefaultCfg.TxFee, }, { @@ -240,7 +240,7 @@ func addPermissionlessDelegatorTx(subnetID ids.ID) txs.UnsignedTx { } } -func baseTx() txs.UnsignedTx { +func baseTxT() txs.UnsignedTx { return &txs.BaseTx{} } diff --git a/vms/platformvm/txs/fee/dynamic_calculator.go b/vms/platformvm/txs/fee/dynamic_calculator.go new file mode 100644 index 000000000000..e275480cc326 --- /dev/null +++ b/vms/platformvm/txs/fee/dynamic_calculator.go @@ -0,0 +1,535 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "errors" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/wrappers" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/fee" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +const ( + intrinsicValidatorBandwidth = ids.NodeIDLen + // nodeID + wrappers.LongLen + // start + wrappers.LongLen + // end + wrappers.LongLen // weight + + intrinsicSubnetValidatorBandwidth = intrinsicValidatorBandwidth + // validator + ids.IDLen // subnetID + + intrinsicOutputBandwidth = ids.IDLen + // assetID + wrappers.IntLen // output typeID + + intrinsicStakeableLockedOutputBandwidth = wrappers.LongLen + // locktime + wrappers.IntLen // output typeID + + intrinsicSECP256k1FxOutputOwnersBandwidth = wrappers.LongLen + // locktime + wrappers.IntLen + // threshold + wrappers.IntLen // num addresses + + intrinsicSECP256k1FxOutputBandwidth = wrappers.LongLen + // amount + intrinsicSECP256k1FxOutputOwnersBandwidth + + intrinsicInputBandwidth = ids.IDLen + // txID + wrappers.IntLen + // output index + ids.IDLen + // assetID + wrappers.IntLen + // input typeID + wrappers.IntLen // credential typeID + + intrinsicStakeableLockedInputBandwidth = wrappers.LongLen + // locktime + wrappers.IntLen // input typeID + + intrinsicSECP256k1FxInputBandwidth = wrappers.LongLen + // amount + wrappers.IntLen + // num indices + wrappers.IntLen // num signatures + + intrinsicSECP256k1FxSignatureBandwidth = wrappers.IntLen + // signature index + secp256k1.SignatureLen // signature length +) + +var ( + _ txs.Visitor = (*dimensionsCalculator)(nil) + + IntrinsicAddPermissionlessValidatorTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + intrinsicValidatorBandwidth + // validator + ids.IDLen + // subnetID + wrappers.IntLen + // signer typeID + wrappers.IntLen + // num stake outs + wrappers.IntLen + // validator rewards typeID + wrappers.IntLen + // delegator rewards typeID + wrappers.IntLen, // delegation shares + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicAddPermissionlessDelegatorTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + intrinsicValidatorBandwidth + // validator + ids.IDLen + // subnetID + wrappers.IntLen + // signer typeID + wrappers.IntLen + // num stake outs + wrappers.IntLen, // delegator rewards typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicAddSubnetValidatorTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + intrinsicSubnetValidatorBandwidth + // subnetValidator + wrappers.IntLen, // subnetAuth typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicBaseTxComplexities = fee.Dimensions{ + fee.Bandwidth: wrappers.ShortLen + // codecID + wrappers.IntLen + // typeID + wrappers.IntLen + // networkID + ids.IDLen + // blockchainID + wrappers.IntLen + // number of outputs + wrappers.IntLen + // number of inputs + wrappers.IntLen + // length of memo + wrappers.IntLen, // number of credentials + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicCreateChainTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + ids.IDLen + // subnetID + wrappers.ShortLen + // chainName length + ids.IDLen + // vmID + wrappers.IntLen + // num fxIDs + wrappers.IntLen + // genesis length + wrappers.IntLen, // subnetAuth typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicCreateSubnetTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + wrappers.IntLen, // owner typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicExportTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + ids.IDLen + // destination chainID + wrappers.IntLen, // num exported outputs + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicImportTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + ids.IDLen + // source chainID + wrappers.IntLen, // num importing inputs + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicRemoveSubnetValidatorTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + ids.NodeIDLen + // nodeID + ids.IDLen + // subnetID + wrappers.IntLen, // subnetAuth typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicTransferSubnetOwnershipTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + ids.IDLen + // subnetID + wrappers.IntLen + // subnetAuth typeID + wrappers.IntLen, // owner typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + + errUnsupportedTx = errors.New("unsupported tx type") + errUnsupportedOutput = errors.New("unsupported output type") + errUnsupportedInput = errors.New("unsupported input type") +) + +func TxComplexity(tx txs.UnsignedTx) (fee.Dimensions, error) { + c := dimensionsCalculator{} + err := tx.Visit(&c) + return c.dimensions, err +} + +func OutputComplexity(out *avax.TransferableOutput) (fee.Dimensions, error) { + complexity := fee.Dimensions{ + fee.Bandwidth: intrinsicOutputBandwidth + intrinsicSECP256k1FxOutputBandwidth, + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, + } + + outIntf := out.Out + if stakeableOut, ok := outIntf.(*stakeable.LockOut); ok { + complexity[fee.Bandwidth] += intrinsicStakeableLockedOutputBandwidth + outIntf = stakeableOut.TransferableOut + } + + secp256k1Out, ok := outIntf.(*secp256k1fx.TransferOutput) + if !ok { + return fee.Dimensions{}, errUnsupportedOutput + } + + numAddresses := uint64(len(secp256k1Out.Addrs)) + // TODO: Overflow check + complexity[fee.Bandwidth] += numAddresses * ids.ShortIDLen // addresses + return complexity, nil +} + +// InputComplexity returns the complexity an input adds to a transaction. It +// includes the complexity that the corresponding credential will add. +func InputComplexity(in *avax.TransferableInput) (fee.Dimensions, error) { + complexity := fee.Dimensions{ + fee.Bandwidth: intrinsicInputBandwidth + intrinsicSECP256k1FxInputBandwidth, + fee.DBRead: 1, + fee.DBWrite: 1, + fee.Compute: 0, // TODO + } + + inIntf := in.In + if stakeableIn, ok := inIntf.(*stakeable.LockIn); ok { + complexity[fee.Bandwidth] += intrinsicStakeableLockedInputBandwidth + inIntf = stakeableIn.TransferableIn + } + + secp256k1In, ok := inIntf.(*secp256k1fx.TransferInput) + if !ok { + return fee.Dimensions{}, errUnsupportedInput + } + + numSignatures := uint64(len(secp256k1In.SigIndices)) + complexity[fee.Bandwidth] += numSignatures * intrinsicSECP256k1FxSignatureBandwidth // TODO: Overflow check + return complexity, nil +} + +// OwnerComplexity returns the complexity an owner adds to a transaction. +// It does not include the typeID of the owner. +func OwnerComplexity(_ fx.Owner) (fee.Dimensions, error) { + return fee.Dimensions{ + fee.Bandwidth: 0, // TODO + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, // TODO + }, nil +} + +// AuthComplexity returns the complexity an authorization adds to a transaction. +// It does not include the typeID of the authorization. +// It does includes the complexity that the corresponding credential will add. +func AuthComplexity(_ verify.Verifiable) (fee.Dimensions, error) { + return fee.Dimensions{ + fee.Bandwidth: 0, // TODO + fee.DBRead: 1, + fee.DBWrite: 0, + fee.Compute: 0, // TODO + }, nil +} + +// SignerComplexity returns the complexity a signer adds to a transaction. +// It does not include the typeID of the signer. +func SignerComplexity(_ signer.Signer) (fee.Dimensions, error) { + return fee.Dimensions{ + fee.Bandwidth: 0, // TODO + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, // TODO + }, nil +} + +type dimensionsCalculator struct { + // outputs: + dimensions fee.Dimensions +} + +func (*dimensionsCalculator) AddDelegatorTx(*txs.AddDelegatorTx) error { + return errUnsupportedTx +} + +func (*dimensionsCalculator) AddValidatorTx(*txs.AddValidatorTx) error { + return errUnsupportedTx +} + +func (*dimensionsCalculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + return errUnsupportedTx +} + +func (*dimensionsCalculator) RewardValidatorTx(*txs.RewardValidatorTx) error { + return errUnsupportedTx +} + +func (*dimensionsCalculator) TransformSubnetTx(*txs.TransformSubnetTx) error { + return errUnsupportedTx +} + +func (c *dimensionsCalculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { + complexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + signerComplexity, err := SignerComplexity(tx.Signer) + if err != nil { + return err + } + complexity, err = complexity.Add(signerComplexity) + if err != nil { + return err + } + for _, out := range tx.StakeOuts { + outputComplexity, err := OutputComplexity(out) + if err != nil { + return err + } + + complexity, err = complexity.Add(outputComplexity) + if err != nil { + return err + } + } + validatorOwnerComplexity, err := OwnerComplexity(tx.ValidatorRewardsOwner) + if err != nil { + return err + } + complexity, err = complexity.Add(validatorOwnerComplexity) + if err != nil { + return err + } + delegatorOwnerComplexity, err := OwnerComplexity(tx.DelegatorRewardsOwner) + if err != nil { + return err + } + complexity, err = complexity.Add(delegatorOwnerComplexity) + if err != nil { + return err + } + c.dimensions, err = complexity.Add(IntrinsicAddPermissionlessDelegatorTxComplexities) + return err +} + +func (c *dimensionsCalculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { + complexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + ownerComplexity, err := OwnerComplexity(tx.DelegationRewardsOwner) + if err != nil { + return err + } + complexity, err = complexity.Add(ownerComplexity) + if err != nil { + return err + } + for _, out := range tx.StakeOuts { + outputComplexity, err := OutputComplexity(out) + if err != nil { + return err + } + + complexity, err = complexity.Add(outputComplexity) + if err != nil { + return err + } + } + c.dimensions, err = complexity.Add(IntrinsicAddPermissionlessDelegatorTxComplexities) + return err +} + +func (c *dimensionsCalculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { + complexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + authComplexity, err := AuthComplexity(tx.SubnetAuth) + if err != nil { + return err + } + complexity, err = complexity.Add(authComplexity) + if err != nil { + return err + } + c.dimensions, err = complexity.Add(IntrinsicAddSubnetValidatorTxComplexities) + return err +} + +func (c *dimensionsCalculator) BaseTx(tx *txs.BaseTx) error { + complexity, err := baseTx(tx) + if err != nil { + return err + } + c.dimensions, err = complexity.Add(IntrinsicBaseTxComplexities) + return err +} + +func (c *dimensionsCalculator) CreateChainTx(tx *txs.CreateChainTx) error { + complexity := fee.Dimensions{ + // TODO: Overflow check + fee.Bandwidth: uint64(len(tx.ChainName) + len(tx.FxIDs)*ids.IDLen + len(tx.GenesisData)), + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + baseTxComplexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + complexity, err = complexity.Add(baseTxComplexity) + if err != nil { + return err + } + authComplexity, err := AuthComplexity(tx.SubnetAuth) + if err != nil { + return err + } + complexity, err = complexity.Add(authComplexity) + if err != nil { + return err + } + c.dimensions, err = complexity.Add(IntrinsicCreateChainTxComplexities) + return err +} + +func (c *dimensionsCalculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { + complexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + ownerComplexity, err := OwnerComplexity(tx.Owner) + if err != nil { + return err + } + complexity, err = complexity.Add(ownerComplexity) + if err != nil { + return err + } + c.dimensions, err = complexity.Add(IntrinsicCreateChainTxComplexities) + return err +} + +func (c *dimensionsCalculator) ExportTx(tx *txs.ExportTx) error { + complexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + for _, out := range tx.ExportedOutputs { + outputComplexity, err := OutputComplexity(out) + if err != nil { + return err + } + + complexity, err = complexity.Add(outputComplexity) + if err != nil { + return err + } + } + c.dimensions, err = complexity.Add(IntrinsicExportTxComplexities) + return err +} + +func (c *dimensionsCalculator) ImportTx(tx *txs.ImportTx) error { + complexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + for _, in := range tx.ImportedInputs { + inputComplexity, err := InputComplexity(in) + if err != nil { + return err + } + + complexity, err = complexity.Add(inputComplexity) + if err != nil { + return err + } + } + c.dimensions, err = complexity.Add(IntrinsicImportTxComplexities) + return err +} + +func (c *dimensionsCalculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { + complexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + authComplexity, err := AuthComplexity(tx.SubnetAuth) + if err != nil { + return err + } + complexity, err = complexity.Add(authComplexity) + if err != nil { + return err + } + c.dimensions, err = complexity.Add(IntrinsicRemoveSubnetValidatorTxComplexities) + return err +} + +func (c *dimensionsCalculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { + complexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + authComplexity, err := AuthComplexity(tx.SubnetAuth) + if err != nil { + return err + } + complexity, err = complexity.Add(authComplexity) + if err != nil { + return err + } + ownerComplexity, err := OwnerComplexity(tx.Owner) + if err != nil { + return err + } + complexity, err = complexity.Add(ownerComplexity) + if err != nil { + return err + } + c.dimensions, err = complexity.Add(IntrinsicTransferSubnetOwnershipTxComplexities) + return err +} + +func baseTx(tx *txs.BaseTx) (fee.Dimensions, error) { + var complexity fee.Dimensions + for _, out := range tx.Outs { + outputComplexity, err := OutputComplexity(out) + if err != nil { + return fee.Dimensions{}, err + } + + complexity, err = complexity.Add(outputComplexity) + if err != nil { + return fee.Dimensions{}, err + } + } + for _, in := range tx.Ins { + inputComplexity, err := InputComplexity(in) + if err != nil { + return fee.Dimensions{}, err + } + + complexity, err = complexity.Add(inputComplexity) + if err != nil { + return fee.Dimensions{}, err + } + } + complexity[fee.Bandwidth] += uint64(len(tx.Memo)) + return complexity, nil +} diff --git a/vms/platformvm/txs/fee/dynamic_calculator_test.go b/vms/platformvm/txs/fee/dynamic_calculator_test.go new file mode 100644 index 000000000000..61c35d3f463c --- /dev/null +++ b/vms/platformvm/txs/fee/dynamic_calculator_test.go @@ -0,0 +1,262 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/wrappers" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/fee" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +func TestOutputComplexity(t *testing.T) { + tests := []struct { + name string + out *avax.TransferableOutput + expected fee.Dimensions + expectedErr error + }{ + { + name: "any can spend", + out: &avax.TransferableOutput{ + Out: &secp256k1fx.TransferOutput{ + OutputOwners: secp256k1fx.OutputOwners{ + Addrs: make([]ids.ShortID, 0), + }, + }, + }, + expected: fee.Dimensions{ + fee.Bandwidth: 60, + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "one owner", + out: &avax.TransferableOutput{ + Out: &secp256k1fx.TransferOutput{ + OutputOwners: secp256k1fx.OutputOwners{ + Addrs: make([]ids.ShortID, 1), + }, + }, + }, + expected: fee.Dimensions{ + fee.Bandwidth: 80, + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "three owners", + out: &avax.TransferableOutput{ + Out: &secp256k1fx.TransferOutput{ + OutputOwners: secp256k1fx.OutputOwners{ + Addrs: make([]ids.ShortID, 3), + }, + }, + }, + expected: fee.Dimensions{ + fee.Bandwidth: 120, + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "locked stakeable", + out: &avax.TransferableOutput{ + Out: &stakeable.LockOut{ + TransferableOut: &secp256k1fx.TransferOutput{ + OutputOwners: secp256k1fx.OutputOwners{ + Addrs: make([]ids.ShortID, 3), + }, + }, + }, + }, + expected: fee.Dimensions{ + fee.Bandwidth: 132, + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "invalid output type", + out: &avax.TransferableOutput{ + Out: nil, + }, + expected: fee.Dimensions{ + fee.Bandwidth: 0, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + }, + expectedErr: errUnsupportedOutput, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + actual, err := OutputComplexity(test.out) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + + if err != nil { + return + } + + bytes, err := txs.Codec.Marshal(txs.CodecVersion, test.out) + require.NoError(err) + + numBytesWithoutCodecVersion := uint64(len(bytes) - wrappers.ShortLen) + require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) + }) + } +} + +func TestInputComplexity(t *testing.T) { + tests := []struct { + name string + in *avax.TransferableInput + cred verify.Verifiable + expected fee.Dimensions + expectedErr error + }{ + { + name: "any can spend", + in: &avax.TransferableInput{ + In: &secp256k1fx.TransferInput{ + Input: secp256k1fx.Input{ + SigIndices: make([]uint32, 0), + }, + }, + }, + cred: &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, 0), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 92, + fee.DBRead: 1, + fee.DBWrite: 1, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "one owner", + in: &avax.TransferableInput{ + In: &secp256k1fx.TransferInput{ + Input: secp256k1fx.Input{ + SigIndices: make([]uint32, 1), + }, + }, + }, + cred: &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, 1), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 161, + fee.DBRead: 1, + fee.DBWrite: 1, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "three owners", + in: &avax.TransferableInput{ + In: &secp256k1fx.TransferInput{ + Input: secp256k1fx.Input{ + SigIndices: make([]uint32, 3), + }, + }, + }, + cred: &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, 3), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 299, + fee.DBRead: 1, + fee.DBWrite: 1, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "locked stakeable", + in: &avax.TransferableInput{ + In: &stakeable.LockIn{ + TransferableIn: &secp256k1fx.TransferInput{ + Input: secp256k1fx.Input{ + SigIndices: make([]uint32, 3), + }, + }, + }, + }, + cred: &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, 3), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 311, + fee.DBRead: 1, + fee.DBWrite: 1, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "invalid input type", + in: &avax.TransferableInput{ + In: nil, + }, + cred: nil, + expected: fee.Dimensions{ + fee.Bandwidth: 0, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + }, + expectedErr: errUnsupportedInput, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + actual, err := InputComplexity(test.in) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + + if err != nil { + return + } + + inputBytes, err := txs.Codec.Marshal(txs.CodecVersion, test.in) + require.NoError(err) + + cred := test.cred + credentialBytes, err := txs.Codec.Marshal(txs.CodecVersion, &cred) + require.NoError(err) + + numBytesWithoutCodecVersion := uint64(len(inputBytes) + len(credentialBytes) - 2*wrappers.ShortLen) + require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) + }) + } +} From 473151876aff3252e716330bcd460309ebbd3f99 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jul 2024 18:04:42 -0400 Subject: [PATCH 068/100] nits --- vms/components/fee/dimensions.go | 38 +++---- vms/components/fee/dimensions_test.go | 156 +++++++++++++++++++------- 2 files changed, 132 insertions(+), 62 deletions(-) diff --git a/vms/components/fee/dimensions.go b/vms/components/fee/dimensions.go index 21427af9821e..968af5f5a6ea 100644 --- a/vms/components/fee/dimensions.go +++ b/vms/components/fee/dimensions.go @@ -19,32 +19,30 @@ type ( Dimensions [NumDimensions]uint64 ) -func (d Dimensions) Add(o Dimensions) (Dimensions, error) { - var ( - res Dimensions - err error - ) - for i := range d { - res[i], err = math.Add64(d[i], o[i]) - if err != nil { - return res, err +func (d Dimensions) Add(os ...Dimensions) (Dimensions, error) { + var err error + for _, o := range os { + for i := range o { + d[i], err = math.Add64(d[i], o[i]) + if err != nil { + return d, err + } } } - return res, nil + return d, nil } -func (d Dimensions) Sub(o Dimensions) (Dimensions, error) { - var ( - res Dimensions - err error - ) - for i := range d { - res[i], err = math.Sub(d[i], o[i]) - if err != nil { - return res, err +func (d Dimensions) Sub(os ...Dimensions) (Dimensions, error) { + var err error + for _, o := range os { + for i := range o { + d[i], err = math.Sub(d[i], o[i]) + if err != nil { + return d, err + } } } - return res, nil + return d, nil } func (d Dimensions) ToGas(weights Dimensions) (Gas, error) { diff --git a/vms/components/fee/dimensions_test.go b/vms/components/fee/dimensions_test.go index 22579b696d46..6e64aa0050ff 100644 --- a/vms/components/fee/dimensions_test.go +++ b/vms/components/fee/dimensions_test.go @@ -16,23 +16,25 @@ func Test_Dimensions_Add(t *testing.T) { tests := []struct { name string lhs Dimensions - rhs Dimensions + rhs []Dimensions expected Dimensions expectedErr error }{ { - name: "no error", + name: "no error single entry", lhs: Dimensions{ Bandwidth: 1, DBRead: 2, DBWrite: 3, Compute: 4, }, - rhs: Dimensions{ - Bandwidth: 10, - DBRead: 20, - DBWrite: 30, - Compute: 40, + rhs: []Dimensions{ + { + Bandwidth: 10, + DBRead: 20, + DBWrite: 30, + Compute: 40, + }, }, expected: Dimensions{ Bandwidth: 11, @@ -42,6 +44,36 @@ func Test_Dimensions_Add(t *testing.T) { }, expectedErr: nil, }, + { + name: "no error multiple entries", + lhs: Dimensions{ + Bandwidth: 1, + DBRead: 2, + DBWrite: 3, + Compute: 4, + }, + rhs: []Dimensions{ + { + Bandwidth: 10, + DBRead: 20, + DBWrite: 30, + Compute: 40, + }, + { + Bandwidth: 100, + DBRead: 200, + DBWrite: 300, + Compute: 400, + }, + }, + expected: Dimensions{ + Bandwidth: 111, + DBRead: 222, + DBWrite: 333, + Compute: 444, + }, + expectedErr: nil, + }, { name: "bandwidth overflow", lhs: Dimensions{ @@ -50,17 +82,19 @@ func Test_Dimensions_Add(t *testing.T) { DBWrite: 3, Compute: 4, }, - rhs: Dimensions{ - Bandwidth: 10, - DBRead: 20, - DBWrite: 30, - Compute: 40, + rhs: []Dimensions{ + { + Bandwidth: 10, + DBRead: 20, + DBWrite: 30, + Compute: 40, + }, }, expected: Dimensions{ Bandwidth: 0, - DBRead: 0, - DBWrite: 0, - Compute: 0, + DBRead: 2, + DBWrite: 3, + Compute: 4, }, expectedErr: safemath.ErrOverflow, }, @@ -72,11 +106,13 @@ func Test_Dimensions_Add(t *testing.T) { DBWrite: 3, Compute: math.MaxUint64, }, - rhs: Dimensions{ - Bandwidth: 10, - DBRead: 20, - DBWrite: 30, - Compute: 40, + rhs: []Dimensions{ + { + Bandwidth: 10, + DBRead: 20, + DBWrite: 30, + Compute: 40, + }, }, expected: Dimensions{ Bandwidth: 11, @@ -91,7 +127,7 @@ func Test_Dimensions_Add(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - actual, err := test.lhs.Add(test.rhs) + actual, err := test.lhs.Add(test.rhs...) require.ErrorIs(err, test.expectedErr) require.Equal(test.expected, actual) }) @@ -102,23 +138,25 @@ func Test_Dimensions_Sub(t *testing.T) { tests := []struct { name string lhs Dimensions - rhs Dimensions + rhs []Dimensions expected Dimensions expectedErr error }{ { - name: "no error", + name: "no error single entry", lhs: Dimensions{ Bandwidth: 11, DBRead: 22, DBWrite: 33, Compute: 44, }, - rhs: Dimensions{ - Bandwidth: 1, - DBRead: 2, - DBWrite: 3, - Compute: 4, + rhs: []Dimensions{ + { + Bandwidth: 1, + DBRead: 2, + DBWrite: 3, + Compute: 4, + }, }, expected: Dimensions{ Bandwidth: 10, @@ -128,6 +166,36 @@ func Test_Dimensions_Sub(t *testing.T) { }, expectedErr: nil, }, + { + name: "no error multiple entries", + lhs: Dimensions{ + Bandwidth: 11, + DBRead: 22, + DBWrite: 33, + Compute: 44, + }, + rhs: []Dimensions{ + { + Bandwidth: 1, + DBRead: 2, + DBWrite: 3, + Compute: 4, + }, + { + Bandwidth: 5, + DBRead: 5, + DBWrite: 5, + Compute: 5, + }, + }, + expected: Dimensions{ + Bandwidth: 5, + DBRead: 15, + DBWrite: 25, + Compute: 35, + }, + expectedErr: nil, + }, { name: "bandwidth underflow", lhs: Dimensions{ @@ -136,17 +204,19 @@ func Test_Dimensions_Sub(t *testing.T) { DBWrite: 33, Compute: 44, }, - rhs: Dimensions{ - Bandwidth: math.MaxUint64, - DBRead: 2, - DBWrite: 3, - Compute: 4, + rhs: []Dimensions{ + { + Bandwidth: math.MaxUint64, + DBRead: 2, + DBWrite: 3, + Compute: 4, + }, }, expected: Dimensions{ Bandwidth: 0, - DBRead: 0, - DBWrite: 0, - Compute: 0, + DBRead: 22, + DBWrite: 33, + Compute: 44, }, expectedErr: safemath.ErrUnderflow, }, @@ -158,11 +228,13 @@ func Test_Dimensions_Sub(t *testing.T) { DBWrite: 33, Compute: 44, }, - rhs: Dimensions{ - Bandwidth: 1, - DBRead: 2, - DBWrite: 3, - Compute: math.MaxUint64, + rhs: []Dimensions{ + { + Bandwidth: 1, + DBRead: 2, + DBWrite: 3, + Compute: math.MaxUint64, + }, }, expected: Dimensions{ Bandwidth: 10, @@ -177,7 +249,7 @@ func Test_Dimensions_Sub(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - actual, err := test.lhs.Sub(test.rhs) + actual, err := test.lhs.Sub(test.rhs...) require.ErrorIs(err, test.expectedErr) require.Equal(test.expected, actual) }) From 666b7a742fdb99d6b185d185ed0fd2937b78e00a Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 09:16:45 -0400 Subject: [PATCH 069/100] wip --- .../txs/fee/complexity_calculator.go | 521 ++++++++++++++++++ .../txs/fee/complexity_calculator_test.go | 262 +++++++++ 2 files changed, 783 insertions(+) create mode 100644 vms/platformvm/txs/fee/complexity_calculator.go create mode 100644 vms/platformvm/txs/fee/complexity_calculator_test.go diff --git a/vms/platformvm/txs/fee/complexity_calculator.go b/vms/platformvm/txs/fee/complexity_calculator.go new file mode 100644 index 000000000000..995d02814dc6 --- /dev/null +++ b/vms/platformvm/txs/fee/complexity_calculator.go @@ -0,0 +1,521 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "errors" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/wrappers" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/fee" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +const ( + intrinsicValidatorBandwidth = ids.NodeIDLen + // nodeID + wrappers.LongLen + // start + wrappers.LongLen + // end + wrappers.LongLen // weight + + intrinsicSubnetValidatorBandwidth = intrinsicValidatorBandwidth + // validator + ids.IDLen // subnetID + + intrinsicOutputBandwidth = ids.IDLen + // assetID + wrappers.IntLen // output typeID + + intrinsicStakeableLockedOutputBandwidth = wrappers.LongLen + // locktime + wrappers.IntLen // output typeID + + intrinsicSECP256k1FxOutputOwnersBandwidth = wrappers.LongLen + // locktime + wrappers.IntLen + // threshold + wrappers.IntLen // num addresses + + intrinsicSECP256k1FxOutputBandwidth = wrappers.LongLen + // amount + intrinsicSECP256k1FxOutputOwnersBandwidth + + intrinsicInputBandwidth = ids.IDLen + // txID + wrappers.IntLen + // output index + ids.IDLen + // assetID + wrappers.IntLen + // input typeID + wrappers.IntLen // credential typeID + + intrinsicStakeableLockedInputBandwidth = wrappers.LongLen + // locktime + wrappers.IntLen // input typeID + + intrinsicSECP256k1FxInputBandwidth = wrappers.LongLen + // amount + wrappers.IntLen + // num indices + wrappers.IntLen // num signatures + + intrinsicSECP256k1FxSignatureBandwidth = wrappers.IntLen + // signature index + secp256k1.SignatureLen // signature length +) + +var ( + _ txs.Visitor = (*complexityCalculator)(nil) + + IntrinsicAddPermissionlessValidatorTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + intrinsicValidatorBandwidth + // validator + ids.IDLen + // subnetID + wrappers.IntLen + // signer typeID + wrappers.IntLen + // num stake outs + wrappers.IntLen + // validator rewards typeID + wrappers.IntLen + // delegator rewards typeID + wrappers.IntLen, // delegation shares + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicAddPermissionlessDelegatorTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + intrinsicValidatorBandwidth + // validator + ids.IDLen + // subnetID + wrappers.IntLen + // signer typeID + wrappers.IntLen + // num stake outs + wrappers.IntLen, // delegator rewards typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicAddSubnetValidatorTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + intrinsicSubnetValidatorBandwidth + // subnetValidator + wrappers.IntLen, // subnetAuth typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicBaseTxComplexities = fee.Dimensions{ + fee.Bandwidth: wrappers.ShortLen + // codecID + wrappers.IntLen + // typeID + wrappers.IntLen + // networkID + ids.IDLen + // blockchainID + wrappers.IntLen + // number of outputs + wrappers.IntLen + // number of inputs + wrappers.IntLen + // length of memo + wrappers.IntLen, // number of credentials + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicCreateChainTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + ids.IDLen + // subnetID + wrappers.ShortLen + // chainName length + ids.IDLen + // vmID + wrappers.IntLen + // num fxIDs + wrappers.IntLen + // genesis length + wrappers.IntLen, // subnetAuth typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicCreateSubnetTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + wrappers.IntLen, // owner typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicExportTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + ids.IDLen + // destination chainID + wrappers.IntLen, // num exported outputs + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicImportTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + ids.IDLen + // source chainID + wrappers.IntLen, // num importing inputs + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicRemoveSubnetValidatorTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + ids.NodeIDLen + // nodeID + ids.IDLen + // subnetID + wrappers.IntLen, // subnetAuth typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + IntrinsicTransferSubnetOwnershipTxComplexities = fee.Dimensions{ + fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + + ids.IDLen + // subnetID + wrappers.IntLen + // subnetAuth typeID + wrappers.IntLen, // owner typeID + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + + errUnsupportedTx = errors.New("unsupported tx type") + errUnsupportedOutput = errors.New("unsupported output type") + errUnsupportedInput = errors.New("unsupported input type") +) + +func TxComplexity(tx txs.UnsignedTx) (fee.Dimensions, error) { + c := complexityCalculator{} + err := tx.Visit(&c) + return c.complexity, err +} + +func OutputComplexity(out *avax.TransferableOutput) (fee.Dimensions, error) { + complexity := fee.Dimensions{ + fee.Bandwidth: intrinsicOutputBandwidth + intrinsicSECP256k1FxOutputBandwidth, + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, + } + + outIntf := out.Out + if stakeableOut, ok := outIntf.(*stakeable.LockOut); ok { + complexity[fee.Bandwidth] += intrinsicStakeableLockedOutputBandwidth + outIntf = stakeableOut.TransferableOut + } + + secp256k1Out, ok := outIntf.(*secp256k1fx.TransferOutput) + if !ok { + return fee.Dimensions{}, errUnsupportedOutput + } + + numAddresses := uint64(len(secp256k1Out.Addrs)) + // TODO: Overflow check + complexity[fee.Bandwidth] += numAddresses * ids.ShortIDLen // addresses + return complexity, nil +} + +// InputComplexity returns the complexity an input adds to a transaction. It +// includes the complexity that the corresponding credential will add. +func InputComplexity(in *avax.TransferableInput) (fee.Dimensions, error) { + complexity := fee.Dimensions{ + fee.Bandwidth: intrinsicInputBandwidth + intrinsicSECP256k1FxInputBandwidth, + fee.DBRead: 1, + fee.DBWrite: 1, + fee.Compute: 0, // TODO + } + + inIntf := in.In + if stakeableIn, ok := inIntf.(*stakeable.LockIn); ok { + complexity[fee.Bandwidth] += intrinsicStakeableLockedInputBandwidth + inIntf = stakeableIn.TransferableIn + } + + secp256k1In, ok := inIntf.(*secp256k1fx.TransferInput) + if !ok { + return fee.Dimensions{}, errUnsupportedInput + } + + numSignatures := uint64(len(secp256k1In.SigIndices)) + complexity[fee.Bandwidth] += numSignatures * intrinsicSECP256k1FxSignatureBandwidth // TODO: Overflow check + return complexity, nil +} + +// OwnerComplexity returns the complexity an owner adds to a transaction. +// It does not include the typeID of the owner. +func OwnerComplexity(_ fx.Owner) (fee.Dimensions, error) { + return fee.Dimensions{ + fee.Bandwidth: 0, // TODO + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, // TODO + }, nil +} + +// AuthComplexity returns the complexity an authorization adds to a transaction. +// It does not include the typeID of the authorization. +// It does includes the complexity that the corresponding credential will add. +func AuthComplexity(_ verify.Verifiable) (fee.Dimensions, error) { + return fee.Dimensions{ + fee.Bandwidth: 0, // TODO + fee.DBRead: 1, + fee.DBWrite: 0, + fee.Compute: 0, // TODO + }, nil +} + +// SignerComplexity returns the complexity a signer adds to a transaction. +// It does not include the typeID of the signer. +func SignerComplexity(_ signer.Signer) (fee.Dimensions, error) { + return fee.Dimensions{ + fee.Bandwidth: 0, // TODO + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, // TODO + }, nil +} + +type complexityCalculator struct { + // outputs: + complexity fee.Dimensions +} + +func (*complexityCalculator) AddDelegatorTx(*txs.AddDelegatorTx) error { + return errUnsupportedTx +} + +func (*complexityCalculator) AddValidatorTx(*txs.AddValidatorTx) error { + return errUnsupportedTx +} + +func (*complexityCalculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + return errUnsupportedTx +} + +func (*complexityCalculator) RewardValidatorTx(*txs.RewardValidatorTx) error { + return errUnsupportedTx +} + +func (*complexityCalculator) TransformSubnetTx(*txs.TransformSubnetTx) error { + return errUnsupportedTx +} + +func (c *complexityCalculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { + baseTxComplexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + signerComplexity, err := SignerComplexity(tx.Signer) + if err != nil { + return err + } + outputsComplexity, err := outputsComplexity(tx.StakeOuts) + if err != nil { + return err + } + validatorOwnerComplexity, err := OwnerComplexity(tx.ValidatorRewardsOwner) + if err != nil { + return err + } + delegatorOwnerComplexity, err := OwnerComplexity(tx.DelegatorRewardsOwner) + if err != nil { + return err + } + c.complexity, err = IntrinsicAddPermissionlessValidatorTxComplexities.Add( + baseTxComplexity, + signerComplexity, + outputsComplexity, + validatorOwnerComplexity, + delegatorOwnerComplexity, + ) + return err +} + +func (c *complexityCalculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { + baseTxComplexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + ownerComplexity, err := OwnerComplexity(tx.DelegationRewardsOwner) + if err != nil { + return err + } + outputsComplexity, err := outputsComplexity(tx.StakeOuts) + if err != nil { + return err + } + c.complexity, err = IntrinsicAddPermissionlessDelegatorTxComplexities.Add( + baseTxComplexity, + ownerComplexity, + outputsComplexity, + ) + return err +} + +func (c *complexityCalculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { + baseTxComplexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + authComplexity, err := AuthComplexity(tx.SubnetAuth) + if err != nil { + return err + } + c.complexity, err = IntrinsicAddSubnetValidatorTxComplexities.Add( + baseTxComplexity, + authComplexity, + ) + return err +} + +func (c *complexityCalculator) BaseTx(tx *txs.BaseTx) error { + baseTxComplexity, err := baseTx(tx) + if err != nil { + return err + } + c.complexity, err = IntrinsicBaseTxComplexities.Add(baseTxComplexity) + return err +} + +func (c *complexityCalculator) CreateChainTx(tx *txs.CreateChainTx) error { + dynamicComplexity := fee.Dimensions{ + // TODO: Overflow check + fee.Bandwidth: uint64(len(tx.ChainName) + len(tx.FxIDs)*ids.IDLen + len(tx.GenesisData)), + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + } + baseTxComplexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + authComplexity, err := AuthComplexity(tx.SubnetAuth) + if err != nil { + return err + } + c.complexity, err = IntrinsicCreateChainTxComplexities.Add( + dynamicComplexity, + baseTxComplexity, + authComplexity, + ) + return err +} + +func (c *complexityCalculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { + baseTxComplexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + ownerComplexity, err := OwnerComplexity(tx.Owner) + if err != nil { + return err + } + c.complexity, err = IntrinsicCreateSubnetTxComplexities.Add( + baseTxComplexity, + ownerComplexity, + ) + return err +} + +func (c *complexityCalculator) ExportTx(tx *txs.ExportTx) error { + baseTxComplexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + outputsComplexity, err := outputsComplexity(tx.ExportedOutputs) + if err != nil { + return err + } + c.complexity, err = IntrinsicExportTxComplexities.Add( + baseTxComplexity, + outputsComplexity, + ) + return err +} + +func (c *complexityCalculator) ImportTx(tx *txs.ImportTx) error { + baseTxComplexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + inputsComplexity, err := inputsComplexity(tx.ImportedInputs) + if err != nil { + return err + } + c.complexity, err = IntrinsicImportTxComplexities.Add( + baseTxComplexity, + inputsComplexity, + ) + return err +} + +func (c *complexityCalculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { + baseTxComplexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + authComplexity, err := AuthComplexity(tx.SubnetAuth) + if err != nil { + return err + } + c.complexity, err = IntrinsicRemoveSubnetValidatorTxComplexities.Add( + baseTxComplexity, + authComplexity, + ) + return err +} + +func (c *complexityCalculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { + baseTxComplexity, err := baseTx(&tx.BaseTx) + if err != nil { + return err + } + authComplexity, err := AuthComplexity(tx.SubnetAuth) + if err != nil { + return err + } + ownerComplexity, err := OwnerComplexity(tx.Owner) + if err != nil { + return err + } + c.complexity, err = IntrinsicTransferSubnetOwnershipTxComplexities.Add( + baseTxComplexity, + authComplexity, + ownerComplexity, + ) + return err +} + +func baseTx(tx *txs.BaseTx) (fee.Dimensions, error) { + outputsComplexity, err := outputsComplexity(tx.Outs) + if err != nil { + return fee.Dimensions{}, err + } + inputsComplexity, err := inputsComplexity(tx.Ins) + if err != nil { + return fee.Dimensions{}, err + } + complexity, err := outputsComplexity.Add(inputsComplexity) + if err != nil { + return fee.Dimensions{}, err + } + complexity[fee.Bandwidth], err = math.Add( + complexity[fee.Bandwidth], + uint64(len(tx.Memo)), + ) + return complexity, err +} + +func outputsComplexity(outs []*avax.TransferableOutput) (fee.Dimensions, error) { + var complexity fee.Dimensions + for _, out := range outs { + outputComplexity, err := OutputComplexity(out) + if err != nil { + return fee.Dimensions{}, err + } + + complexity, err = complexity.Add(outputComplexity) + if err != nil { + return fee.Dimensions{}, err + } + } + return complexity, nil +} + +func inputsComplexity(ins []*avax.TransferableInput) (fee.Dimensions, error) { + var complexity fee.Dimensions + for _, in := range ins { + inputComplexity, err := InputComplexity(in) + if err != nil { + return fee.Dimensions{}, err + } + + complexity, err = complexity.Add(inputComplexity) + if err != nil { + return fee.Dimensions{}, err + } + } + return complexity, nil +} diff --git a/vms/platformvm/txs/fee/complexity_calculator_test.go b/vms/platformvm/txs/fee/complexity_calculator_test.go new file mode 100644 index 000000000000..61c35d3f463c --- /dev/null +++ b/vms/platformvm/txs/fee/complexity_calculator_test.go @@ -0,0 +1,262 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/wrappers" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/fee" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +func TestOutputComplexity(t *testing.T) { + tests := []struct { + name string + out *avax.TransferableOutput + expected fee.Dimensions + expectedErr error + }{ + { + name: "any can spend", + out: &avax.TransferableOutput{ + Out: &secp256k1fx.TransferOutput{ + OutputOwners: secp256k1fx.OutputOwners{ + Addrs: make([]ids.ShortID, 0), + }, + }, + }, + expected: fee.Dimensions{ + fee.Bandwidth: 60, + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "one owner", + out: &avax.TransferableOutput{ + Out: &secp256k1fx.TransferOutput{ + OutputOwners: secp256k1fx.OutputOwners{ + Addrs: make([]ids.ShortID, 1), + }, + }, + }, + expected: fee.Dimensions{ + fee.Bandwidth: 80, + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "three owners", + out: &avax.TransferableOutput{ + Out: &secp256k1fx.TransferOutput{ + OutputOwners: secp256k1fx.OutputOwners{ + Addrs: make([]ids.ShortID, 3), + }, + }, + }, + expected: fee.Dimensions{ + fee.Bandwidth: 120, + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "locked stakeable", + out: &avax.TransferableOutput{ + Out: &stakeable.LockOut{ + TransferableOut: &secp256k1fx.TransferOutput{ + OutputOwners: secp256k1fx.OutputOwners{ + Addrs: make([]ids.ShortID, 3), + }, + }, + }, + }, + expected: fee.Dimensions{ + fee.Bandwidth: 132, + fee.DBRead: 0, + fee.DBWrite: 1, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "invalid output type", + out: &avax.TransferableOutput{ + Out: nil, + }, + expected: fee.Dimensions{ + fee.Bandwidth: 0, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + }, + expectedErr: errUnsupportedOutput, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + actual, err := OutputComplexity(test.out) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + + if err != nil { + return + } + + bytes, err := txs.Codec.Marshal(txs.CodecVersion, test.out) + require.NoError(err) + + numBytesWithoutCodecVersion := uint64(len(bytes) - wrappers.ShortLen) + require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) + }) + } +} + +func TestInputComplexity(t *testing.T) { + tests := []struct { + name string + in *avax.TransferableInput + cred verify.Verifiable + expected fee.Dimensions + expectedErr error + }{ + { + name: "any can spend", + in: &avax.TransferableInput{ + In: &secp256k1fx.TransferInput{ + Input: secp256k1fx.Input{ + SigIndices: make([]uint32, 0), + }, + }, + }, + cred: &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, 0), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 92, + fee.DBRead: 1, + fee.DBWrite: 1, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "one owner", + in: &avax.TransferableInput{ + In: &secp256k1fx.TransferInput{ + Input: secp256k1fx.Input{ + SigIndices: make([]uint32, 1), + }, + }, + }, + cred: &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, 1), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 161, + fee.DBRead: 1, + fee.DBWrite: 1, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "three owners", + in: &avax.TransferableInput{ + In: &secp256k1fx.TransferInput{ + Input: secp256k1fx.Input{ + SigIndices: make([]uint32, 3), + }, + }, + }, + cred: &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, 3), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 299, + fee.DBRead: 1, + fee.DBWrite: 1, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "locked stakeable", + in: &avax.TransferableInput{ + In: &stakeable.LockIn{ + TransferableIn: &secp256k1fx.TransferInput{ + Input: secp256k1fx.Input{ + SigIndices: make([]uint32, 3), + }, + }, + }, + }, + cred: &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, 3), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 311, + fee.DBRead: 1, + fee.DBWrite: 1, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "invalid input type", + in: &avax.TransferableInput{ + In: nil, + }, + cred: nil, + expected: fee.Dimensions{ + fee.Bandwidth: 0, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + }, + expectedErr: errUnsupportedInput, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + actual, err := InputComplexity(test.in) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + + if err != nil { + return + } + + inputBytes, err := txs.Codec.Marshal(txs.CodecVersion, test.in) + require.NoError(err) + + cred := test.cred + credentialBytes, err := txs.Codec.Marshal(txs.CodecVersion, &cred) + require.NoError(err) + + numBytesWithoutCodecVersion := uint64(len(inputBytes) + len(credentialBytes) - 2*wrappers.ShortLen) + require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) + }) + } +} From 0e1b55151af6e47a1d02520bb2fe35b193ce6d97 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 09:25:26 -0400 Subject: [PATCH 070/100] Make math.Add64 and math.Mul64 generic --- genesis/config.go | 4 +- .../snowman/bootstrapper/majority.go | 4 +- .../consensus/snowman/bootstrapper/sampler.go | 2 +- snow/engine/avalanche/state/serializer.go | 2 +- snow/engine/snowman/syncer/state_syncer.go | 2 +- snow/engine/snowman/transitive.go | 4 +- snow/networking/benchlist/benchlist.go | 2 +- snow/validators/set.go | 4 +- utils/math/safe_math.go | 34 ++++++++------- utils/math/safe_math_test.go | 41 ++++++++++++------- utils/sampler/weighted_array.go | 2 +- utils/sampler/weighted_benchmark_test.go | 2 +- utils/sampler/weighted_best.go | 2 +- utils/sampler/weighted_heap.go | 2 +- utils/sampler/weighted_linear.go | 2 +- utils/sampler/weighted_uniform.go | 2 +- .../weighted_without_replacement_generic.go | 2 +- vms/avm/service.go | 12 +++--- vms/avm/utxo/spender.go | 4 +- vms/avm/wallet_service.go | 4 +- vms/components/avax/flow_checker.go | 2 +- vms/components/avax/utxo_fetching.go | 2 +- vms/example/xsvm/state/storage.go | 4 +- vms/platformvm/api/static_service.go | 2 +- vms/platformvm/reward/calculator.go | 2 +- vms/platformvm/service.go | 16 ++++---- vms/platformvm/state/state.go | 6 +-- vms/platformvm/txs/add_delegator_tx.go | 2 +- .../txs/add_permissionless_delegator_tx.go | 2 +- .../txs/add_permissionless_validator_tx.go | 2 +- vms/platformvm/txs/add_validator_tx.go | 2 +- .../txs/executor/staker_tx_verification.go | 4 +- .../staker_tx_verification_helpers.go | 6 +-- vms/platformvm/utxo/verifier.go | 8 ++-- vms/platformvm/warp/validator.go | 4 +- vms/proposervm/proposer/windower.go | 2 +- vms/secp256k1fx/input.go | 2 +- wallet/chain/c/backend.go | 2 +- wallet/chain/c/builder.go | 10 ++--- wallet/chain/p/builder/builder.go | 8 ++-- wallet/chain/x/builder/builder.go | 8 ++-- 41 files changed, 123 insertions(+), 106 deletions(-) diff --git a/genesis/config.go b/genesis/config.go index f09c5df07a89..de7d88f2f693 100644 --- a/genesis/config.go +++ b/genesis/config.go @@ -143,12 +143,12 @@ func (c Config) Unparse() (UnparsedConfig, error) { func (c *Config) InitialSupply() (uint64, error) { initialSupply := uint64(0) for _, allocation := range c.Allocations { - newInitialSupply, err := math.Add64(initialSupply, allocation.InitialAmount) + newInitialSupply, err := math.Add(initialSupply, allocation.InitialAmount) if err != nil { return 0, err } for _, unlock := range allocation.UnlockSchedule { - newInitialSupply, err = math.Add64(newInitialSupply, unlock.Amount) + newInitialSupply, err = math.Add(newInitialSupply, unlock.Amount) if err != nil { return 0, err } diff --git a/snow/consensus/snowman/bootstrapper/majority.go b/snow/consensus/snowman/bootstrapper/majority.go index 261507887a8d..01195dd5a1eb 100644 --- a/snow/consensus/snowman/bootstrapper/majority.go +++ b/snow/consensus/snowman/bootstrapper/majority.go @@ -68,7 +68,7 @@ func (m *Majority) RecordOpinion(_ context.Context, nodeID ids.NodeID, blkIDs se weight := m.nodeWeights[nodeID] for blkID := range blkIDs { - newWeight, err := math.Add64(m.received[blkID], weight) + newWeight, err := math.Add(m.received[blkID], weight) if err != nil { return err } @@ -84,7 +84,7 @@ func (m *Majority) RecordOpinion(_ context.Context, nodeID ids.NodeID, blkIDs se err error ) for _, weight := range m.nodeWeights { - totalWeight, err = math.Add64(totalWeight, weight) + totalWeight, err = math.Add(totalWeight, weight) if err != nil { return err } diff --git a/snow/consensus/snowman/bootstrapper/sampler.go b/snow/consensus/snowman/bootstrapper/sampler.go index 56b27d3076ff..f53958797077 100644 --- a/snow/consensus/snowman/bootstrapper/sampler.go +++ b/snow/consensus/snowman/bootstrapper/sampler.go @@ -27,7 +27,7 @@ func Sample[T comparable](elements map[T]uint64, maxSize int) (set.Set[T], error for key, weight := range elements { keys[i] = key weights[i] = weight - totalWeight, err = math.Add64(totalWeight, weight) + totalWeight, err = math.Add(totalWeight, weight) if err != nil { return nil, err } diff --git a/snow/engine/avalanche/state/serializer.go b/snow/engine/avalanche/state/serializer.go index be8cabc6e140..d88fa79ae240 100644 --- a/snow/engine/avalanche/state/serializer.go +++ b/snow/engine/avalanche/state/serializer.go @@ -86,7 +86,7 @@ func (s *Serializer) BuildStopVtx( return nil, err } parentHeight := parent.v.vtx.Height() - childHeight, err := math.Add64(parentHeight, 1) + childHeight, err := math.Add(parentHeight, 1) if err != nil { return nil, err } diff --git a/snow/engine/snowman/syncer/state_syncer.go b/snow/engine/snowman/syncer/state_syncer.go index bc549a0ce93a..2fea946f3106 100644 --- a/snow/engine/snowman/syncer/state_syncer.go +++ b/snow/engine/snowman/syncer/state_syncer.go @@ -310,7 +310,7 @@ func (ss *stateSyncer) AcceptedStateSummary(ctx context.Context, nodeID ids.Node continue } - newWeight, err := safemath.Add64(nodeWeight, ws.weight) + newWeight, err := safemath.Add(nodeWeight, ws.weight) if err != nil { ss.Ctx.Log.Error("failed to calculate new summary weight", zap.Stringer("nodeID", nodeID), diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index 0b23fa506f5d..4c0969616f05 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -179,7 +179,7 @@ func (t *Transitive) Gossip(ctx context.Context) error { return nil } - nextHeightToAccept, err := math.Add64(lastAcceptedHeight, 1) + nextHeightToAccept, err := math.Add(lastAcceptedHeight, 1) if err != nil { t.Ctx.Log.Error("skipping block gossip", zap.String("reason", "block height overflow"), @@ -886,7 +886,7 @@ func (t *Transitive) sendQuery( } _, lastAcceptedHeight := t.Consensus.LastAccepted() - nextHeightToAccept, err := math.Add64(lastAcceptedHeight, 1) + nextHeightToAccept, err := math.Add(lastAcceptedHeight, 1) if err != nil { t.Ctx.Log.Error("dropped query for block", zap.String("reason", "block height overflow"), diff --git a/snow/networking/benchlist/benchlist.go b/snow/networking/benchlist/benchlist.go index 05934ed2fce5..4887ebbe46f4 100644 --- a/snow/networking/benchlist/benchlist.go +++ b/snow/networking/benchlist/benchlist.go @@ -294,7 +294,7 @@ func (b *benchlist) bench(nodeID ids.NodeID) { return } - newBenchedStake, err := safemath.Add64(benchedStake, validatorStake) + newBenchedStake, err := safemath.Add(benchedStake, validatorStake) if err != nil { // This should never happen b.ctx.Log.Error("overflow calculating new benched stake", diff --git a/snow/validators/set.go b/snow/validators/set.go index b0c7e5de9ba6..e9e29c0a8f01 100644 --- a/snow/validators/set.go +++ b/snow/validators/set.go @@ -97,7 +97,7 @@ func (s *vdrSet) addWeight(nodeID ids.NodeID, weight uint64) error { } oldWeight := vdr.Weight - newWeight, err := math.Add64(oldWeight, weight) + newWeight, err := math.Add(oldWeight, weight) if err != nil { return err } @@ -137,7 +137,7 @@ func (s *vdrSet) subsetWeight(subset set.Set[ids.NodeID]) (uint64, error) { err error ) for nodeID := range subset { - totalWeight, err = math.Add64(totalWeight, s.getWeight(nodeID)) + totalWeight, err = math.Add(totalWeight, s.getWeight(nodeID)) if err != nil { return 0, err } diff --git a/utils/math/safe_math.go b/utils/math/safe_math.go index e975d0d3ecc4..a6bf2cd52e4e 100644 --- a/utils/math/safe_math.go +++ b/utils/math/safe_math.go @@ -5,7 +5,6 @@ package math import ( "errors" - "math" "golang.org/x/exp/constraints" @@ -15,17 +14,28 @@ import ( var ( ErrOverflow = errors.New("overflow") ErrUnderflow = errors.New("underflow") + + // Deprecated: Add64 is deprecated. Use Add[uint64] instead. + Add64 = Add[uint64] + + // Deprecated: Mul64 is deprecated. Use Mul[uint64] instead. + Mul64 = Mul[uint64] ) -// Add64 returns: +// MaxUint returns the maximum value of an unsigned integer of type T. +func MaxUint[T constraints.Unsigned]() T { + // Unsigned integers will underflow to their max value. + // Ref: https://go.dev/ref/spec#Arithmetic_operators + var maxValue T + maxValue-- + return maxValue +} + +// Add returns: // 1) a + b // 2) If there is overflow, an error -// -// Note that we don't have a generic Add function because checking for -// an overflow requires knowing the max size of a given type, which we -// don't know if we're adding generic types. -func Add64(a, b uint64) (uint64, error) { - if a > math.MaxUint64-b { +func Add[T constraints.Unsigned](a, b T) (T, error) { + if a > MaxUint[T]()-b { return 0, ErrOverflow } return a + b, nil @@ -44,12 +54,8 @@ func Sub[T constraints.Unsigned](a, b T) (T, error) { // Mul64 returns: // 1) a * b // 2) If there is overflow, an error -// -// Note that we don't have a generic Mul function because checking for -// an overflow requires knowing the max size of a given type, which we -// don't know if we're adding generic types. -func Mul64(a, b uint64) (uint64, error) { - if b != 0 && a > math.MaxUint64/b { +func Mul[T constraints.Unsigned](a, b T) (T, error) { + if b != 0 && a > MaxUint[T]()/b { return 0, ErrOverflow } return a * b, nil diff --git a/utils/math/safe_math_test.go b/utils/math/safe_math_test.go index 7bcd12a6371a..2ad033e57c25 100644 --- a/utils/math/safe_math_test.go +++ b/utils/math/safe_math_test.go @@ -12,28 +12,39 @@ import ( const maxUint64 uint64 = math.MaxUint64 -func TestAdd64(t *testing.T) { +func TestMaxUint(t *testing.T) { require := require.New(t) - sum, err := Add64(0, maxUint64) + require.Equal(uint(math.MaxUint), MaxUint[uint]()) + require.Equal(uint8(math.MaxUint8), MaxUint[uint8]()) + require.Equal(uint16(math.MaxUint16), MaxUint[uint16]()) + require.Equal(uint32(math.MaxUint32), MaxUint[uint32]()) + require.Equal(uint64(math.MaxUint64), MaxUint[uint64]()) + require.Equal(uintptr(math.MaxUint), MaxUint[uintptr]()) +} + +func TestAdd(t *testing.T) { + require := require.New(t) + + sum, err := Add(0, maxUint64) require.NoError(err) require.Equal(maxUint64, sum) - sum, err = Add64(maxUint64, 0) + sum, err = Add(maxUint64, 0) require.NoError(err) require.Equal(maxUint64, sum) - sum, err = Add64(uint64(1<<62), uint64(1<<62)) + sum, err = Add(uint64(1<<62), uint64(1<<62)) require.NoError(err) require.Equal(uint64(1<<63), sum) - _, err = Add64(1, maxUint64) + _, err = Add(1, maxUint64) require.ErrorIs(err, ErrOverflow) - _, err = Add64(maxUint64, 1) + _, err = Add(maxUint64, 1) require.ErrorIs(err, ErrOverflow) - _, err = Add64(maxUint64, maxUint64) + _, err = Add(maxUint64, maxUint64) require.ErrorIs(err, ErrOverflow) } @@ -63,34 +74,34 @@ func TestSub(t *testing.T) { require.ErrorIs(err, ErrUnderflow) } -func TestMul64(t *testing.T) { +func TestMul(t *testing.T) { require := require.New(t) - got, err := Mul64(0, maxUint64) + got, err := Mul(0, maxUint64) require.NoError(err) require.Zero(got) - got, err = Mul64(maxUint64, 0) + got, err = Mul(maxUint64, 0) require.NoError(err) require.Zero(got) - got, err = Mul64(uint64(1), uint64(3)) + got, err = Mul(uint64(1), uint64(3)) require.NoError(err) require.Equal(uint64(3), got) - got, err = Mul64(uint64(3), uint64(1)) + got, err = Mul(uint64(3), uint64(1)) require.NoError(err) require.Equal(uint64(3), got) - got, err = Mul64(uint64(2), uint64(3)) + got, err = Mul(uint64(2), uint64(3)) require.NoError(err) require.Equal(uint64(6), got) - got, err = Mul64(maxUint64, 0) + got, err = Mul(maxUint64, 0) require.NoError(err) require.Zero(got) - _, err = Mul64(maxUint64-1, 2) + _, err = Mul(maxUint64-1, 2) require.ErrorIs(err, ErrOverflow) } diff --git a/utils/sampler/weighted_array.go b/utils/sampler/weighted_array.go index faae08c0ccbf..a94d4aa44e5f 100644 --- a/utils/sampler/weighted_array.go +++ b/utils/sampler/weighted_array.go @@ -67,7 +67,7 @@ func (s *weightedArray) Initialize(weights []uint64) error { cumulativeWeight := uint64(0) for i := 0; i < len(s.arr); i++ { - newWeight, err := math.Add64( + newWeight, err := math.Add( cumulativeWeight, s.arr[i].cumulativeWeight, ) diff --git a/utils/sampler/weighted_benchmark_test.go b/utils/sampler/weighted_benchmark_test.go index 897e001935a1..83d8d5b6275e 100644 --- a/utils/sampler/weighted_benchmark_test.go +++ b/utils/sampler/weighted_benchmark_test.go @@ -88,7 +88,7 @@ func CalcWeightedPoW(exponent float64, size int) (uint64, []uint64, error) { weight := uint64(math.Pow(float64(i+1), exponent)) weights[i] = weight - newWeight, err := safemath.Add64(totalWeight, weight) + newWeight, err := safemath.Add(totalWeight, weight) if err != nil { return 0, nil, err } diff --git a/utils/sampler/weighted_best.go b/utils/sampler/weighted_best.go index 91ec2ae50135..f96dd52815c3 100644 --- a/utils/sampler/weighted_best.go +++ b/utils/sampler/weighted_best.go @@ -34,7 +34,7 @@ type weightedBest struct { func (s *weightedBest) Initialize(weights []uint64) error { totalWeight := uint64(0) for _, weight := range weights { - newWeight, err := safemath.Add64(totalWeight, weight) + newWeight, err := safemath.Add(totalWeight, weight) if err != nil { return err } diff --git a/utils/sampler/weighted_heap.go b/utils/sampler/weighted_heap.go index 96971657c569..4bc255c7e232 100644 --- a/utils/sampler/weighted_heap.go +++ b/utils/sampler/weighted_heap.go @@ -67,7 +67,7 @@ func (s *weightedHeap) Initialize(weights []uint64) error { // Explicitly performing a shift here allows the compiler to avoid // checking for negative numbers, which saves a couple cycles parentIndex := (i - 1) >> 1 - newWeight, err := math.Add64( + newWeight, err := math.Add( s.heap[parentIndex].cumulativeWeight, s.heap[i].cumulativeWeight, ) diff --git a/utils/sampler/weighted_linear.go b/utils/sampler/weighted_linear.go index c66bd442ab55..64ba4c302099 100644 --- a/utils/sampler/weighted_linear.go +++ b/utils/sampler/weighted_linear.go @@ -55,7 +55,7 @@ func (s *weightedLinear) Initialize(weights []uint64) error { utils.Sort(s.arr) for i := 1; i < len(s.arr); i++ { - newWeight, err := math.Add64( + newWeight, err := math.Add( s.arr[i-1].cumulativeWeight, s.arr[i].cumulativeWeight, ) diff --git a/utils/sampler/weighted_uniform.go b/utils/sampler/weighted_uniform.go index 44836450b3b8..ae28a2f272a3 100644 --- a/utils/sampler/weighted_uniform.go +++ b/utils/sampler/weighted_uniform.go @@ -33,7 +33,7 @@ type weightedUniform struct { func (s *weightedUniform) Initialize(weights []uint64) error { totalWeight := uint64(0) for _, weight := range weights { - newWeight, err := safemath.Add64(totalWeight, weight) + newWeight, err := safemath.Add(totalWeight, weight) if err != nil { return err } diff --git a/utils/sampler/weighted_without_replacement_generic.go b/utils/sampler/weighted_without_replacement_generic.go index 004ff797b90f..7714e8ac4d32 100644 --- a/utils/sampler/weighted_without_replacement_generic.go +++ b/utils/sampler/weighted_without_replacement_generic.go @@ -15,7 +15,7 @@ type weightedWithoutReplacementGeneric struct { func (s *weightedWithoutReplacementGeneric) Initialize(weights []uint64) error { totalWeight := uint64(0) for _, weight := range weights { - newWeight, err := safemath.Add64(totalWeight, weight) + newWeight, err := safemath.Add(totalWeight, weight) if err != nil { return err } diff --git a/vms/avm/service.go b/vms/avm/service.go index bc6dadd8705f..ec36285c9e67 100644 --- a/vms/avm/service.go +++ b/vms/avm/service.go @@ -579,7 +579,7 @@ func (s *Service) GetBalance(_ *http.Request, args *GetBalanceArgs, reply *GetBa if !args.IncludePartial && (len(owners.Addrs) != 1 || owners.Locktime > now) { continue } - amt, err := safemath.Add64(transferable.Amount(), uint64(reply.Balance)) + amt, err := safemath.Add(transferable.Amount(), uint64(reply.Balance)) if err != nil { return err } @@ -650,7 +650,7 @@ func (s *Service) GetAllBalances(_ *http.Request, args *GetAllBalancesArgs, repl assetID := utxo.AssetID() assetIDs.Add(assetID) balance := balances[assetID] // 0 if key doesn't exist - balance, err := safemath.Add64(transferable.Amount(), balance) + balance, err := safemath.Add(transferable.Amount(), balance) if err != nil { balances[assetID] = math.MaxUint64 } else { @@ -1264,7 +1264,7 @@ func (s *Service) buildSendMultiple(args *SendMultipleArgs) (*txs.Tx, ids.ShortI assetIDs[output.AssetID] = assetID } currentAmount := amounts[assetID] - newAmount, err := safemath.Add64(currentAmount, uint64(output.Amount)) + newAmount, err := safemath.Add(currentAmount, uint64(output.Amount)) if err != nil { return nil, ids.ShortEmpty, fmt.Errorf("problem calculating required spend amount: %w", err) } @@ -1295,7 +1295,7 @@ func (s *Service) buildSendMultiple(args *SendMultipleArgs) (*txs.Tx, ids.ShortI amountsWithFee[assetID] = amount } - amountWithFee, err := safemath.Add64(amounts[s.vm.feeAssetID], s.vm.TxFee) + amountWithFee, err := safemath.Add(amounts[s.vm.feeAssetID], s.vm.TxFee) if err != nil { return nil, ids.ShortEmpty, fmt.Errorf("problem calculating required spend amount: %w", err) } @@ -1818,7 +1818,7 @@ func (s *Service) buildImport(args *ImportArgs) (*txs.Tx, error) { return nil, err } for asset, amount := range localAmountsSpent { - newAmount, err := safemath.Add64(amountsSpent[asset], amount) + newAmount, err := safemath.Add(amountsSpent[asset], amount) if err != nil { return nil, fmt.Errorf("problem calculating required spend amount: %w", err) } @@ -1955,7 +1955,7 @@ func (s *Service) buildExport(args *ExportArgs) (*txs.Tx, ids.ShortID, error) { amounts := map[ids.ID]uint64{} if assetID == s.vm.feeAssetID { - amountWithFee, err := safemath.Add64(uint64(args.Amount), s.vm.TxFee) + amountWithFee, err := safemath.Add(uint64(args.Amount), s.vm.TxFee) if err != nil { return nil, ids.ShortEmpty, fmt.Errorf("problem calculating required spend amount: %w", err) } diff --git a/vms/avm/utxo/spender.go b/vms/avm/utxo/spender.go index 02ade0d92eae..1c6fd0142b88 100644 --- a/vms/avm/utxo/spender.go +++ b/vms/avm/utxo/spender.go @@ -141,7 +141,7 @@ func (s *spender) Spend( // this input doesn't have an amount, so I don't care about it here continue } - newAmountSpent, err := math.Add64(amountSpent, input.Amount()) + newAmountSpent, err := math.Add(amountSpent, input.Amount()) if err != nil { // there was an error calculating the consumed amount, just error return nil, nil, nil, errSpendOverflow @@ -274,7 +274,7 @@ func (s *spender) SpendAll( // this input doesn't have an amount, so I don't care about it here continue } - newAmountSpent, err := math.Add64(amountSpent, input.Amount()) + newAmountSpent, err := math.Add(amountSpent, input.Amount()) if err != nil { // there was an error calculating the consumed amount, just error return nil, nil, nil, errSpendOverflow diff --git a/vms/avm/wallet_service.go b/vms/avm/wallet_service.go index 871d81580a59..c5bf0ab00ea6 100644 --- a/vms/avm/wallet_service.go +++ b/vms/avm/wallet_service.go @@ -229,7 +229,7 @@ func (w *WalletService) SendMultiple(_ *http.Request, args *SendMultipleArgs, re assetIDs[output.AssetID] = assetID } currentAmount := amounts[assetID] - newAmount, err := math.Add64(currentAmount, uint64(output.Amount)) + newAmount, err := math.Add(currentAmount, uint64(output.Amount)) if err != nil { return fmt.Errorf("problem calculating required spend amount: %w", err) } @@ -257,7 +257,7 @@ func (w *WalletService) SendMultiple(_ *http.Request, args *SendMultipleArgs, re amountsWithFee := maps.Clone(amounts) - amountWithFee, err := math.Add64(amounts[w.vm.feeAssetID], w.vm.TxFee) + amountWithFee, err := math.Add(amounts[w.vm.feeAssetID], w.vm.TxFee) if err != nil { return fmt.Errorf("problem calculating required spend amount: %w", err) } diff --git a/vms/components/avax/flow_checker.go b/vms/components/avax/flow_checker.go index e02aee717e3b..d4d5cc8cafda 100644 --- a/vms/components/avax/flow_checker.go +++ b/vms/components/avax/flow_checker.go @@ -35,7 +35,7 @@ func (fc *FlowChecker) Produce(assetID ids.ID, amount uint64) { func (fc *FlowChecker) add(value map[ids.ID]uint64, assetID ids.ID, amount uint64) { var err error - value[assetID], err = math.Add64(value[assetID], amount) + value[assetID], err = math.Add(value[assetID], amount) fc.errs.Add(err) } diff --git a/vms/components/avax/utxo_fetching.go b/vms/components/avax/utxo_fetching.go index 082327319efd..34e3279f22ef 100644 --- a/vms/components/avax/utxo_fetching.go +++ b/vms/components/avax/utxo_fetching.go @@ -24,7 +24,7 @@ func GetBalance(db UTXOReader, addrs set.Set[ids.ShortID]) (uint64, error) { balance := uint64(0) for _, utxo := range utxos { if out, ok := utxo.Out.(Amounter); ok { - balance, err = safemath.Add64(out.Amount(), balance) + balance, err = safemath.Add(out.Amount(), balance) if err != nil { return 0, err } diff --git a/vms/example/xsvm/state/storage.go b/vms/example/xsvm/state/storage.go index 48234e9678de..00fb20e45c7b 100644 --- a/vms/example/xsvm/state/storage.go +++ b/vms/example/xsvm/state/storage.go @@ -133,7 +133,7 @@ func IncreaseBalance(db database.KeyValueReaderWriterDeleter, address ids.ShortI if err != nil { return err } - balance, err = math.Add64(balance, amount) + balance, err = math.Add(balance, amount) if err != nil { return err } @@ -185,7 +185,7 @@ func IncreaseLoan(db database.KeyValueReaderWriterDeleter, chainID ids.ID, amoun if err != nil { return err } - balance, err = math.Add64(balance, amount) + balance, err = math.Add(balance, amount) if err != nil { return err } diff --git a/vms/platformvm/api/static_service.go b/vms/platformvm/api/static_service.go index d2374d74133a..418b447114c7 100644 --- a/vms/platformvm/api/static_service.go +++ b/vms/platformvm/api/static_service.go @@ -280,7 +280,7 @@ func (*StaticService) BuildGenesis(_ *http.Request, args *BuildGenesisArgs, repl } stake[i] = utxo - newWeight, err := math.Add64(weight, uint64(apiUTXO.Amount)) + newWeight, err := math.Add(weight, uint64(apiUTXO.Amount)) if err != nil { return errStakeOverflow } diff --git a/vms/platformvm/reward/calculator.go b/vms/platformvm/reward/calculator.go index 79a845ef8980..1806da18e25f 100644 --- a/vms/platformvm/reward/calculator.go +++ b/vms/platformvm/reward/calculator.go @@ -78,7 +78,7 @@ func Split(totalAmount uint64, shares uint32) (uint64, uint64) { remainderAmount := remainderShares * (totalAmount / PercentDenominator) // Delay rounding as long as possible for small numbers - if optimisticReward, err := math.Mul64(remainderShares, totalAmount); err == nil { + if optimisticReward, err := math.Mul(remainderShares, totalAmount); err == nil { remainderAmount = optimisticReward / PercentDenominator } diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index d1bdf60a6529..0299192b6677 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -192,14 +192,14 @@ utxoFor: switch out := utxo.Out.(type) { case *secp256k1fx.TransferOutput: if out.Locktime <= currentTime { - newBalance, err := safemath.Add64(unlockeds[assetID], out.Amount()) + newBalance, err := safemath.Add(unlockeds[assetID], out.Amount()) if err != nil { unlockeds[assetID] = math.MaxUint64 } else { unlockeds[assetID] = newBalance } } else { - newBalance, err := safemath.Add64(lockedNotStakeables[assetID], out.Amount()) + newBalance, err := safemath.Add(lockedNotStakeables[assetID], out.Amount()) if err != nil { lockedNotStakeables[assetID] = math.MaxUint64 } else { @@ -215,21 +215,21 @@ utxoFor: ) continue utxoFor case innerOut.Locktime > currentTime: - newBalance, err := safemath.Add64(lockedNotStakeables[assetID], out.Amount()) + newBalance, err := safemath.Add(lockedNotStakeables[assetID], out.Amount()) if err != nil { lockedNotStakeables[assetID] = math.MaxUint64 } else { lockedNotStakeables[assetID] = newBalance } case out.Locktime <= currentTime: - newBalance, err := safemath.Add64(unlockeds[assetID], out.Amount()) + newBalance, err := safemath.Add(unlockeds[assetID], out.Amount()) if err != nil { unlockeds[assetID] = math.MaxUint64 } else { unlockeds[assetID] = newBalance } default: - newBalance, err := safemath.Add64(lockedStakeables[assetID], out.Amount()) + newBalance, err := safemath.Add(lockedStakeables[assetID], out.Amount()) if err != nil { lockedStakeables[assetID] = math.MaxUint64 } else { @@ -245,7 +245,7 @@ utxoFor: balances := maps.Clone(lockedStakeables) for assetID, amount := range lockedNotStakeables { - newBalance, err := safemath.Add64(balances[assetID], amount) + newBalance, err := safemath.Add(balances[assetID], amount) if err != nil { balances[assetID] = math.MaxUint64 } else { @@ -253,7 +253,7 @@ utxoFor: } } for assetID, amount := range unlockeds { - newBalance, err := safemath.Add64(balances[assetID], amount) + newBalance, err := safemath.Add(balances[assetID], amount) if err != nil { balances[assetID] = math.MaxUint64 } else { @@ -1898,7 +1898,7 @@ func getStakeHelper(tx *txs.Tx, addrs set.Set[ids.ShortID], totalAmountStaked ma } assetID := output.AssetID() - newAmount, err := safemath.Add64(totalAmountStaked[assetID], secpOut.Amt) + newAmount, err := safemath.Add(totalAmountStaked[assetID], secpOut.Amt) if err != nil { newAmount = math.MaxUint64 } diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 74b71dadf8a2..a6266a480858 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -379,7 +379,7 @@ type ValidatorWeightDiff struct { func (v *ValidatorWeightDiff) Add(negative bool, amount uint64) error { if v.Decrease == negative { var err error - v.Amount, err = safemath.Add64(v.Amount, amount) + v.Amount, err = safemath.Add(v.Amount, amount) return err } @@ -1126,7 +1126,7 @@ func applyWeightDiff( if weightDiff.Decrease { // The validator's weight was decreased at this block, so in the // prior block it was higher. - vdr.Weight, err = safemath.Add64(vdr.Weight, weightDiff.Amount) + vdr.Weight, err = safemath.Add(vdr.Weight, weightDiff.Amount) } else { // The validator's weight was increased at this block, so in the // prior block it was lower. @@ -1232,7 +1232,7 @@ func (s *state) syncGenesis(genesisBlk block.Block, genesis *genesis.Genesis) er stakeAmount, currentSupply, ) - newCurrentSupply, err := safemath.Add64(currentSupply, potentialReward) + newCurrentSupply, err := safemath.Add(currentSupply, potentialReward) if err != nil { return err } diff --git a/vms/platformvm/txs/add_delegator_tx.go b/vms/platformvm/txs/add_delegator_tx.go index 3df97cf0af74..25e9a9251821 100644 --- a/vms/platformvm/txs/add_delegator_tx.go +++ b/vms/platformvm/txs/add_delegator_tx.go @@ -99,7 +99,7 @@ func (tx *AddDelegatorTx) SyntacticVerify(ctx *snow.Context) error { if err := out.Verify(); err != nil { return fmt.Errorf("output verification failed: %w", err) } - newWeight, err := math.Add64(totalStakeWeight, out.Output().Amount()) + newWeight, err := math.Add(totalStakeWeight, out.Output().Amount()) if err != nil { return err } diff --git a/vms/platformvm/txs/add_permissionless_delegator_tx.go b/vms/platformvm/txs/add_permissionless_delegator_tx.go index 9c29b97339d0..38fd73e7f857 100644 --- a/vms/platformvm/txs/add_permissionless_delegator_tx.go +++ b/vms/platformvm/txs/add_permissionless_delegator_tx.go @@ -110,7 +110,7 @@ func (tx *AddPermissionlessDelegatorTx) SyntacticVerify(ctx *snow.Context) error stakedAssetID := firstStakeOutput.AssetID() totalStakeWeight := firstStakeOutput.Output().Amount() for _, out := range tx.StakeOuts[1:] { - newWeight, err := math.Add64(totalStakeWeight, out.Output().Amount()) + newWeight, err := math.Add(totalStakeWeight, out.Output().Amount()) if err != nil { return err } diff --git a/vms/platformvm/txs/add_permissionless_validator_tx.go b/vms/platformvm/txs/add_permissionless_validator_tx.go index 0f655c8daea4..15a11bc23cae 100644 --- a/vms/platformvm/txs/add_permissionless_validator_tx.go +++ b/vms/platformvm/txs/add_permissionless_validator_tx.go @@ -160,7 +160,7 @@ func (tx *AddPermissionlessValidatorTx) SyntacticVerify(ctx *snow.Context) error stakedAssetID := firstStakeOutput.AssetID() totalStakeWeight := firstStakeOutput.Output().Amount() for _, out := range tx.StakeOuts[1:] { - newWeight, err := math.Add64(totalStakeWeight, out.Output().Amount()) + newWeight, err := math.Add(totalStakeWeight, out.Output().Amount()) if err != nil { return err } diff --git a/vms/platformvm/txs/add_validator_tx.go b/vms/platformvm/txs/add_validator_tx.go index b6ab65b56e8f..8a86ef172713 100644 --- a/vms/platformvm/txs/add_validator_tx.go +++ b/vms/platformvm/txs/add_validator_tx.go @@ -112,7 +112,7 @@ func (tx *AddValidatorTx) SyntacticVerify(ctx *snow.Context) error { if err := out.Verify(); err != nil { return fmt.Errorf("failed to verify output: %w", err) } - newWeight, err := math.Add64(totalStakeWeight, out.Output().Amount()) + newWeight, err := math.Add(totalStakeWeight, out.Output().Amount()) if err != nil { return err } diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index b31b73ce543b..9b9876e3ccca 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -425,7 +425,7 @@ func verifyAddDelegatorTx( ) } - maximumWeight, err := safemath.Mul64(MaxValidatorWeightFactor, primaryNetworkValidator.Weight) + maximumWeight, err := safemath.Mul(MaxValidatorWeightFactor, primaryNetworkValidator.Weight) if err != nil { return nil, ErrStakeOverflow } @@ -678,7 +678,7 @@ func verifyAddPermissionlessDelegatorTx( ) } - maximumWeight, err := safemath.Mul64( + maximumWeight, err := safemath.Mul( uint64(delegatorRules.maxValidatorWeightFactor), validator.Weight, ) diff --git a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go index eb18c6609299..8c6d14b1071f 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go @@ -125,7 +125,7 @@ func overDelegated( if err != nil { return true, err } - newMaxWeight, err := math.Add64(maxWeight, delegatorWeight) + newMaxWeight, err := math.Add(maxWeight, delegatorWeight) if err != nil { return true, err } @@ -159,7 +159,7 @@ func GetMaxWeight( for currentDelegatorIterator.Next() { currentDelegator := currentDelegatorIterator.Value() - currentWeight, err = math.Add64(currentWeight, currentDelegator.Weight) + currentWeight, err = math.Add(currentWeight, currentDelegator.Weight) if err != nil { currentDelegatorIterator.Release() return 0, err @@ -202,7 +202,7 @@ func GetMaxWeight( var op func(uint64, uint64) (uint64, error) if isAdded { - op = math.Add64 + op = math.Add } else { op = math.Sub[uint64] } diff --git a/vms/platformvm/utxo/verifier.go b/vms/platformvm/utxo/verifier.go index 4adde447bad5..be1187880146 100644 --- a/vms/platformvm/utxo/verifier.go +++ b/vms/platformvm/utxo/verifier.go @@ -206,7 +206,7 @@ func (h *verifier) VerifySpendUTXOs( amount := in.Amount() if now >= locktime { - newUnlockedConsumed, err := math.Add64(unlockedConsumed[realAssetID], amount) + newUnlockedConsumed, err := math.Add(unlockedConsumed[realAssetID], amount) if err != nil { return err } @@ -234,7 +234,7 @@ func (h *verifier) VerifySpendUTXOs( owners = make(map[ids.ID]uint64) lockedConsumedAsset[locktime] = owners } - newAmount, err := math.Add64(owners[ownerID], amount) + newAmount, err := math.Add(owners[ownerID], amount) if err != nil { return err } @@ -255,7 +255,7 @@ func (h *verifier) VerifySpendUTXOs( amount := output.Amount() if locktime == 0 { - newUnlockedProduced, err := math.Add64(unlockedProduced[assetID], amount) + newUnlockedProduced, err := math.Add(unlockedProduced[assetID], amount) if err != nil { return err } @@ -283,7 +283,7 @@ func (h *verifier) VerifySpendUTXOs( owners = make(map[ids.ID]uint64) lockedProducedAsset[locktime] = owners } - newAmount, err := math.Add64(owners[ownerID], amount) + newAmount, err := math.Add(owners[ownerID], amount) if err != nil { return err } diff --git a/vms/platformvm/warp/validator.go b/vms/platformvm/warp/validator.go index 0d33a9f12f26..805128a6d963 100644 --- a/vms/platformvm/warp/validator.go +++ b/vms/platformvm/warp/validator.go @@ -71,7 +71,7 @@ func FlattenValidatorSet(vdrSet map[ids.NodeID]*validators.GetValidatorOutput) ( err error ) for _, vdr := range vdrSet { - totalWeight, err = math.Add64(totalWeight, vdr.Weight) + totalWeight, err = math.Add(totalWeight, vdr.Weight) if err != nil { return nil, 0, fmt.Errorf("%w: %w", ErrWeightOverflow, err) } @@ -136,7 +136,7 @@ func SumWeight(vdrs []*Validator) (uint64, error) { err error ) for _, vdr := range vdrs { - weight, err = math.Add64(weight, vdr.Weight) + weight, err = math.Add(weight, vdr.Weight) if err != nil { return 0, fmt.Errorf("%w: %w", ErrWeightOverflow, err) } diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index ae79aecafcd5..f0122fb13c7d 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -123,7 +123,7 @@ func (w *windower) Proposers(ctx context.Context, blockHeight, pChainHeight uint var totalWeight uint64 for _, validator := range validators { - totalWeight, err = math.Add64(totalWeight, validator.weight) + totalWeight, err = math.Add(totalWeight, validator.weight) if err != nil { return nil, err } diff --git a/vms/secp256k1fx/input.go b/vms/secp256k1fx/input.go index 7e11556be582..a013928e611b 100644 --- a/vms/secp256k1fx/input.go +++ b/vms/secp256k1fx/input.go @@ -28,7 +28,7 @@ type Input struct { func (in *Input) Cost() (uint64, error) { numSigs := uint64(len(in.SigIndices)) - return math.Mul64(numSigs, CostPerSignature) + return math.Mul(numSigs, CostPerSignature) } // Verify this input is syntactically valid diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index 8d1ea6f34f07..000e8e095664 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -116,7 +116,7 @@ func (b *backend) AcceptAtomicTx(ctx context.Context, tx *evm.Tx) error { } account.Balance.Sub(account.Balance, balance) - newNonce, err := math.Add64(input.Nonce, 1) + newNonce, err := math.Add(input.Nonce, 1) if err != nil { return err } diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index 0554cb39ba95..1628c2002956 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -170,7 +170,7 @@ func (b *builder) GetImportableBalance( continue } - newBalance, err := math.Add64(balance, amount) + newBalance, err := math.Add(balance, amount) if err != nil { return 0, err } @@ -218,7 +218,7 @@ func (b *builder) NewImportTx( }, }) - newImportedAmount, err := math.Add64(importedAmount, amount) + newImportedAmount, err := math.Add(importedAmount, amount) if err != nil { return nil, err } @@ -280,7 +280,7 @@ func (b *builder) NewExportTx( Out: output, } - newExportedAmount, err := math.Add64(exportedAmount, output.Amt) + newExportedAmount, err := math.Add(exportedAmount, output.Amt) if err != nil { return nil, err } @@ -311,7 +311,7 @@ func (b *builder) NewExportTx( return nil, err } - amountToConsume, err := math.Add64(exportedAmount, initialFee) + amountToConsume, err := math.Add(exportedAmount, initialFee) if err != nil { return nil, err } @@ -360,7 +360,7 @@ func (b *builder) NewExportTx( // Update the cost for the next iteration cost = newCost - amountToConsume, err = math.Add64(amountToConsume, additionalFee) + amountToConsume, err = math.Add(amountToConsume, additionalFee) if err != nil { return nil, err } diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index 745ebe4d5848..61e5e824f55c 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -315,7 +315,7 @@ func (b *builder) NewBaseTx( } for _, out := range outputs { assetID := out.AssetID() - amountToBurn, err := math.Add64(toBurn[assetID], out.Out.Amount()) + amountToBurn, err := math.Add(toBurn[assetID], out.Out.Amount()) if err != nil { return nil, err } @@ -630,7 +630,7 @@ func (b *builder) NewImportTx( }) assetID := utxo.AssetID() - newImportedAmount, err := math.Add64(importedAmounts[assetID], out.Amt) + newImportedAmount, err := math.Add(importedAmounts[assetID], out.Amt) if err != nil { return nil, err } @@ -702,7 +702,7 @@ func (b *builder) NewExportTx( } for _, out := range outputs { assetID := out.AssetID() - amountToBurn, err := math.Add64(toBurn[assetID], out.Out.Amount()) + amountToBurn, err := math.Add(toBurn[assetID], out.Out.Amount()) if err != nil { return nil, err } @@ -916,7 +916,7 @@ func (b *builder) getBalance( } assetID := utxo.AssetID() - balance[assetID], err = math.Add64(balance[assetID], out.Amt) + balance[assetID], err = math.Add(balance[assetID], out.Amt) if err != nil { return nil, err } diff --git a/wallet/chain/x/builder/builder.go b/wallet/chain/x/builder/builder.go index 20411e6e4ce7..46e28fdf7504 100644 --- a/wallet/chain/x/builder/builder.go +++ b/wallet/chain/x/builder/builder.go @@ -213,7 +213,7 @@ func (b *builder) NewBaseTx( } for _, out := range outputs { assetID := out.AssetID() - amountToBurn, err := math.Add64(toBurn[assetID], out.Out.Amount()) + amountToBurn, err := math.Add(toBurn[assetID], out.Out.Amount()) if err != nil { return nil, err } @@ -408,7 +408,7 @@ func (b *builder) NewImportTx( }) assetID := utxo.AssetID() - newImportedAmount, err := math.Add64(importedAmounts[assetID], out.Amt) + newImportedAmount, err := math.Add(importedAmounts[assetID], out.Amt) if err != nil { return nil, err } @@ -480,7 +480,7 @@ func (b *builder) NewExportTx( } for _, out := range outputs { assetID := out.AssetID() - amountToBurn, err := math.Add64(toBurn[assetID], out.Out.Amount()) + amountToBurn, err := math.Add(toBurn[assetID], out.Out.Amount()) if err != nil { return nil, err } @@ -540,7 +540,7 @@ func (b *builder) getBalance( } assetID := utxo.AssetID() - balance[assetID], err = math.Add64(balance[assetID], out.Amt) + balance[assetID], err = math.Add(balance[assetID], out.Amt) if err != nil { return nil, err } From 2246a5cb333afc12346b374d6b7fb61faa8b9902 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 09:35:22 -0400 Subject: [PATCH 071/100] cleanup --- utils/math/safe_math.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/utils/math/safe_math.go b/utils/math/safe_math.go index a6bf2cd52e4e..265127606a9c 100644 --- a/utils/math/safe_math.go +++ b/utils/math/safe_math.go @@ -7,8 +7,6 @@ import ( "errors" "golang.org/x/exp/constraints" - - "github.com/ava-labs/avalanchego/utils" ) var ( @@ -26,9 +24,7 @@ var ( func MaxUint[T constraints.Unsigned]() T { // Unsigned integers will underflow to their max value. // Ref: https://go.dev/ref/spec#Arithmetic_operators - var maxValue T - maxValue-- - return maxValue + return T(0) - 1 } // Add returns: @@ -46,7 +42,7 @@ func Add[T constraints.Unsigned](a, b T) (T, error) { // 2) If there is underflow, an error func Sub[T constraints.Unsigned](a, b T) (T, error) { if a < b { - return utils.Zero[T](), ErrUnderflow + return 0, ErrUnderflow } return a - b, nil } From b43fa129e474bd4673db8e5988c893c9678644a8 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 09:54:23 -0400 Subject: [PATCH 072/100] nits --- utils/math/safe_math.go | 4 +--- vms/platformvm/txs/executor/staker_tx_verification_helpers.go | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/utils/math/safe_math.go b/utils/math/safe_math.go index 265127606a9c..8b76647bf83d 100644 --- a/utils/math/safe_math.go +++ b/utils/math/safe_math.go @@ -22,9 +22,7 @@ var ( // MaxUint returns the maximum value of an unsigned integer of type T. func MaxUint[T constraints.Unsigned]() T { - // Unsigned integers will underflow to their max value. - // Ref: https://go.dev/ref/spec#Arithmetic_operators - return T(0) - 1 + return ^T(0) } // Add returns: diff --git a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go index 8c6d14b1071f..184ab313aa2f 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go @@ -204,7 +204,7 @@ func GetMaxWeight( if isAdded { op = math.Add } else { - op = math.Sub[uint64] + op = math.Sub } currentWeight, err = op(currentWeight, delegator.Weight) if err != nil { From 67dabb6c0dc0993972ed1febcac7bf57aafaf78d Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 10:13:13 -0400 Subject: [PATCH 073/100] merged --- vms/components/fee/dimensions.go | 6 +++--- vms/components/fee/gas.go | 6 +++--- vms/components/fee/state.go | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/vms/components/fee/dimensions.go b/vms/components/fee/dimensions.go index 968af5f5a6ea..843a8b24615f 100644 --- a/vms/components/fee/dimensions.go +++ b/vms/components/fee/dimensions.go @@ -23,7 +23,7 @@ func (d Dimensions) Add(os ...Dimensions) (Dimensions, error) { var err error for _, o := range os { for i := range o { - d[i], err = math.Add64(d[i], o[i]) + d[i], err = math.Add(d[i], o[i]) if err != nil { return d, err } @@ -48,11 +48,11 @@ func (d Dimensions) Sub(os ...Dimensions) (Dimensions, error) { func (d Dimensions) ToGas(weights Dimensions) (Gas, error) { var res uint64 for i := range d { - v, err := math.Mul64(d[i], weights[i]) + v, err := math.Mul(d[i], weights[i]) if err != nil { return 0, err } - res, err = math.Add64(res, v) + res, err = math.Add(res, v) if err != nil { return 0, err } diff --git a/vms/components/fee/gas.go b/vms/components/fee/gas.go index 1e5023945957..e1ac563f1e55 100644 --- a/vms/components/fee/gas.go +++ b/vms/components/fee/gas.go @@ -19,11 +19,11 @@ type ( ) func (g Gas) AddPerSecond(gasPerSecond Gas, seconds uint64) Gas { - newGas, err := safemath.Mul64(uint64(gasPerSecond), seconds) + newGas, err := safemath.Mul(uint64(gasPerSecond), seconds) if err != nil { return math.MaxUint64 } - totalGas, err := safemath.Add64(uint64(g), newGas) + totalGas, err := safemath.Add(uint64(g), newGas) if err != nil { return math.MaxUint64 } @@ -31,7 +31,7 @@ func (g Gas) AddPerSecond(gasPerSecond Gas, seconds uint64) Gas { } func (g Gas) SubPerSecond(gasPerSecond Gas, seconds uint64) Gas { - gasToRemove, err := safemath.Mul64(uint64(gasPerSecond), seconds) + gasToRemove, err := safemath.Mul(uint64(gasPerSecond), seconds) if err != nil { return 0 } diff --git a/vms/components/fee/state.go b/vms/components/fee/state.go index 622f233552e7..03f36e17257f 100644 --- a/vms/components/fee/state.go +++ b/vms/components/fee/state.go @@ -38,7 +38,7 @@ func (s State) ConsumeGas(gas Gas) (State, error) { return State{}, ErrInsufficientCapacity } - newExcess, err := safemath.Add64(uint64(s.Excess), uint64(gas)) + newExcess, err := safemath.Add(uint64(s.Excess), uint64(gas)) if err != nil { //nolint:nilerr // excess is capped at math.MaxUint64 return State{ From 4f2ac8a8440dbfcf57a9aab204082cad11df578f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 10:13:51 -0400 Subject: [PATCH 074/100] fix comment --- utils/math/safe_math.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/math/safe_math.go b/utils/math/safe_math.go index 8b76647bf83d..1a3aa0bb7ae8 100644 --- a/utils/math/safe_math.go +++ b/utils/math/safe_math.go @@ -45,7 +45,7 @@ func Sub[T constraints.Unsigned](a, b T) (T, error) { return a - b, nil } -// Mul64 returns: +// Mul returns: // 1) a * b // 2) If there is overflow, an error func Mul[T constraints.Unsigned](a, b T) (T, error) { From 7aa464590dc6b2e0593643fa0972bb4b682914a4 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 10:35:43 -0400 Subject: [PATCH 075/100] nits --- vms/components/fee/dimensions.go | 9 +++ vms/components/fee/dimensions_test.go | 96 +++++++++++++++++++++++++++ vms/components/fee/gas.go | 10 ++- vms/components/fee/state.go | 11 ++- vms/components/fee/state_test.go | 7 +- 5 files changed, 125 insertions(+), 8 deletions(-) diff --git a/vms/components/fee/dimensions.go b/vms/components/fee/dimensions.go index 843a8b24615f..3db1db01b3d2 100644 --- a/vms/components/fee/dimensions.go +++ b/vms/components/fee/dimensions.go @@ -19,6 +19,9 @@ type ( Dimensions [NumDimensions]uint64 ) +// Add returns d + sum(os...). +// +// If overflow occurs, an error is returned. func (d Dimensions) Add(os ...Dimensions) (Dimensions, error) { var err error for _, o := range os { @@ -32,6 +35,9 @@ func (d Dimensions) Add(os ...Dimensions) (Dimensions, error) { return d, nil } +// Sub returns d - sum(os...). +// +// If underflow occurs, an error is returned. func (d Dimensions) Sub(os ...Dimensions) (Dimensions, error) { var err error for _, o := range os { @@ -45,6 +51,9 @@ func (d Dimensions) Sub(os ...Dimensions) (Dimensions, error) { return d, nil } +// ToGas returns d · weights. +// +// If overflow occurs, an error is returned. func (d Dimensions) ToGas(weights Dimensions) (Gas, error) { var res uint64 for i := range d { diff --git a/vms/components/fee/dimensions_test.go b/vms/components/fee/dimensions_test.go index 6e64aa0050ff..3a0260934e75 100644 --- a/vms/components/fee/dimensions_test.go +++ b/vms/components/fee/dimensions_test.go @@ -98,6 +98,54 @@ func Test_Dimensions_Add(t *testing.T) { }, expectedErr: safemath.ErrOverflow, }, + { + name: "db read overflow", + lhs: Dimensions{ + Bandwidth: 1, + DBRead: math.MaxUint64, + DBWrite: 3, + Compute: 4, + }, + rhs: []Dimensions{ + { + Bandwidth: 10, + DBRead: 20, + DBWrite: 30, + Compute: 40, + }, + }, + expected: Dimensions{ + Bandwidth: 11, + DBRead: 0, + DBWrite: 3, + Compute: 4, + }, + expectedErr: safemath.ErrOverflow, + }, + { + name: "db write overflow", + lhs: Dimensions{ + Bandwidth: 1, + DBRead: 2, + DBWrite: math.MaxUint64, + Compute: 4, + }, + rhs: []Dimensions{ + { + Bandwidth: 10, + DBRead: 20, + DBWrite: 30, + Compute: 40, + }, + }, + expected: Dimensions{ + Bandwidth: 11, + DBRead: 22, + DBWrite: 0, + Compute: 4, + }, + expectedErr: safemath.ErrOverflow, + }, { name: "compute overflow", lhs: Dimensions{ @@ -220,6 +268,54 @@ func Test_Dimensions_Sub(t *testing.T) { }, expectedErr: safemath.ErrUnderflow, }, + { + name: "db read underflow", + lhs: Dimensions{ + Bandwidth: 11, + DBRead: 22, + DBWrite: 33, + Compute: 44, + }, + rhs: []Dimensions{ + { + Bandwidth: 1, + DBRead: math.MaxUint64, + DBWrite: 3, + Compute: 4, + }, + }, + expected: Dimensions{ + Bandwidth: 10, + DBRead: 0, + DBWrite: 33, + Compute: 44, + }, + expectedErr: safemath.ErrUnderflow, + }, + { + name: "db write underflow", + lhs: Dimensions{ + Bandwidth: 11, + DBRead: 22, + DBWrite: 33, + Compute: 44, + }, + rhs: []Dimensions{ + { + Bandwidth: 1, + DBRead: 2, + DBWrite: math.MaxUint64, + Compute: 4, + }, + }, + expected: Dimensions{ + Bandwidth: 10, + DBRead: 20, + DBWrite: 0, + Compute: 44, + }, + expectedErr: safemath.ErrUnderflow, + }, { name: "compute underflow", lhs: Dimensions{ diff --git a/vms/components/fee/gas.go b/vms/components/fee/gas.go index e1ac563f1e55..1e0ef2af86fe 100644 --- a/vms/components/fee/gas.go +++ b/vms/components/fee/gas.go @@ -18,6 +18,9 @@ type ( GasPrice uint64 ) +// AddPerSecond returns g + gasPerSecond * seconds. +// +// If overflow would occur, MaxUint64 is returned. func (g Gas) AddPerSecond(gasPerSecond Gas, seconds uint64) Gas { newGas, err := safemath.Mul(uint64(gasPerSecond), seconds) if err != nil { @@ -30,6 +33,9 @@ func (g Gas) AddPerSecond(gasPerSecond Gas, seconds uint64) Gas { return Gas(totalGas) } +// SubPerSecond returns g - gasPerSecond * seconds. +// +// If underflow would occur, 0 is returned. func (g Gas) SubPerSecond(gasPerSecond Gas, seconds uint64) Gas { gasToRemove, err := safemath.Mul(uint64(gasPerSecond), seconds) if err != nil { @@ -42,7 +48,7 @@ func (g Gas) SubPerSecond(gasPerSecond Gas, seconds uint64) Gas { return Gas(totalGas) } -// MulExp returns an approximation of g*e^(excess / excessConversionConstant) +// MulExp returns an approximation of g * e^(excess / excessConversionConstant) // // This implements the EIP-4844 fake exponential formula: // @@ -63,7 +69,7 @@ func (g Gas) SubPerSecond(gasPerSecond Gas, seconds uint64) Gas { // // This function does not perform any memory allocations. // -//nolint:dupword // This comment is copied from the EIP-4844 specification +//nolint:dupword // The python is copied from the EIP-4844 specification func (g GasPrice) MulExp( excess Gas, excessConversionConstant Gas, diff --git a/vms/components/fee/state.go b/vms/components/fee/state.go index 03f36e17257f..cd6414bba355 100644 --- a/vms/components/fee/state.go +++ b/vms/components/fee/state.go @@ -17,6 +17,11 @@ type State struct { Excess Gas } +// AdvanceTime adds maxGasPerSecond to capacity and subtracts targetGasPerSecond +// from excess over the provided duration. +// +// Capacity is capped at maxGasCapacity. +// Excess to be removed is capped at excess. func (s State) AdvanceTime( maxGasCapacity Gas, maxGasPerSecond Gas, @@ -32,6 +37,10 @@ func (s State) AdvanceTime( } } +// ConsumeGas removes gas from capacity and adds gas to excess. +// +// If the capacity is insufficient, an error is returned. +// If the excess would overflow, it is capped at MaxUint64. func (s State) ConsumeGas(gas Gas) (State, error) { newCapacity, err := safemath.Sub(uint64(s.Capacity), uint64(gas)) if err != nil { @@ -40,7 +49,7 @@ func (s State) ConsumeGas(gas Gas) (State, error) { newExcess, err := safemath.Add(uint64(s.Excess), uint64(gas)) if err != nil { - //nolint:nilerr // excess is capped at math.MaxUint64 + //nolint:nilerr // excess is capped at MaxUint64 return State{ Capacity: Gas(newCapacity), Excess: math.MaxUint64, diff --git a/vms/components/fee/state_test.go b/vms/components/fee/state_test.go index d688acd745d9..2a48f33a4cc0 100644 --- a/vms/components/fee/state_test.go +++ b/vms/components/fee/state_test.go @@ -129,11 +129,8 @@ func Test_State_ConsumeGas(t *testing.T) { Capacity: 10, Excess: 10, }, - gas: 11, - expected: State{ - Capacity: 0, - Excess: 0, - }, + gas: 11, + expected: State{}, expectedErr: ErrInsufficientCapacity, }, { From 76ccfc4214249dbbd285559e641f91e10eeec2f5 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 12:01:44 -0400 Subject: [PATCH 076/100] wip --- .../txs/fee/complexity_calculator.go | 68 ++- vms/platformvm/txs/fee/dynamic_calculator.go | 535 ------------------ .../txs/fee/dynamic_calculator_test.go | 262 --------- 3 files changed, 46 insertions(+), 819 deletions(-) delete mode 100644 vms/platformvm/txs/fee/dynamic_calculator.go delete mode 100644 vms/platformvm/txs/fee/dynamic_calculator_test.go diff --git a/vms/platformvm/txs/fee/complexity_calculator.go b/vms/platformvm/txs/fee/complexity_calculator.go index 995d02814dc6..2a0a6b175a17 100644 --- a/vms/platformvm/txs/fee/complexity_calculator.go +++ b/vms/platformvm/txs/fee/complexity_calculator.go @@ -164,12 +164,13 @@ var ( errUnsupportedTx = errors.New("unsupported tx type") errUnsupportedOutput = errors.New("unsupported output type") errUnsupportedInput = errors.New("unsupported input type") + errUnsupportedOwner = errors.New("unsupported owner type") ) func TxComplexity(tx txs.UnsignedTx) (fee.Dimensions, error) { c := complexityCalculator{} err := tx.Visit(&c) - return c.complexity, err + return c.output, err } func OutputComplexity(out *avax.TransferableOutput) (fee.Dimensions, error) { @@ -192,9 +193,12 @@ func OutputComplexity(out *avax.TransferableOutput) (fee.Dimensions, error) { } numAddresses := uint64(len(secp256k1Out.Addrs)) - // TODO: Overflow check - complexity[fee.Bandwidth] += numAddresses * ids.ShortIDLen // addresses - return complexity, nil + addressBandwidth, err := math.Mul(numAddresses, ids.ShortIDLen) + if err != nil { + return fee.Dimensions{}, err + } + complexity[fee.Bandwidth], err = math.Add(complexity[fee.Bandwidth], addressBandwidth) + return complexity, err } // InputComplexity returns the complexity an input adds to a transaction. It @@ -219,15 +223,24 @@ func InputComplexity(in *avax.TransferableInput) (fee.Dimensions, error) { } numSignatures := uint64(len(secp256k1In.SigIndices)) - complexity[fee.Bandwidth] += numSignatures * intrinsicSECP256k1FxSignatureBandwidth // TODO: Overflow check - return complexity, nil + signatureBandwidth, err := math.Mul(numSignatures, intrinsicSECP256k1FxSignatureBandwidth) + if err != nil { + return fee.Dimensions{}, err + } + complexity[fee.Bandwidth], err = math.Add(complexity[fee.Bandwidth], signatureBandwidth) + return complexity, err } // OwnerComplexity returns the complexity an owner adds to a transaction. // It does not include the typeID of the owner. -func OwnerComplexity(_ fx.Owner) (fee.Dimensions, error) { +func OwnerComplexity(ownerIntf fx.Owner) (fee.Dimensions, error) { + owner, ok := ownerIntf.(*secp256k1fx.OutputOwners) + if !ok { + return fee.Dimensions{}, errUnsupportedOwner + } + return fee.Dimensions{ - fee.Bandwidth: 0, // TODO + fee.Bandwidth: intrinsicSECP256k1FxOutputOwnersBandwidth, // TODO fee.DBRead: 0, fee.DBWrite: 1, fee.Compute: 0, // TODO @@ -258,8 +271,7 @@ func SignerComplexity(_ signer.Signer) (fee.Dimensions, error) { } type complexityCalculator struct { - // outputs: - complexity fee.Dimensions + output fee.Dimensions } func (*complexityCalculator) AddDelegatorTx(*txs.AddDelegatorTx) error { @@ -303,7 +315,7 @@ func (c *complexityCalculator) AddPermissionlessValidatorTx(tx *txs.AddPermissio if err != nil { return err } - c.complexity, err = IntrinsicAddPermissionlessValidatorTxComplexities.Add( + c.output, err = IntrinsicAddPermissionlessValidatorTxComplexities.Add( baseTxComplexity, signerComplexity, outputsComplexity, @@ -326,7 +338,7 @@ func (c *complexityCalculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissio if err != nil { return err } - c.complexity, err = IntrinsicAddPermissionlessDelegatorTxComplexities.Add( + c.output, err = IntrinsicAddPermissionlessDelegatorTxComplexities.Add( baseTxComplexity, ownerComplexity, outputsComplexity, @@ -343,7 +355,7 @@ func (c *complexityCalculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx if err != nil { return err } - c.complexity, err = IntrinsicAddSubnetValidatorTxComplexities.Add( + c.output, err = IntrinsicAddSubnetValidatorTxComplexities.Add( baseTxComplexity, authComplexity, ) @@ -355,18 +367,30 @@ func (c *complexityCalculator) BaseTx(tx *txs.BaseTx) error { if err != nil { return err } - c.complexity, err = IntrinsicBaseTxComplexities.Add(baseTxComplexity) + c.output, err = IntrinsicBaseTxComplexities.Add(baseTxComplexity) return err } func (c *complexityCalculator) CreateChainTx(tx *txs.CreateChainTx) error { + bandwidth, err := math.Mul(uint64(len(tx.FxIDs)), ids.IDLen) + if err != nil { + return err + } + bandwidth, err = math.Add(bandwidth, uint64(len(tx.ChainName))) + if err != nil { + return err + } + bandwidth, err = math.Add(bandwidth, uint64(len(tx.GenesisData))) + if err != nil { + return err + } dynamicComplexity := fee.Dimensions{ - // TODO: Overflow check - fee.Bandwidth: uint64(len(tx.ChainName) + len(tx.FxIDs)*ids.IDLen + len(tx.GenesisData)), + fee.Bandwidth: bandwidth, fee.DBRead: 0, fee.DBWrite: 0, fee.Compute: 0, } + baseTxComplexity, err := baseTx(&tx.BaseTx) if err != nil { return err @@ -375,7 +399,7 @@ func (c *complexityCalculator) CreateChainTx(tx *txs.CreateChainTx) error { if err != nil { return err } - c.complexity, err = IntrinsicCreateChainTxComplexities.Add( + c.output, err = IntrinsicCreateChainTxComplexities.Add( dynamicComplexity, baseTxComplexity, authComplexity, @@ -392,7 +416,7 @@ func (c *complexityCalculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { if err != nil { return err } - c.complexity, err = IntrinsicCreateSubnetTxComplexities.Add( + c.output, err = IntrinsicCreateSubnetTxComplexities.Add( baseTxComplexity, ownerComplexity, ) @@ -408,7 +432,7 @@ func (c *complexityCalculator) ExportTx(tx *txs.ExportTx) error { if err != nil { return err } - c.complexity, err = IntrinsicExportTxComplexities.Add( + c.output, err = IntrinsicExportTxComplexities.Add( baseTxComplexity, outputsComplexity, ) @@ -424,7 +448,7 @@ func (c *complexityCalculator) ImportTx(tx *txs.ImportTx) error { if err != nil { return err } - c.complexity, err = IntrinsicImportTxComplexities.Add( + c.output, err = IntrinsicImportTxComplexities.Add( baseTxComplexity, inputsComplexity, ) @@ -440,7 +464,7 @@ func (c *complexityCalculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValid if err != nil { return err } - c.complexity, err = IntrinsicRemoveSubnetValidatorTxComplexities.Add( + c.output, err = IntrinsicRemoveSubnetValidatorTxComplexities.Add( baseTxComplexity, authComplexity, ) @@ -460,7 +484,7 @@ func (c *complexityCalculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetO if err != nil { return err } - c.complexity, err = IntrinsicTransferSubnetOwnershipTxComplexities.Add( + c.output, err = IntrinsicTransferSubnetOwnershipTxComplexities.Add( baseTxComplexity, authComplexity, ownerComplexity, diff --git a/vms/platformvm/txs/fee/dynamic_calculator.go b/vms/platformvm/txs/fee/dynamic_calculator.go deleted file mode 100644 index e275480cc326..000000000000 --- a/vms/platformvm/txs/fee/dynamic_calculator.go +++ /dev/null @@ -1,535 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package fee - -import ( - "errors" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/fee" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/platformvm/fx" - "github.com/ava-labs/avalanchego/vms/platformvm/signer" - "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" -) - -const ( - intrinsicValidatorBandwidth = ids.NodeIDLen + // nodeID - wrappers.LongLen + // start - wrappers.LongLen + // end - wrappers.LongLen // weight - - intrinsicSubnetValidatorBandwidth = intrinsicValidatorBandwidth + // validator - ids.IDLen // subnetID - - intrinsicOutputBandwidth = ids.IDLen + // assetID - wrappers.IntLen // output typeID - - intrinsicStakeableLockedOutputBandwidth = wrappers.LongLen + // locktime - wrappers.IntLen // output typeID - - intrinsicSECP256k1FxOutputOwnersBandwidth = wrappers.LongLen + // locktime - wrappers.IntLen + // threshold - wrappers.IntLen // num addresses - - intrinsicSECP256k1FxOutputBandwidth = wrappers.LongLen + // amount - intrinsicSECP256k1FxOutputOwnersBandwidth - - intrinsicInputBandwidth = ids.IDLen + // txID - wrappers.IntLen + // output index - ids.IDLen + // assetID - wrappers.IntLen + // input typeID - wrappers.IntLen // credential typeID - - intrinsicStakeableLockedInputBandwidth = wrappers.LongLen + // locktime - wrappers.IntLen // input typeID - - intrinsicSECP256k1FxInputBandwidth = wrappers.LongLen + // amount - wrappers.IntLen + // num indices - wrappers.IntLen // num signatures - - intrinsicSECP256k1FxSignatureBandwidth = wrappers.IntLen + // signature index - secp256k1.SignatureLen // signature length -) - -var ( - _ txs.Visitor = (*dimensionsCalculator)(nil) - - IntrinsicAddPermissionlessValidatorTxComplexities = fee.Dimensions{ - fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + - intrinsicValidatorBandwidth + // validator - ids.IDLen + // subnetID - wrappers.IntLen + // signer typeID - wrappers.IntLen + // num stake outs - wrappers.IntLen + // validator rewards typeID - wrappers.IntLen + // delegator rewards typeID - wrappers.IntLen, // delegation shares - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - } - IntrinsicAddPermissionlessDelegatorTxComplexities = fee.Dimensions{ - fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + - intrinsicValidatorBandwidth + // validator - ids.IDLen + // subnetID - wrappers.IntLen + // signer typeID - wrappers.IntLen + // num stake outs - wrappers.IntLen, // delegator rewards typeID - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - } - IntrinsicAddSubnetValidatorTxComplexities = fee.Dimensions{ - fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + - intrinsicSubnetValidatorBandwidth + // subnetValidator - wrappers.IntLen, // subnetAuth typeID - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - } - IntrinsicBaseTxComplexities = fee.Dimensions{ - fee.Bandwidth: wrappers.ShortLen + // codecID - wrappers.IntLen + // typeID - wrappers.IntLen + // networkID - ids.IDLen + // blockchainID - wrappers.IntLen + // number of outputs - wrappers.IntLen + // number of inputs - wrappers.IntLen + // length of memo - wrappers.IntLen, // number of credentials - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - } - IntrinsicCreateChainTxComplexities = fee.Dimensions{ - fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + - ids.IDLen + // subnetID - wrappers.ShortLen + // chainName length - ids.IDLen + // vmID - wrappers.IntLen + // num fxIDs - wrappers.IntLen + // genesis length - wrappers.IntLen, // subnetAuth typeID - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - } - IntrinsicCreateSubnetTxComplexities = fee.Dimensions{ - fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + - wrappers.IntLen, // owner typeID - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - } - IntrinsicExportTxComplexities = fee.Dimensions{ - fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + - ids.IDLen + // destination chainID - wrappers.IntLen, // num exported outputs - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - } - IntrinsicImportTxComplexities = fee.Dimensions{ - fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + - ids.IDLen + // source chainID - wrappers.IntLen, // num importing inputs - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - } - IntrinsicRemoveSubnetValidatorTxComplexities = fee.Dimensions{ - fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + - ids.NodeIDLen + // nodeID - ids.IDLen + // subnetID - wrappers.IntLen, // subnetAuth typeID - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - } - IntrinsicTransferSubnetOwnershipTxComplexities = fee.Dimensions{ - fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + - ids.IDLen + // subnetID - wrappers.IntLen + // subnetAuth typeID - wrappers.IntLen, // owner typeID - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - } - - errUnsupportedTx = errors.New("unsupported tx type") - errUnsupportedOutput = errors.New("unsupported output type") - errUnsupportedInput = errors.New("unsupported input type") -) - -func TxComplexity(tx txs.UnsignedTx) (fee.Dimensions, error) { - c := dimensionsCalculator{} - err := tx.Visit(&c) - return c.dimensions, err -} - -func OutputComplexity(out *avax.TransferableOutput) (fee.Dimensions, error) { - complexity := fee.Dimensions{ - fee.Bandwidth: intrinsicOutputBandwidth + intrinsicSECP256k1FxOutputBandwidth, - fee.DBRead: 0, - fee.DBWrite: 1, - fee.Compute: 0, - } - - outIntf := out.Out - if stakeableOut, ok := outIntf.(*stakeable.LockOut); ok { - complexity[fee.Bandwidth] += intrinsicStakeableLockedOutputBandwidth - outIntf = stakeableOut.TransferableOut - } - - secp256k1Out, ok := outIntf.(*secp256k1fx.TransferOutput) - if !ok { - return fee.Dimensions{}, errUnsupportedOutput - } - - numAddresses := uint64(len(secp256k1Out.Addrs)) - // TODO: Overflow check - complexity[fee.Bandwidth] += numAddresses * ids.ShortIDLen // addresses - return complexity, nil -} - -// InputComplexity returns the complexity an input adds to a transaction. It -// includes the complexity that the corresponding credential will add. -func InputComplexity(in *avax.TransferableInput) (fee.Dimensions, error) { - complexity := fee.Dimensions{ - fee.Bandwidth: intrinsicInputBandwidth + intrinsicSECP256k1FxInputBandwidth, - fee.DBRead: 1, - fee.DBWrite: 1, - fee.Compute: 0, // TODO - } - - inIntf := in.In - if stakeableIn, ok := inIntf.(*stakeable.LockIn); ok { - complexity[fee.Bandwidth] += intrinsicStakeableLockedInputBandwidth - inIntf = stakeableIn.TransferableIn - } - - secp256k1In, ok := inIntf.(*secp256k1fx.TransferInput) - if !ok { - return fee.Dimensions{}, errUnsupportedInput - } - - numSignatures := uint64(len(secp256k1In.SigIndices)) - complexity[fee.Bandwidth] += numSignatures * intrinsicSECP256k1FxSignatureBandwidth // TODO: Overflow check - return complexity, nil -} - -// OwnerComplexity returns the complexity an owner adds to a transaction. -// It does not include the typeID of the owner. -func OwnerComplexity(_ fx.Owner) (fee.Dimensions, error) { - return fee.Dimensions{ - fee.Bandwidth: 0, // TODO - fee.DBRead: 0, - fee.DBWrite: 1, - fee.Compute: 0, // TODO - }, nil -} - -// AuthComplexity returns the complexity an authorization adds to a transaction. -// It does not include the typeID of the authorization. -// It does includes the complexity that the corresponding credential will add. -func AuthComplexity(_ verify.Verifiable) (fee.Dimensions, error) { - return fee.Dimensions{ - fee.Bandwidth: 0, // TODO - fee.DBRead: 1, - fee.DBWrite: 0, - fee.Compute: 0, // TODO - }, nil -} - -// SignerComplexity returns the complexity a signer adds to a transaction. -// It does not include the typeID of the signer. -func SignerComplexity(_ signer.Signer) (fee.Dimensions, error) { - return fee.Dimensions{ - fee.Bandwidth: 0, // TODO - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, // TODO - }, nil -} - -type dimensionsCalculator struct { - // outputs: - dimensions fee.Dimensions -} - -func (*dimensionsCalculator) AddDelegatorTx(*txs.AddDelegatorTx) error { - return errUnsupportedTx -} - -func (*dimensionsCalculator) AddValidatorTx(*txs.AddValidatorTx) error { - return errUnsupportedTx -} - -func (*dimensionsCalculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - return errUnsupportedTx -} - -func (*dimensionsCalculator) RewardValidatorTx(*txs.RewardValidatorTx) error { - return errUnsupportedTx -} - -func (*dimensionsCalculator) TransformSubnetTx(*txs.TransformSubnetTx) error { - return errUnsupportedTx -} - -func (c *dimensionsCalculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { - complexity, err := baseTx(&tx.BaseTx) - if err != nil { - return err - } - signerComplexity, err := SignerComplexity(tx.Signer) - if err != nil { - return err - } - complexity, err = complexity.Add(signerComplexity) - if err != nil { - return err - } - for _, out := range tx.StakeOuts { - outputComplexity, err := OutputComplexity(out) - if err != nil { - return err - } - - complexity, err = complexity.Add(outputComplexity) - if err != nil { - return err - } - } - validatorOwnerComplexity, err := OwnerComplexity(tx.ValidatorRewardsOwner) - if err != nil { - return err - } - complexity, err = complexity.Add(validatorOwnerComplexity) - if err != nil { - return err - } - delegatorOwnerComplexity, err := OwnerComplexity(tx.DelegatorRewardsOwner) - if err != nil { - return err - } - complexity, err = complexity.Add(delegatorOwnerComplexity) - if err != nil { - return err - } - c.dimensions, err = complexity.Add(IntrinsicAddPermissionlessDelegatorTxComplexities) - return err -} - -func (c *dimensionsCalculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { - complexity, err := baseTx(&tx.BaseTx) - if err != nil { - return err - } - ownerComplexity, err := OwnerComplexity(tx.DelegationRewardsOwner) - if err != nil { - return err - } - complexity, err = complexity.Add(ownerComplexity) - if err != nil { - return err - } - for _, out := range tx.StakeOuts { - outputComplexity, err := OutputComplexity(out) - if err != nil { - return err - } - - complexity, err = complexity.Add(outputComplexity) - if err != nil { - return err - } - } - c.dimensions, err = complexity.Add(IntrinsicAddPermissionlessDelegatorTxComplexities) - return err -} - -func (c *dimensionsCalculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { - complexity, err := baseTx(&tx.BaseTx) - if err != nil { - return err - } - authComplexity, err := AuthComplexity(tx.SubnetAuth) - if err != nil { - return err - } - complexity, err = complexity.Add(authComplexity) - if err != nil { - return err - } - c.dimensions, err = complexity.Add(IntrinsicAddSubnetValidatorTxComplexities) - return err -} - -func (c *dimensionsCalculator) BaseTx(tx *txs.BaseTx) error { - complexity, err := baseTx(tx) - if err != nil { - return err - } - c.dimensions, err = complexity.Add(IntrinsicBaseTxComplexities) - return err -} - -func (c *dimensionsCalculator) CreateChainTx(tx *txs.CreateChainTx) error { - complexity := fee.Dimensions{ - // TODO: Overflow check - fee.Bandwidth: uint64(len(tx.ChainName) + len(tx.FxIDs)*ids.IDLen + len(tx.GenesisData)), - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - } - baseTxComplexity, err := baseTx(&tx.BaseTx) - if err != nil { - return err - } - complexity, err = complexity.Add(baseTxComplexity) - if err != nil { - return err - } - authComplexity, err := AuthComplexity(tx.SubnetAuth) - if err != nil { - return err - } - complexity, err = complexity.Add(authComplexity) - if err != nil { - return err - } - c.dimensions, err = complexity.Add(IntrinsicCreateChainTxComplexities) - return err -} - -func (c *dimensionsCalculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { - complexity, err := baseTx(&tx.BaseTx) - if err != nil { - return err - } - ownerComplexity, err := OwnerComplexity(tx.Owner) - if err != nil { - return err - } - complexity, err = complexity.Add(ownerComplexity) - if err != nil { - return err - } - c.dimensions, err = complexity.Add(IntrinsicCreateChainTxComplexities) - return err -} - -func (c *dimensionsCalculator) ExportTx(tx *txs.ExportTx) error { - complexity, err := baseTx(&tx.BaseTx) - if err != nil { - return err - } - for _, out := range tx.ExportedOutputs { - outputComplexity, err := OutputComplexity(out) - if err != nil { - return err - } - - complexity, err = complexity.Add(outputComplexity) - if err != nil { - return err - } - } - c.dimensions, err = complexity.Add(IntrinsicExportTxComplexities) - return err -} - -func (c *dimensionsCalculator) ImportTx(tx *txs.ImportTx) error { - complexity, err := baseTx(&tx.BaseTx) - if err != nil { - return err - } - for _, in := range tx.ImportedInputs { - inputComplexity, err := InputComplexity(in) - if err != nil { - return err - } - - complexity, err = complexity.Add(inputComplexity) - if err != nil { - return err - } - } - c.dimensions, err = complexity.Add(IntrinsicImportTxComplexities) - return err -} - -func (c *dimensionsCalculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { - complexity, err := baseTx(&tx.BaseTx) - if err != nil { - return err - } - authComplexity, err := AuthComplexity(tx.SubnetAuth) - if err != nil { - return err - } - complexity, err = complexity.Add(authComplexity) - if err != nil { - return err - } - c.dimensions, err = complexity.Add(IntrinsicRemoveSubnetValidatorTxComplexities) - return err -} - -func (c *dimensionsCalculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { - complexity, err := baseTx(&tx.BaseTx) - if err != nil { - return err - } - authComplexity, err := AuthComplexity(tx.SubnetAuth) - if err != nil { - return err - } - complexity, err = complexity.Add(authComplexity) - if err != nil { - return err - } - ownerComplexity, err := OwnerComplexity(tx.Owner) - if err != nil { - return err - } - complexity, err = complexity.Add(ownerComplexity) - if err != nil { - return err - } - c.dimensions, err = complexity.Add(IntrinsicTransferSubnetOwnershipTxComplexities) - return err -} - -func baseTx(tx *txs.BaseTx) (fee.Dimensions, error) { - var complexity fee.Dimensions - for _, out := range tx.Outs { - outputComplexity, err := OutputComplexity(out) - if err != nil { - return fee.Dimensions{}, err - } - - complexity, err = complexity.Add(outputComplexity) - if err != nil { - return fee.Dimensions{}, err - } - } - for _, in := range tx.Ins { - inputComplexity, err := InputComplexity(in) - if err != nil { - return fee.Dimensions{}, err - } - - complexity, err = complexity.Add(inputComplexity) - if err != nil { - return fee.Dimensions{}, err - } - } - complexity[fee.Bandwidth] += uint64(len(tx.Memo)) - return complexity, nil -} diff --git a/vms/platformvm/txs/fee/dynamic_calculator_test.go b/vms/platformvm/txs/fee/dynamic_calculator_test.go deleted file mode 100644 index 61c35d3f463c..000000000000 --- a/vms/platformvm/txs/fee/dynamic_calculator_test.go +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package fee - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/fee" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" -) - -func TestOutputComplexity(t *testing.T) { - tests := []struct { - name string - out *avax.TransferableOutput - expected fee.Dimensions - expectedErr error - }{ - { - name: "any can spend", - out: &avax.TransferableOutput{ - Out: &secp256k1fx.TransferOutput{ - OutputOwners: secp256k1fx.OutputOwners{ - Addrs: make([]ids.ShortID, 0), - }, - }, - }, - expected: fee.Dimensions{ - fee.Bandwidth: 60, - fee.DBRead: 0, - fee.DBWrite: 1, - fee.Compute: 0, - }, - expectedErr: nil, - }, - { - name: "one owner", - out: &avax.TransferableOutput{ - Out: &secp256k1fx.TransferOutput{ - OutputOwners: secp256k1fx.OutputOwners{ - Addrs: make([]ids.ShortID, 1), - }, - }, - }, - expected: fee.Dimensions{ - fee.Bandwidth: 80, - fee.DBRead: 0, - fee.DBWrite: 1, - fee.Compute: 0, - }, - expectedErr: nil, - }, - { - name: "three owners", - out: &avax.TransferableOutput{ - Out: &secp256k1fx.TransferOutput{ - OutputOwners: secp256k1fx.OutputOwners{ - Addrs: make([]ids.ShortID, 3), - }, - }, - }, - expected: fee.Dimensions{ - fee.Bandwidth: 120, - fee.DBRead: 0, - fee.DBWrite: 1, - fee.Compute: 0, - }, - expectedErr: nil, - }, - { - name: "locked stakeable", - out: &avax.TransferableOutput{ - Out: &stakeable.LockOut{ - TransferableOut: &secp256k1fx.TransferOutput{ - OutputOwners: secp256k1fx.OutputOwners{ - Addrs: make([]ids.ShortID, 3), - }, - }, - }, - }, - expected: fee.Dimensions{ - fee.Bandwidth: 132, - fee.DBRead: 0, - fee.DBWrite: 1, - fee.Compute: 0, - }, - expectedErr: nil, - }, - { - name: "invalid output type", - out: &avax.TransferableOutput{ - Out: nil, - }, - expected: fee.Dimensions{ - fee.Bandwidth: 0, - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - }, - expectedErr: errUnsupportedOutput, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - require := require.New(t) - - actual, err := OutputComplexity(test.out) - require.ErrorIs(err, test.expectedErr) - require.Equal(test.expected, actual) - - if err != nil { - return - } - - bytes, err := txs.Codec.Marshal(txs.CodecVersion, test.out) - require.NoError(err) - - numBytesWithoutCodecVersion := uint64(len(bytes) - wrappers.ShortLen) - require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) - }) - } -} - -func TestInputComplexity(t *testing.T) { - tests := []struct { - name string - in *avax.TransferableInput - cred verify.Verifiable - expected fee.Dimensions - expectedErr error - }{ - { - name: "any can spend", - in: &avax.TransferableInput{ - In: &secp256k1fx.TransferInput{ - Input: secp256k1fx.Input{ - SigIndices: make([]uint32, 0), - }, - }, - }, - cred: &secp256k1fx.Credential{ - Sigs: make([][secp256k1.SignatureLen]byte, 0), - }, - expected: fee.Dimensions{ - fee.Bandwidth: 92, - fee.DBRead: 1, - fee.DBWrite: 1, - fee.Compute: 0, // TODO: implement - }, - expectedErr: nil, - }, - { - name: "one owner", - in: &avax.TransferableInput{ - In: &secp256k1fx.TransferInput{ - Input: secp256k1fx.Input{ - SigIndices: make([]uint32, 1), - }, - }, - }, - cred: &secp256k1fx.Credential{ - Sigs: make([][secp256k1.SignatureLen]byte, 1), - }, - expected: fee.Dimensions{ - fee.Bandwidth: 161, - fee.DBRead: 1, - fee.DBWrite: 1, - fee.Compute: 0, // TODO: implement - }, - expectedErr: nil, - }, - { - name: "three owners", - in: &avax.TransferableInput{ - In: &secp256k1fx.TransferInput{ - Input: secp256k1fx.Input{ - SigIndices: make([]uint32, 3), - }, - }, - }, - cred: &secp256k1fx.Credential{ - Sigs: make([][secp256k1.SignatureLen]byte, 3), - }, - expected: fee.Dimensions{ - fee.Bandwidth: 299, - fee.DBRead: 1, - fee.DBWrite: 1, - fee.Compute: 0, // TODO: implement - }, - expectedErr: nil, - }, - { - name: "locked stakeable", - in: &avax.TransferableInput{ - In: &stakeable.LockIn{ - TransferableIn: &secp256k1fx.TransferInput{ - Input: secp256k1fx.Input{ - SigIndices: make([]uint32, 3), - }, - }, - }, - }, - cred: &secp256k1fx.Credential{ - Sigs: make([][secp256k1.SignatureLen]byte, 3), - }, - expected: fee.Dimensions{ - fee.Bandwidth: 311, - fee.DBRead: 1, - fee.DBWrite: 1, - fee.Compute: 0, // TODO: implement - }, - expectedErr: nil, - }, - { - name: "invalid input type", - in: &avax.TransferableInput{ - In: nil, - }, - cred: nil, - expected: fee.Dimensions{ - fee.Bandwidth: 0, - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, - }, - expectedErr: errUnsupportedInput, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - require := require.New(t) - - actual, err := InputComplexity(test.in) - require.ErrorIs(err, test.expectedErr) - require.Equal(test.expected, actual) - - if err != nil { - return - } - - inputBytes, err := txs.Codec.Marshal(txs.CodecVersion, test.in) - require.NoError(err) - - cred := test.cred - credentialBytes, err := txs.Codec.Marshal(txs.CodecVersion, &cred) - require.NoError(err) - - numBytesWithoutCodecVersion := uint64(len(inputBytes) + len(credentialBytes) - 2*wrappers.ShortLen) - require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) - }) - } -} From 446a210170db0a90bdee17ea19f022dff903a019 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 19:30:01 -0400 Subject: [PATCH 077/100] wip --- .../txs/fee/complexity_calculator.go | 118 ++++-- .../txs/fee/complexity_calculator_test.go | 358 ++++++++++++++++++ 2 files changed, 440 insertions(+), 36 deletions(-) diff --git a/vms/platformvm/txs/fee/complexity_calculator.go b/vms/platformvm/txs/fee/complexity_calculator.go index 2a0a6b175a17..afb87baa0c98 100644 --- a/vms/platformvm/txs/fee/complexity_calculator.go +++ b/vms/platformvm/txs/fee/complexity_calculator.go @@ -7,6 +7,7 @@ import ( "errors" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/wrappers" @@ -51,12 +52,17 @@ const ( intrinsicStakeableLockedInputBandwidth = wrappers.LongLen + // locktime wrappers.IntLen // input typeID - intrinsicSECP256k1FxInputBandwidth = wrappers.LongLen + // amount - wrappers.IntLen + // num indices + intrinsicSECP256k1FxInputBandwidth = wrappers.IntLen + // num indices wrappers.IntLen // num signatures + intrinsicSECP256k1FxTransferableInputBandwidth = wrappers.LongLen + // amount + intrinsicSECP256k1FxInputBandwidth + intrinsicSECP256k1FxSignatureBandwidth = wrappers.IntLen + // signature index secp256k1.SignatureLen // signature length + + intrinsicPoPBandwidth = bls.PublicKeyLen + // public key + bls.SignatureLen // signature ) var ( @@ -71,27 +77,27 @@ var ( wrappers.IntLen + // validator rewards typeID wrappers.IntLen + // delegator rewards typeID wrappers.IntLen, // delegation shares - fee.DBRead: 0, - fee.DBWrite: 0, + fee.DBRead: 1, + fee.DBWrite: 1, fee.Compute: 0, } IntrinsicAddPermissionlessDelegatorTxComplexities = fee.Dimensions{ fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + intrinsicValidatorBandwidth + // validator ids.IDLen + // subnetID - wrappers.IntLen + // signer typeID wrappers.IntLen + // num stake outs wrappers.IntLen, // delegator rewards typeID - fee.DBRead: 0, + fee.DBRead: 1, fee.DBWrite: 0, fee.Compute: 0, } IntrinsicAddSubnetValidatorTxComplexities = fee.Dimensions{ fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + intrinsicSubnetValidatorBandwidth + // subnetValidator - wrappers.IntLen, // subnetAuth typeID - fee.DBRead: 0, - fee.DBWrite: 0, + wrappers.IntLen + // subnetAuth typeID + wrappers.IntLen, // subnetAuthCredential typeID + fee.DBRead: 2, + fee.DBWrite: 1, fee.Compute: 0, } IntrinsicBaseTxComplexities = fee.Dimensions{ @@ -114,16 +120,17 @@ var ( ids.IDLen + // vmID wrappers.IntLen + // num fxIDs wrappers.IntLen + // genesis length - wrappers.IntLen, // subnetAuth typeID - fee.DBRead: 0, - fee.DBWrite: 0, + wrappers.IntLen + // subnetAuth typeID + wrappers.IntLen, // subnetAuthCredential typeID + fee.DBRead: 1, + fee.DBWrite: 1, fee.Compute: 0, } IntrinsicCreateSubnetTxComplexities = fee.Dimensions{ fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + wrappers.IntLen, // owner typeID fee.DBRead: 0, - fee.DBWrite: 0, + fee.DBWrite: 1, fee.Compute: 0, } IntrinsicExportTxComplexities = fee.Dimensions{ @@ -146,18 +153,20 @@ var ( fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + ids.NodeIDLen + // nodeID ids.IDLen + // subnetID - wrappers.IntLen, // subnetAuth typeID - fee.DBRead: 0, - fee.DBWrite: 0, + wrappers.IntLen + // subnetAuth typeID + wrappers.IntLen, // subnetAuthCredential typeID + fee.DBRead: 2, + fee.DBWrite: 1, fee.Compute: 0, } IntrinsicTransferSubnetOwnershipTxComplexities = fee.Dimensions{ fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + ids.IDLen + // subnetID wrappers.IntLen + // subnetAuth typeID - wrappers.IntLen, // owner typeID - fee.DBRead: 0, - fee.DBWrite: 0, + wrappers.IntLen + // owner typeID + wrappers.IntLen, // subnetAuthCredential typeID + fee.DBRead: 1, + fee.DBWrite: 1, fee.Compute: 0, } @@ -165,6 +174,8 @@ var ( errUnsupportedOutput = errors.New("unsupported output type") errUnsupportedInput = errors.New("unsupported input type") errUnsupportedOwner = errors.New("unsupported owner type") + errUnsupportedAuth = errors.New("unsupported auth type") + errUnsupportedSigner = errors.New("unsupported signer type") ) func TxComplexity(tx txs.UnsignedTx) (fee.Dimensions, error) { @@ -201,11 +212,11 @@ func OutputComplexity(out *avax.TransferableOutput) (fee.Dimensions, error) { return complexity, err } -// InputComplexity returns the complexity an input adds to a transaction. It -// includes the complexity that the corresponding credential will add. +// InputComplexity returns the complexity an input adds to a transaction. +// It includes the complexity that the corresponding credential will add. func InputComplexity(in *avax.TransferableInput) (fee.Dimensions, error) { complexity := fee.Dimensions{ - fee.Bandwidth: intrinsicInputBandwidth + intrinsicSECP256k1FxInputBandwidth, + fee.Bandwidth: intrinsicInputBandwidth + intrinsicSECP256k1FxTransferableInputBandwidth, fee.DBRead: 1, fee.DBWrite: 1, fee.Compute: 0, // TODO @@ -239,35 +250,70 @@ func OwnerComplexity(ownerIntf fx.Owner) (fee.Dimensions, error) { return fee.Dimensions{}, errUnsupportedOwner } + numAddresses := uint64(len(owner.Addrs)) + addressBandwidth, err := math.Mul(numAddresses, ids.ShortIDLen) + if err != nil { + return fee.Dimensions{}, err + } + + bandwidth, err := math.Add(addressBandwidth, intrinsicSECP256k1FxOutputOwnersBandwidth) + if err != nil { + return fee.Dimensions{}, err + } + return fee.Dimensions{ - fee.Bandwidth: intrinsicSECP256k1FxOutputOwnersBandwidth, // TODO + fee.Bandwidth: bandwidth, fee.DBRead: 0, - fee.DBWrite: 1, - fee.Compute: 0, // TODO + fee.DBWrite: 0, + fee.Compute: 0, }, nil } // AuthComplexity returns the complexity an authorization adds to a transaction. // It does not include the typeID of the authorization. // It does includes the complexity that the corresponding credential will add. -func AuthComplexity(_ verify.Verifiable) (fee.Dimensions, error) { +// It does not include the typeID of the credential. +func AuthComplexity(authIntf verify.Verifiable) (fee.Dimensions, error) { + auth, ok := authIntf.(*secp256k1fx.Input) + if !ok { + return fee.Dimensions{}, errUnsupportedAuth + } + + numSignatures := uint64(len(auth.SigIndices)) + signatureBandwidth, err := math.Mul(numSignatures, intrinsicSECP256k1FxSignatureBandwidth) + if err != nil { + return fee.Dimensions{}, err + } + + bandwidth, err := math.Add(signatureBandwidth, intrinsicSECP256k1FxInputBandwidth) + if err != nil { + return fee.Dimensions{}, err + } + return fee.Dimensions{ - fee.Bandwidth: 0, // TODO - fee.DBRead: 1, + fee.Bandwidth: bandwidth, + fee.DBRead: 0, fee.DBWrite: 0, - fee.Compute: 0, // TODO + fee.Compute: 0, }, nil } // SignerComplexity returns the complexity a signer adds to a transaction. // It does not include the typeID of the signer. -func SignerComplexity(_ signer.Signer) (fee.Dimensions, error) { - return fee.Dimensions{ - fee.Bandwidth: 0, // TODO - fee.DBRead: 0, - fee.DBWrite: 0, - fee.Compute: 0, // TODO - }, nil +func SignerComplexity(s signer.Signer) (fee.Dimensions, error) { + switch s.(type) { + case *signer.Empty: + return fee.Dimensions{}, nil + case *signer.ProofOfPossession: + return fee.Dimensions{ + fee.Bandwidth: intrinsicPoPBandwidth, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + }, nil + default: + return fee.Dimensions{}, errUnsupportedSigner + } } type complexityCalculator struct { diff --git a/vms/platformvm/txs/fee/complexity_calculator_test.go b/vms/platformvm/txs/fee/complexity_calculator_test.go index 61c35d3f463c..b5bbcd33e907 100644 --- a/vms/platformvm/txs/fee/complexity_calculator_test.go +++ b/vms/platformvm/txs/fee/complexity_calculator_test.go @@ -4,6 +4,7 @@ package fee import ( + "encoding/hex" "testing" "github.com/stretchr/testify/require" @@ -14,11 +15,139 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/fee" "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) +func TestTxComplexity(t *testing.T) { + tests := []struct { + name string + tx string + expected fee.Dimensions + }{ + { + name: "AddPermissionlessValidatorTx", + tx: "00000000001900003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba8b1e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001043c91e9d508169329034e2a68110427a311f945efc53ed3f3493d335b393fd100000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f263d53e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae35f0000000066b692df000001d1a94a200000000000000000000000000000000000000000000000000000000000000000000000001ca3783a891cb41cadbfcf456da149f30e7af972677a162b984bef0779f254baac51ec042df1781d1295df80fb41c801269731fc6c25e1e5940dc3cb8509e30348fa712742cfdc83678acc9f95908eb98b89b28802fb559b4a2a6ff3216707c07f0ceb0b45a95f4f9a9540bbd3331d8ab4f233bffa4abb97fad9d59a1695f31b92a2b89e365facf7ab8c30de7c4a496d1e00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0007a12000000001000000090000000135f122f90bcece0d6c43e07fed1829578a23bc1734f8a4b46203f9f192ea1aec7526f3dca8fddec7418988615e6543012452bae1544275aae435313ec006ec9000", + expected: fee.Dimensions{ + fee.Bandwidth: 691, + fee.DBRead: 2, + fee.DBWrite: 4, + fee.Compute: 0, + }, + }, + { + name: "AddPermissionlessDelegatorTx", + tx: "00000000001a00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1140fe00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000017d199179744b3b82d0071c83c2fb7dd6b95a2cdbe9dde295e0ae4f8c2287370300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba8b1e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae6080000000066ad5b08000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000100000009000000012261556f74a29f02ffc2725a567db2c81f75d0892525dbebaa1cf8650534cc70061123533a9553184cb02d899943ff0bf0b39c77b173c133854bc7c8bc7ab9a400", + expected: fee.Dimensions{ + fee.Bandwidth: 499, + fee.DBRead: 2, + fee.DBWrite: 3, + fee.Compute: 0, + }, + }, + { + name: "AddSubnetValidatorTx", + tx: "00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1131bbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000138f94d1a0514eaabdaf4c52cad8d62b26cee61eaa951f5b75a5e57c2ee3793c800000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1140fe00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae7c90000000066ad5cc9000000000000c13797ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000200000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb60000000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb600", + expected: fee.Dimensions{ + fee.Bandwidth: 460, + fee.DBRead: 3, + fee.DBWrite: 3, + fee.Compute: 0, + }, + }, + { + name: "BaseTx", + tx: "00000000002200003039000000000000000000000000000000000000000000000000000000000000000000000002dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fadbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834ed587af80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001fa4ff39749d44f29563ed9da03193d4a19ef419da4ce326594817ca266fda5ed00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1131bbc00000000100000000000000000000000100000009000000014a7b54c63dd25a532b5fe5045b6d0e1db876e067422f12c9c327333c2c792d9273405ac8bbbc2cce549bbd3d0f9274242085ee257adfdb859b0f8d55bdd16fb000", + expected: fee.Dimensions{ + fee.Bandwidth: 399, + fee.DBRead: 1, + fee.DBWrite: 3, + fee.Compute: 0, + }, + }, + { + name: "CreateChainTx", + tx: "00000000000f00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263d53e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000197ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269cb1f0000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400096c65742074686572657873766d00000000000000000000000000000000000000000000000000000000000000000000002a000000000000669ae21e000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cffffffffffffffff0000000a0000000100000000000000020000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f8010000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f801", + expected: fee.Dimensions{ + fee.Bandwidth: 509, + fee.DBRead: 2, + fee.DBWrite: 3, + fee.Compute: 0, + }, + }, + { + name: "CreateSubnetTx", + tx: "00000000001000003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f269cb1f00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc100000000000100000000000000000000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000010000000900000001b3c905e7227e619bd6b98c164a8b2b4a8ce89ac5142bbb1c42b139df2d17fd777c4c76eae66cef3de90800e567407945f58d918978f734f8ca4eda6923c78eb201", + expected: fee.Dimensions{ + fee.Bandwidth: 339, + fee.DBRead: 1, + fee.DBWrite: 3, + fee.Compute: 0, + }, + }, + { + name: "ExportTx", + tx: "00000000001200003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99dda340000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001f62c03574790b6a31a988f90c3e91c50fdd6f5d93baf200057463021ff23ec5c00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834ed587af800000000100000000000000009d0775f450604bd2fbc49ce0c5c1c6dfeb2dc2acb8c92c26eeae6e6df4502b1900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fa000000010000000900000001129a07c92045e0b9d0a203fcb5b53db7890fabce1397ff6a2ad16c98ef0151891ae72949d240122abf37b1206b95e05ff171df164a98e6bdf2384432eac2c30200", + expected: fee.Dimensions{ + fee.Bandwidth: 435, + fee.DBRead: 1, + fee.DBWrite: 3, + fee.Compute: 0, + }, + }, + { + name: "ImportTx", + tx: "00000000001100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b8b87c0000000000000000100000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000000000000d891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf0000000163684415710a7d65f4ccb095edff59f897106b94d38937fc60e3ffc29892833b00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000003b9aca00000000010000000000000001000000090000000148ea12cb0950e47d852b99765208f5a811d3c8a47fa7b23fd524bd970019d157029f973abb91c31a146752ef8178434deb331db24c8dca5e61c961e6ac2f3b6700", + expected: fee.Dimensions{ + fee.Bandwidth: 335, + fee.DBRead: 1, + fee.DBWrite: 2, + fee.Compute: 0, + }, + }, + { + name: "RemoveSubnetValidatorTx", + tx: "00000000001700003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99ce6100000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001cd4569cfd044d50636fa597c700710403b3b52d3b75c30c542a111cc52c911ec00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99dda340000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a0000000100000000000000020000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d010000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d01", + expected: fee.Dimensions{ + fee.Bandwidth: 436, + fee.DBRead: 3, + fee.DBWrite: 3, + fee.Compute: 0, + }, + }, + { + name: "TransferSubnetOwnershipTx", + tx: "00000000002100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99bf1ec0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000018f6e5f2840e34f9a375f35627a44bb0b9974285d280dc3220aa9489f97b17ebd00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99ce610000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000b00000000000000000000000000000000000000020000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f010000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f01", + expected: fee.Dimensions{ + fee.Bandwidth: 436, + fee.DBRead: 2, + fee.DBWrite: 3, + fee.Compute: 0, + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + txBytes, err := hex.DecodeString(test.tx) + require.NoError(err) + + tx, err := txs.Parse(txs.Codec, txBytes) + require.NoError(err) + + actual, err := TxComplexity(tx.Unsigned) + require.NoError(err) + require.Equal(test.expected, actual) + + require.Len(txBytes, int(actual[fee.Bandwidth])) + }) + } +} + func TestOutputComplexity(t *testing.T) { tests := []struct { name string @@ -260,3 +389,232 @@ func TestInputComplexity(t *testing.T) { }) } } + +func TestOwnerComplexity(t *testing.T) { + tests := []struct { + name string + owner fx.Owner + expected fee.Dimensions + expectedErr error + }{ + { + name: "any can spend", + owner: &secp256k1fx.OutputOwners{ + Addrs: make([]ids.ShortID, 0), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 16, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "one owner", + owner: &secp256k1fx.OutputOwners{ + Addrs: make([]ids.ShortID, 1), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 36, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "three owners", + owner: &secp256k1fx.OutputOwners{ + Addrs: make([]ids.ShortID, 3), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 76, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "invalid owner type", + owner: nil, + expected: fee.Dimensions{}, + expectedErr: errUnsupportedOwner, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + actual, err := OwnerComplexity(test.owner) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + + if err != nil { + return + } + + ownerBytes, err := txs.Codec.Marshal(txs.CodecVersion, test.owner) + require.NoError(err) + + numBytesWithoutCodecVersion := uint64(len(ownerBytes) - wrappers.ShortLen) + require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) + }) + } +} + +func TestAuthComplexity(t *testing.T) { + tests := []struct { + name string + auth verify.Verifiable + cred verify.Verifiable + expected fee.Dimensions + expectedErr error + }{ + { + name: "any can spend", + auth: &secp256k1fx.Input{ + SigIndices: make([]uint32, 0), + }, + cred: &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, 0), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 8, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "one owner", + auth: &secp256k1fx.Input{ + SigIndices: make([]uint32, 1), + }, + cred: &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, 1), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 77, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "three owners", + auth: &secp256k1fx.Input{ + SigIndices: make([]uint32, 3), + }, + cred: &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, 3), + }, + expected: fee.Dimensions{ + fee.Bandwidth: 215, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "invalid auth type", + auth: nil, + cred: nil, + expected: fee.Dimensions{ + fee.Bandwidth: 0, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, // TODO: implement + }, + expectedErr: errUnsupportedAuth, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + actual, err := AuthComplexity(test.auth) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + + if err != nil { + return + } + + authBytes, err := txs.Codec.Marshal(txs.CodecVersion, test.auth) + require.NoError(err) + + credentialBytes, err := txs.Codec.Marshal(txs.CodecVersion, test.cred) + require.NoError(err) + + numBytesWithoutCodecVersion := uint64(len(authBytes) + len(credentialBytes) - 2*wrappers.ShortLen) + require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) + }) + } +} + +func TestSignerComplexity(t *testing.T) { + tests := []struct { + name string + signer signer.Signer + expected fee.Dimensions + expectedErr error + }{ + { + name: "empty", + signer: &signer.Empty{}, + expected: fee.Dimensions{ + fee.Bandwidth: 0, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + }, + expectedErr: nil, + }, + { + name: "bls pop", + signer: &signer.ProofOfPossession{}, + expected: fee.Dimensions{ + fee.Bandwidth: 144, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, // TODO: implement + }, + expectedErr: nil, + }, + { + name: "invalid signer type", + signer: nil, + expected: fee.Dimensions{ + fee.Bandwidth: 0, + fee.DBRead: 0, + fee.DBWrite: 0, + fee.Compute: 0, + }, + expectedErr: errUnsupportedSigner, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + actual, err := SignerComplexity(test.signer) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expected, actual) + + if err != nil { + return + } + + signerBytes, err := txs.Codec.Marshal(txs.CodecVersion, test.signer) + require.NoError(err) + + numBytesWithoutCodecVersion := uint64(len(signerBytes) - wrappers.ShortLen) + require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) + }) + } +} From 70331a5c956871e0cd3211e3dffd712183632ce9 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 19:41:06 -0400 Subject: [PATCH 078/100] nits --- ...complexity_calculator.go => complexity.go} | 39 ++++++++++--------- ..._calculator_test.go => complexity_test.go} | 7 ++++ vms/platformvm/txs/fee/static_calculator.go | 2 +- 3 files changed, 28 insertions(+), 20 deletions(-) rename vms/platformvm/txs/fee/{complexity_calculator.go => complexity.go} (91%) rename vms/platformvm/txs/fee/{complexity_calculator_test.go => complexity_test.go} (99%) diff --git a/vms/platformvm/txs/fee/complexity_calculator.go b/vms/platformvm/txs/fee/complexity.go similarity index 91% rename from vms/platformvm/txs/fee/complexity_calculator.go rename to vms/platformvm/txs/fee/complexity.go index afb87baa0c98..fda4c01fec9f 100644 --- a/vms/platformvm/txs/fee/complexity_calculator.go +++ b/vms/platformvm/txs/fee/complexity.go @@ -66,7 +66,7 @@ const ( ) var ( - _ txs.Visitor = (*complexityCalculator)(nil) + _ txs.Visitor = (*complexityVisitor)(nil) IntrinsicAddPermissionlessValidatorTxComplexities = fee.Dimensions{ fee.Bandwidth: IntrinsicBaseTxComplexities[fee.Bandwidth] + @@ -178,8 +178,9 @@ var ( errUnsupportedSigner = errors.New("unsupported signer type") ) +// TODO: Implement compute complexity func TxComplexity(tx txs.UnsignedTx) (fee.Dimensions, error) { - c := complexityCalculator{} + c := complexityVisitor{} err := tx.Visit(&c) return c.output, err } @@ -219,7 +220,7 @@ func InputComplexity(in *avax.TransferableInput) (fee.Dimensions, error) { fee.Bandwidth: intrinsicInputBandwidth + intrinsicSECP256k1FxTransferableInputBandwidth, fee.DBRead: 1, fee.DBWrite: 1, - fee.Compute: 0, // TODO + fee.Compute: 0, } inIntf := in.In @@ -316,31 +317,31 @@ func SignerComplexity(s signer.Signer) (fee.Dimensions, error) { } } -type complexityCalculator struct { +type complexityVisitor struct { output fee.Dimensions } -func (*complexityCalculator) AddDelegatorTx(*txs.AddDelegatorTx) error { +func (*complexityVisitor) AddDelegatorTx(*txs.AddDelegatorTx) error { return errUnsupportedTx } -func (*complexityCalculator) AddValidatorTx(*txs.AddValidatorTx) error { +func (*complexityVisitor) AddValidatorTx(*txs.AddValidatorTx) error { return errUnsupportedTx } -func (*complexityCalculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { +func (*complexityVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { return errUnsupportedTx } -func (*complexityCalculator) RewardValidatorTx(*txs.RewardValidatorTx) error { +func (*complexityVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { return errUnsupportedTx } -func (*complexityCalculator) TransformSubnetTx(*txs.TransformSubnetTx) error { +func (*complexityVisitor) TransformSubnetTx(*txs.TransformSubnetTx) error { return errUnsupportedTx } -func (c *complexityCalculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { +func (c *complexityVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { baseTxComplexity, err := baseTx(&tx.BaseTx) if err != nil { return err @@ -371,7 +372,7 @@ func (c *complexityCalculator) AddPermissionlessValidatorTx(tx *txs.AddPermissio return err } -func (c *complexityCalculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { +func (c *complexityVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { baseTxComplexity, err := baseTx(&tx.BaseTx) if err != nil { return err @@ -392,7 +393,7 @@ func (c *complexityCalculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissio return err } -func (c *complexityCalculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { +func (c *complexityVisitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { baseTxComplexity, err := baseTx(&tx.BaseTx) if err != nil { return err @@ -408,7 +409,7 @@ func (c *complexityCalculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx return err } -func (c *complexityCalculator) BaseTx(tx *txs.BaseTx) error { +func (c *complexityVisitor) BaseTx(tx *txs.BaseTx) error { baseTxComplexity, err := baseTx(tx) if err != nil { return err @@ -417,7 +418,7 @@ func (c *complexityCalculator) BaseTx(tx *txs.BaseTx) error { return err } -func (c *complexityCalculator) CreateChainTx(tx *txs.CreateChainTx) error { +func (c *complexityVisitor) CreateChainTx(tx *txs.CreateChainTx) error { bandwidth, err := math.Mul(uint64(len(tx.FxIDs)), ids.IDLen) if err != nil { return err @@ -453,7 +454,7 @@ func (c *complexityCalculator) CreateChainTx(tx *txs.CreateChainTx) error { return err } -func (c *complexityCalculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { +func (c *complexityVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { baseTxComplexity, err := baseTx(&tx.BaseTx) if err != nil { return err @@ -469,7 +470,7 @@ func (c *complexityCalculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { return err } -func (c *complexityCalculator) ExportTx(tx *txs.ExportTx) error { +func (c *complexityVisitor) ExportTx(tx *txs.ExportTx) error { baseTxComplexity, err := baseTx(&tx.BaseTx) if err != nil { return err @@ -485,7 +486,7 @@ func (c *complexityCalculator) ExportTx(tx *txs.ExportTx) error { return err } -func (c *complexityCalculator) ImportTx(tx *txs.ImportTx) error { +func (c *complexityVisitor) ImportTx(tx *txs.ImportTx) error { baseTxComplexity, err := baseTx(&tx.BaseTx) if err != nil { return err @@ -501,7 +502,7 @@ func (c *complexityCalculator) ImportTx(tx *txs.ImportTx) error { return err } -func (c *complexityCalculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { +func (c *complexityVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { baseTxComplexity, err := baseTx(&tx.BaseTx) if err != nil { return err @@ -517,7 +518,7 @@ func (c *complexityCalculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValid return err } -func (c *complexityCalculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { +func (c *complexityVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { baseTxComplexity, err := baseTx(&tx.BaseTx) if err != nil { return err diff --git a/vms/platformvm/txs/fee/complexity_calculator_test.go b/vms/platformvm/txs/fee/complexity_test.go similarity index 99% rename from vms/platformvm/txs/fee/complexity_calculator_test.go rename to vms/platformvm/txs/fee/complexity_test.go index b5bbcd33e907..89b63b44d19c 100644 --- a/vms/platformvm/txs/fee/complexity_calculator_test.go +++ b/vms/platformvm/txs/fee/complexity_test.go @@ -5,6 +5,7 @@ package fee import ( "encoding/hex" + "encoding/json" "testing" "github.com/stretchr/testify/require" @@ -139,6 +140,12 @@ func TestTxComplexity(t *testing.T) { tx, err := txs.Parse(txs.Codec, txBytes) require.NoError(err) + // If the test fails, logging the transaction can be helpful for + // debugging. + txJSON, err := json.MarshalIndent(tx, "", "\t") + require.NoError(err) + t.Log(string(txJSON)) + actual, err := TxComplexity(tx.Unsigned) require.NoError(err) require.Equal(test.expected, actual) diff --git a/vms/platformvm/txs/fee/static_calculator.go b/vms/platformvm/txs/fee/static_calculator.go index 7bfb5cf799a0..1e051e2cdcd7 100644 --- a/vms/platformvm/txs/fee/static_calculator.go +++ b/vms/platformvm/txs/fee/static_calculator.go @@ -39,7 +39,7 @@ type staticCalculator struct { } func (c *staticCalculator) CalculateFee(tx *txs.Tx) (uint64, error) { - c.fee = 0 // zero fee among different calculateFee invocations (unlike gas which gets cumulated) + c.fee = 0 // zero fee among different calculateFee invocations err := tx.Unsigned.Visit(c) return c.fee, err } From f3a663812c19f383f7a8ee5b759a46c715fcf94d Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 19:43:19 -0400 Subject: [PATCH 079/100] revert diff --- .vscode/settings.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 44fc7c3d9475..0abd38ef2982 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,7 +8,4 @@ ], }, "go.testTags": "test", - "cSpell.words": [ - "Stakeable" - ], } \ No newline at end of file From 38f435055a3b70755337f77b0319f09c6019f320 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 19:44:36 -0400 Subject: [PATCH 080/100] revert diff --- vms/components/fee/dimensions.go | 8 ++++---- vms/platformvm/txs/fee/static_calculator.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vms/components/fee/dimensions.go b/vms/components/fee/dimensions.go index 7c155947d9a8..3db1db01b3d2 100644 --- a/vms/components/fee/dimensions.go +++ b/vms/components/fee/dimensions.go @@ -6,10 +6,10 @@ package fee import "github.com/ava-labs/avalanchego/utils/math" const ( - Bandwidth Dimension = iota // bytes - DBRead // num reads - DBWrite // num writes (includes deletes) - Compute // time + Bandwidth Dimension = iota + DBRead + DBWrite // includes deletes + Compute NumDimensions = iota ) diff --git a/vms/platformvm/txs/fee/static_calculator.go b/vms/platformvm/txs/fee/static_calculator.go index 1e051e2cdcd7..7bfb5cf799a0 100644 --- a/vms/platformvm/txs/fee/static_calculator.go +++ b/vms/platformvm/txs/fee/static_calculator.go @@ -39,7 +39,7 @@ type staticCalculator struct { } func (c *staticCalculator) CalculateFee(tx *txs.Tx) (uint64, error) { - c.fee = 0 // zero fee among different calculateFee invocations + c.fee = 0 // zero fee among different calculateFee invocations (unlike gas which gets cumulated) err := tx.Unsigned.Visit(c) return c.fee, err } From 6c3c96efb3b4e3cf1fe5eba5b879c0d42bf13e41 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 19 Jul 2024 19:48:09 -0400 Subject: [PATCH 081/100] reduce diff --- vms/platformvm/txs/fee/calculator_test.go | 4 ++-- vms/platformvm/txs/fee/complexity.go | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index fa5c4371add9..454072e9df8d 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -148,7 +148,7 @@ func TestTxFees(t *testing.T) { { name: "BaseTx pre EUpgrade", chainTime: preEUpgradeTime, - unsignedTx: baseTxT, + unsignedTx: baseTx, expected: feeTestsDefaultCfg.TxFee, }, { @@ -240,7 +240,7 @@ func addPermissionlessDelegatorTx(subnetID ids.ID) txs.UnsignedTx { } } -func baseTxT() txs.UnsignedTx { +func baseTx() txs.UnsignedTx { return &txs.BaseTx{} } diff --git a/vms/platformvm/txs/fee/complexity.go b/vms/platformvm/txs/fee/complexity.go index fda4c01fec9f..2af783b55312 100644 --- a/vms/platformvm/txs/fee/complexity.go +++ b/vms/platformvm/txs/fee/complexity.go @@ -342,7 +342,7 @@ func (*complexityVisitor) TransformSubnetTx(*txs.TransformSubnetTx) error { } func (c *complexityVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { - baseTxComplexity, err := baseTx(&tx.BaseTx) + baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err } @@ -373,7 +373,7 @@ func (c *complexityVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionle } func (c *complexityVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { - baseTxComplexity, err := baseTx(&tx.BaseTx) + baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err } @@ -394,7 +394,7 @@ func (c *complexityVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionle } func (c *complexityVisitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { - baseTxComplexity, err := baseTx(&tx.BaseTx) + baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err } @@ -410,7 +410,7 @@ func (c *complexityVisitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) e } func (c *complexityVisitor) BaseTx(tx *txs.BaseTx) error { - baseTxComplexity, err := baseTx(tx) + baseTxComplexity, err := baseTxComplexity(tx) if err != nil { return err } @@ -438,7 +438,7 @@ func (c *complexityVisitor) CreateChainTx(tx *txs.CreateChainTx) error { fee.Compute: 0, } - baseTxComplexity, err := baseTx(&tx.BaseTx) + baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err } @@ -455,7 +455,7 @@ func (c *complexityVisitor) CreateChainTx(tx *txs.CreateChainTx) error { } func (c *complexityVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { - baseTxComplexity, err := baseTx(&tx.BaseTx) + baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err } @@ -471,7 +471,7 @@ func (c *complexityVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } func (c *complexityVisitor) ExportTx(tx *txs.ExportTx) error { - baseTxComplexity, err := baseTx(&tx.BaseTx) + baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err } @@ -487,7 +487,7 @@ func (c *complexityVisitor) ExportTx(tx *txs.ExportTx) error { } func (c *complexityVisitor) ImportTx(tx *txs.ImportTx) error { - baseTxComplexity, err := baseTx(&tx.BaseTx) + baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err } @@ -503,7 +503,7 @@ func (c *complexityVisitor) ImportTx(tx *txs.ImportTx) error { } func (c *complexityVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { - baseTxComplexity, err := baseTx(&tx.BaseTx) + baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err } @@ -519,7 +519,7 @@ func (c *complexityVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidato } func (c *complexityVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { - baseTxComplexity, err := baseTx(&tx.BaseTx) + baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err } @@ -539,7 +539,7 @@ func (c *complexityVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwne return err } -func baseTx(tx *txs.BaseTx) (fee.Dimensions, error) { +func baseTxComplexity(tx *txs.BaseTx) (fee.Dimensions, error) { outputsComplexity, err := outputsComplexity(tx.Outs) if err != nil { return fee.Dimensions{}, err From 5d8da76a865121eff7a816c0c4538fbbf83fe921 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 21 Jul 2024 13:18:36 -0400 Subject: [PATCH 082/100] export helpers --- vms/platformvm/txs/fee/complexity.go | 85 ++++++++++++++-------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/vms/platformvm/txs/fee/complexity.go b/vms/platformvm/txs/fee/complexity.go index 2af783b55312..a6bcf7692b2d 100644 --- a/vms/platformvm/txs/fee/complexity.go +++ b/vms/platformvm/txs/fee/complexity.go @@ -185,7 +185,24 @@ func TxComplexity(tx txs.UnsignedTx) (fee.Dimensions, error) { return c.output, err } -func OutputComplexity(out *avax.TransferableOutput) (fee.Dimensions, error) { +// OutputComplexity returns the complexity outputs adds to a transaction. +func OutputComplexity(outs ...*avax.TransferableOutput) (fee.Dimensions, error) { + var complexity fee.Dimensions + for _, out := range outs { + outputComplexity, err := outputComplexity(out) + if err != nil { + return fee.Dimensions{}, err + } + + complexity, err = complexity.Add(outputComplexity) + if err != nil { + return fee.Dimensions{}, err + } + } + return complexity, nil +} + +func outputComplexity(out *avax.TransferableOutput) (fee.Dimensions, error) { complexity := fee.Dimensions{ fee.Bandwidth: intrinsicOutputBandwidth + intrinsicSECP256k1FxOutputBandwidth, fee.DBRead: 0, @@ -213,9 +230,25 @@ func OutputComplexity(out *avax.TransferableOutput) (fee.Dimensions, error) { return complexity, err } -// InputComplexity returns the complexity an input adds to a transaction. -// It includes the complexity that the corresponding credential will add. -func InputComplexity(in *avax.TransferableInput) (fee.Dimensions, error) { +// InputComplexity returns the complexity inputs adds to a transaction. +// It includes the complexity that the corresponding credentials will add. +func InputComplexity(ins ...*avax.TransferableInput) (fee.Dimensions, error) { + var complexity fee.Dimensions + for _, in := range ins { + inputComplexity, err := inputComplexity(in) + if err != nil { + return fee.Dimensions{}, err + } + + complexity, err = complexity.Add(inputComplexity) + if err != nil { + return fee.Dimensions{}, err + } + } + return complexity, nil +} + +func inputComplexity(in *avax.TransferableInput) (fee.Dimensions, error) { complexity := fee.Dimensions{ fee.Bandwidth: intrinsicInputBandwidth + intrinsicSECP256k1FxTransferableInputBandwidth, fee.DBRead: 1, @@ -350,7 +383,7 @@ func (c *complexityVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionle if err != nil { return err } - outputsComplexity, err := outputsComplexity(tx.StakeOuts) + outputsComplexity, err := OutputComplexity(tx.StakeOuts...) if err != nil { return err } @@ -381,7 +414,7 @@ func (c *complexityVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionle if err != nil { return err } - outputsComplexity, err := outputsComplexity(tx.StakeOuts) + outputsComplexity, err := OutputComplexity(tx.StakeOuts...) if err != nil { return err } @@ -475,7 +508,7 @@ func (c *complexityVisitor) ExportTx(tx *txs.ExportTx) error { if err != nil { return err } - outputsComplexity, err := outputsComplexity(tx.ExportedOutputs) + outputsComplexity, err := OutputComplexity(tx.ExportedOutputs...) if err != nil { return err } @@ -491,7 +524,7 @@ func (c *complexityVisitor) ImportTx(tx *txs.ImportTx) error { if err != nil { return err } - inputsComplexity, err := inputsComplexity(tx.ImportedInputs) + inputsComplexity, err := InputComplexity(tx.ImportedInputs...) if err != nil { return err } @@ -540,11 +573,11 @@ func (c *complexityVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwne } func baseTxComplexity(tx *txs.BaseTx) (fee.Dimensions, error) { - outputsComplexity, err := outputsComplexity(tx.Outs) + outputsComplexity, err := OutputComplexity(tx.Outs...) if err != nil { return fee.Dimensions{}, err } - inputsComplexity, err := inputsComplexity(tx.Ins) + inputsComplexity, err := InputComplexity(tx.Ins...) if err != nil { return fee.Dimensions{}, err } @@ -558,35 +591,3 @@ func baseTxComplexity(tx *txs.BaseTx) (fee.Dimensions, error) { ) return complexity, err } - -func outputsComplexity(outs []*avax.TransferableOutput) (fee.Dimensions, error) { - var complexity fee.Dimensions - for _, out := range outs { - outputComplexity, err := OutputComplexity(out) - if err != nil { - return fee.Dimensions{}, err - } - - complexity, err = complexity.Add(outputComplexity) - if err != nil { - return fee.Dimensions{}, err - } - } - return complexity, nil -} - -func inputsComplexity(ins []*avax.TransferableInput) (fee.Dimensions, error) { - var complexity fee.Dimensions - for _, in := range ins { - inputComplexity, err := InputComplexity(in) - if err != nil { - return fee.Dimensions{}, err - } - - complexity, err = complexity.Add(inputComplexity) - if err != nil { - return fee.Dimensions{}, err - } - } - return complexity, nil -} From e67fe3eab0dfdda72b2df6bef201c3edea10304f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 21 Jul 2024 13:23:48 -0400 Subject: [PATCH 083/100] add todos --- vms/platformvm/txs/fee/complexity_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/vms/platformvm/txs/fee/complexity_test.go b/vms/platformvm/txs/fee/complexity_test.go index 89b63b44d19c..688fa93ed339 100644 --- a/vms/platformvm/txs/fee/complexity_test.go +++ b/vms/platformvm/txs/fee/complexity_test.go @@ -36,7 +36,7 @@ func TestTxComplexity(t *testing.T) { fee.Bandwidth: 691, fee.DBRead: 2, fee.DBWrite: 4, - fee.Compute: 0, + fee.Compute: 0, // TODO: implement }, }, { @@ -46,7 +46,7 @@ func TestTxComplexity(t *testing.T) { fee.Bandwidth: 499, fee.DBRead: 2, fee.DBWrite: 3, - fee.Compute: 0, + fee.Compute: 0, // TODO: implement }, }, { @@ -56,7 +56,7 @@ func TestTxComplexity(t *testing.T) { fee.Bandwidth: 460, fee.DBRead: 3, fee.DBWrite: 3, - fee.Compute: 0, + fee.Compute: 0, // TODO: implement }, }, { @@ -66,7 +66,7 @@ func TestTxComplexity(t *testing.T) { fee.Bandwidth: 399, fee.DBRead: 1, fee.DBWrite: 3, - fee.Compute: 0, + fee.Compute: 0, // TODO: implement }, }, { @@ -76,7 +76,7 @@ func TestTxComplexity(t *testing.T) { fee.Bandwidth: 509, fee.DBRead: 2, fee.DBWrite: 3, - fee.Compute: 0, + fee.Compute: 0, // TODO: implement }, }, { @@ -86,7 +86,7 @@ func TestTxComplexity(t *testing.T) { fee.Bandwidth: 339, fee.DBRead: 1, fee.DBWrite: 3, - fee.Compute: 0, + fee.Compute: 0, // TODO: implement }, }, { @@ -96,7 +96,7 @@ func TestTxComplexity(t *testing.T) { fee.Bandwidth: 435, fee.DBRead: 1, fee.DBWrite: 3, - fee.Compute: 0, + fee.Compute: 0, // TODO: implement }, }, { @@ -106,7 +106,7 @@ func TestTxComplexity(t *testing.T) { fee.Bandwidth: 335, fee.DBRead: 1, fee.DBWrite: 2, - fee.Compute: 0, + fee.Compute: 0, // TODO: implement }, }, { @@ -116,7 +116,7 @@ func TestTxComplexity(t *testing.T) { fee.Bandwidth: 436, fee.DBRead: 3, fee.DBWrite: 3, - fee.Compute: 0, + fee.Compute: 0, // TODO: implement }, }, { @@ -126,7 +126,7 @@ func TestTxComplexity(t *testing.T) { fee.Bandwidth: 436, fee.DBRead: 2, fee.DBWrite: 3, - fee.Compute: 0, + fee.Compute: 0, // TODO: implement }, }, } From 2b00d3f0c1c04b93fcd9144c6dd47d9d98eefe60 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 21 Jul 2024 13:33:09 -0400 Subject: [PATCH 084/100] nit --- vms/platformvm/txs/fee/complexity.go | 3 ++- vms/platformvm/txs/fee/complexity_test.go | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/vms/platformvm/txs/fee/complexity.go b/vms/platformvm/txs/fee/complexity.go index a6bcf7692b2d..52edf2ddae4e 100644 --- a/vms/platformvm/txs/fee/complexity.go +++ b/vms/platformvm/txs/fee/complexity.go @@ -6,6 +6,7 @@ package fee import ( "errors" + "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" @@ -101,7 +102,7 @@ var ( fee.Compute: 0, } IntrinsicBaseTxComplexities = fee.Dimensions{ - fee.Bandwidth: wrappers.ShortLen + // codecID + fee.Bandwidth: codec.VersionSize + // codecVersion wrappers.IntLen + // typeID wrappers.IntLen + // networkID ids.IDLen + // blockchainID diff --git a/vms/platformvm/txs/fee/complexity_test.go b/vms/platformvm/txs/fee/complexity_test.go index 688fa93ed339..232cb0840c3a 100644 --- a/vms/platformvm/txs/fee/complexity_test.go +++ b/vms/platformvm/txs/fee/complexity_test.go @@ -10,9 +10,9 @@ import ( "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/fee" "github.com/ava-labs/avalanchego/vms/components/verify" @@ -261,7 +261,7 @@ func TestOutputComplexity(t *testing.T) { bytes, err := txs.Codec.Marshal(txs.CodecVersion, test.out) require.NoError(err) - numBytesWithoutCodecVersion := uint64(len(bytes) - wrappers.ShortLen) + numBytesWithoutCodecVersion := uint64(len(bytes) - codec.VersionSize) require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) }) } @@ -391,7 +391,7 @@ func TestInputComplexity(t *testing.T) { credentialBytes, err := txs.Codec.Marshal(txs.CodecVersion, &cred) require.NoError(err) - numBytesWithoutCodecVersion := uint64(len(inputBytes) + len(credentialBytes) - 2*wrappers.ShortLen) + numBytesWithoutCodecVersion := uint64(len(inputBytes) + len(credentialBytes) - 2*codec.VersionSize) require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) }) } @@ -465,7 +465,7 @@ func TestOwnerComplexity(t *testing.T) { ownerBytes, err := txs.Codec.Marshal(txs.CodecVersion, test.owner) require.NoError(err) - numBytesWithoutCodecVersion := uint64(len(ownerBytes) - wrappers.ShortLen) + numBytesWithoutCodecVersion := uint64(len(ownerBytes) - codec.VersionSize) require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) }) } @@ -558,7 +558,7 @@ func TestAuthComplexity(t *testing.T) { credentialBytes, err := txs.Codec.Marshal(txs.CodecVersion, test.cred) require.NoError(err) - numBytesWithoutCodecVersion := uint64(len(authBytes) + len(credentialBytes) - 2*wrappers.ShortLen) + numBytesWithoutCodecVersion := uint64(len(authBytes) + len(credentialBytes) - 2*codec.VersionSize) require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) }) } @@ -620,7 +620,7 @@ func TestSignerComplexity(t *testing.T) { signerBytes, err := txs.Codec.Marshal(txs.CodecVersion, test.signer) require.NoError(err) - numBytesWithoutCodecVersion := uint64(len(signerBytes) - wrappers.ShortLen) + numBytesWithoutCodecVersion := uint64(len(signerBytes) - codec.VersionSize) require.Equal(numBytesWithoutCodecVersion, actual[fee.Bandwidth]) }) } From 67e3e9005c1d5b997c73576c79fecffa4f0bde99 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 22 Jul 2024 17:37:14 -0400 Subject: [PATCH 085/100] nit --- vms/platformvm/txs/fee/complexity.go | 2 +- vms/platformvm/txs/fee/complexity_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vms/platformvm/txs/fee/complexity.go b/vms/platformvm/txs/fee/complexity.go index 52edf2ddae4e..45d410bddae4 100644 --- a/vms/platformvm/txs/fee/complexity.go +++ b/vms/platformvm/txs/fee/complexity.go @@ -89,7 +89,7 @@ var ( wrappers.IntLen + // num stake outs wrappers.IntLen, // delegator rewards typeID fee.DBRead: 1, - fee.DBWrite: 0, + fee.DBWrite: 1, fee.Compute: 0, } IntrinsicAddSubnetValidatorTxComplexities = fee.Dimensions{ diff --git a/vms/platformvm/txs/fee/complexity_test.go b/vms/platformvm/txs/fee/complexity_test.go index 232cb0840c3a..b533e5e4e3a1 100644 --- a/vms/platformvm/txs/fee/complexity_test.go +++ b/vms/platformvm/txs/fee/complexity_test.go @@ -45,7 +45,7 @@ func TestTxComplexity(t *testing.T) { expected: fee.Dimensions{ fee.Bandwidth: 499, fee.DBRead: 2, - fee.DBWrite: 3, + fee.DBWrite: 4, fee.Compute: 0, // TODO: implement }, }, From 4cf38302a8e76ae79131609f785629eb57a9d4d0 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 25 Jul 2024 20:49:20 -0400 Subject: [PATCH 086/100] merged --- vms/platformvm/txs/fee/complexity.go | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/vms/platformvm/txs/fee/complexity.go b/vms/platformvm/txs/fee/complexity.go index 45d410bddae4..805fa21abb1b 100644 --- a/vms/platformvm/txs/fee/complexity.go +++ b/vms/platformvm/txs/fee/complexity.go @@ -195,7 +195,7 @@ func OutputComplexity(outs ...*avax.TransferableOutput) (fee.Dimensions, error) return fee.Dimensions{}, err } - complexity, err = complexity.Add(outputComplexity) + complexity, err = complexity.Add(&outputComplexity) if err != nil { return fee.Dimensions{}, err } @@ -241,7 +241,7 @@ func InputComplexity(ins ...*avax.TransferableInput) (fee.Dimensions, error) { return fee.Dimensions{}, err } - complexity, err = complexity.Add(inputComplexity) + complexity, err = complexity.Add(&inputComplexity) if err != nil { return fee.Dimensions{}, err } @@ -397,11 +397,11 @@ func (c *complexityVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionle return err } c.output, err = IntrinsicAddPermissionlessValidatorTxComplexities.Add( - baseTxComplexity, - signerComplexity, - outputsComplexity, - validatorOwnerComplexity, - delegatorOwnerComplexity, + &baseTxComplexity, + &signerComplexity, + &outputsComplexity, + &validatorOwnerComplexity, + &delegatorOwnerComplexity, ) return err } @@ -420,9 +420,9 @@ func (c *complexityVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionle return err } c.output, err = IntrinsicAddPermissionlessDelegatorTxComplexities.Add( - baseTxComplexity, - ownerComplexity, - outputsComplexity, + &baseTxComplexity, + &ownerComplexity, + &outputsComplexity, ) return err } @@ -437,8 +437,8 @@ func (c *complexityVisitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) e return err } c.output, err = IntrinsicAddSubnetValidatorTxComplexities.Add( - baseTxComplexity, - authComplexity, + &baseTxComplexity, + &authComplexity, ) return err } @@ -448,7 +448,7 @@ func (c *complexityVisitor) BaseTx(tx *txs.BaseTx) error { if err != nil { return err } - c.output, err = IntrinsicBaseTxComplexities.Add(baseTxComplexity) + c.output, err = IntrinsicBaseTxComplexities.Add(&baseTxComplexity) return err } @@ -481,9 +481,9 @@ func (c *complexityVisitor) CreateChainTx(tx *txs.CreateChainTx) error { return err } c.output, err = IntrinsicCreateChainTxComplexities.Add( - dynamicComplexity, - baseTxComplexity, - authComplexity, + &dynamicComplexity, + &baseTxComplexity, + &authComplexity, ) return err } @@ -498,8 +498,8 @@ func (c *complexityVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { return err } c.output, err = IntrinsicCreateSubnetTxComplexities.Add( - baseTxComplexity, - ownerComplexity, + &baseTxComplexity, + &ownerComplexity, ) return err } @@ -514,8 +514,8 @@ func (c *complexityVisitor) ExportTx(tx *txs.ExportTx) error { return err } c.output, err = IntrinsicExportTxComplexities.Add( - baseTxComplexity, - outputsComplexity, + &baseTxComplexity, + &outputsComplexity, ) return err } @@ -530,8 +530,8 @@ func (c *complexityVisitor) ImportTx(tx *txs.ImportTx) error { return err } c.output, err = IntrinsicImportTxComplexities.Add( - baseTxComplexity, - inputsComplexity, + &baseTxComplexity, + &inputsComplexity, ) return err } @@ -546,8 +546,8 @@ func (c *complexityVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidato return err } c.output, err = IntrinsicRemoveSubnetValidatorTxComplexities.Add( - baseTxComplexity, - authComplexity, + &baseTxComplexity, + &authComplexity, ) return err } @@ -566,9 +566,9 @@ func (c *complexityVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwne return err } c.output, err = IntrinsicTransferSubnetOwnershipTxComplexities.Add( - baseTxComplexity, - authComplexity, - ownerComplexity, + &baseTxComplexity, + &authComplexity, + &ownerComplexity, ) return err } @@ -582,7 +582,7 @@ func baseTxComplexity(tx *txs.BaseTx) (fee.Dimensions, error) { if err != nil { return fee.Dimensions{}, err } - complexity, err := outputsComplexity.Add(inputsComplexity) + complexity, err := outputsComplexity.Add(&inputsComplexity) if err != nil { return fee.Dimensions{}, err } From 804c5773e11dd139f63dcabe986371c00a4dd9b0 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 25 Jul 2024 20:59:57 -0400 Subject: [PATCH 087/100] Add benchmark --- vms/platformvm/txs/fee/complexity_test.go | 216 ++++++++++++---------- 1 file changed, 118 insertions(+), 98 deletions(-) diff --git a/vms/platformvm/txs/fee/complexity_test.go b/vms/platformvm/txs/fee/complexity_test.go index b533e5e4e3a1..28b77461babd 100644 --- a/vms/platformvm/txs/fee/complexity_test.go +++ b/vms/platformvm/txs/fee/complexity_test.go @@ -23,114 +23,115 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) -func TestTxComplexity(t *testing.T) { - tests := []struct { - name string - tx string - expected fee.Dimensions - }{ - { - name: "AddPermissionlessValidatorTx", - tx: "00000000001900003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba8b1e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001043c91e9d508169329034e2a68110427a311f945efc53ed3f3493d335b393fd100000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f263d53e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae35f0000000066b692df000001d1a94a200000000000000000000000000000000000000000000000000000000000000000000000001ca3783a891cb41cadbfcf456da149f30e7af972677a162b984bef0779f254baac51ec042df1781d1295df80fb41c801269731fc6c25e1e5940dc3cb8509e30348fa712742cfdc83678acc9f95908eb98b89b28802fb559b4a2a6ff3216707c07f0ceb0b45a95f4f9a9540bbd3331d8ab4f233bffa4abb97fad9d59a1695f31b92a2b89e365facf7ab8c30de7c4a496d1e00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0007a12000000001000000090000000135f122f90bcece0d6c43e07fed1829578a23bc1734f8a4b46203f9f192ea1aec7526f3dca8fddec7418988615e6543012452bae1544275aae435313ec006ec9000", - expected: fee.Dimensions{ - fee.Bandwidth: 691, - fee.DBRead: 2, - fee.DBWrite: 4, - fee.Compute: 0, // TODO: implement - }, +var txTests = []struct { + name string + tx string + expected fee.Dimensions +}{ + { + name: "AddPermissionlessValidatorTx", + tx: "00000000001900003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba8b1e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001043c91e9d508169329034e2a68110427a311f945efc53ed3f3493d335b393fd100000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f263d53e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae35f0000000066b692df000001d1a94a200000000000000000000000000000000000000000000000000000000000000000000000001ca3783a891cb41cadbfcf456da149f30e7af972677a162b984bef0779f254baac51ec042df1781d1295df80fb41c801269731fc6c25e1e5940dc3cb8509e30348fa712742cfdc83678acc9f95908eb98b89b28802fb559b4a2a6ff3216707c07f0ceb0b45a95f4f9a9540bbd3331d8ab4f233bffa4abb97fad9d59a1695f31b92a2b89e365facf7ab8c30de7c4a496d1e00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0007a12000000001000000090000000135f122f90bcece0d6c43e07fed1829578a23bc1734f8a4b46203f9f192ea1aec7526f3dca8fddec7418988615e6543012452bae1544275aae435313ec006ec9000", + expected: fee.Dimensions{ + fee.Bandwidth: 691, + fee.DBRead: 2, + fee.DBWrite: 4, + fee.Compute: 0, // TODO: implement }, - { - name: "AddPermissionlessDelegatorTx", - tx: "00000000001a00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1140fe00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000017d199179744b3b82d0071c83c2fb7dd6b95a2cdbe9dde295e0ae4f8c2287370300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba8b1e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae6080000000066ad5b08000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000100000009000000012261556f74a29f02ffc2725a567db2c81f75d0892525dbebaa1cf8650534cc70061123533a9553184cb02d899943ff0bf0b39c77b173c133854bc7c8bc7ab9a400", - expected: fee.Dimensions{ - fee.Bandwidth: 499, - fee.DBRead: 2, - fee.DBWrite: 4, - fee.Compute: 0, // TODO: implement - }, + }, + { + name: "AddPermissionlessDelegatorTx", + tx: "00000000001a00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1140fe00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000017d199179744b3b82d0071c83c2fb7dd6b95a2cdbe9dde295e0ae4f8c2287370300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba8b1e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae6080000000066ad5b08000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000100000009000000012261556f74a29f02ffc2725a567db2c81f75d0892525dbebaa1cf8650534cc70061123533a9553184cb02d899943ff0bf0b39c77b173c133854bc7c8bc7ab9a400", + expected: fee.Dimensions{ + fee.Bandwidth: 499, + fee.DBRead: 2, + fee.DBWrite: 4, + fee.Compute: 0, // TODO: implement }, - { - name: "AddSubnetValidatorTx", - tx: "00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1131bbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000138f94d1a0514eaabdaf4c52cad8d62b26cee61eaa951f5b75a5e57c2ee3793c800000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1140fe00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae7c90000000066ad5cc9000000000000c13797ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000200000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb60000000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb600", - expected: fee.Dimensions{ - fee.Bandwidth: 460, - fee.DBRead: 3, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, + }, + { + name: "AddSubnetValidatorTx", + tx: "00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1131bbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000138f94d1a0514eaabdaf4c52cad8d62b26cee61eaa951f5b75a5e57c2ee3793c800000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1140fe00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae7c90000000066ad5cc9000000000000c13797ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000200000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb60000000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb600", + expected: fee.Dimensions{ + fee.Bandwidth: 460, + fee.DBRead: 3, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement }, - { - name: "BaseTx", - tx: "00000000002200003039000000000000000000000000000000000000000000000000000000000000000000000002dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fadbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834ed587af80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001fa4ff39749d44f29563ed9da03193d4a19ef419da4ce326594817ca266fda5ed00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1131bbc00000000100000000000000000000000100000009000000014a7b54c63dd25a532b5fe5045b6d0e1db876e067422f12c9c327333c2c792d9273405ac8bbbc2cce549bbd3d0f9274242085ee257adfdb859b0f8d55bdd16fb000", - expected: fee.Dimensions{ - fee.Bandwidth: 399, - fee.DBRead: 1, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, + }, + { + name: "BaseTx", + tx: "00000000002200003039000000000000000000000000000000000000000000000000000000000000000000000002dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fadbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834ed587af80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001fa4ff39749d44f29563ed9da03193d4a19ef419da4ce326594817ca266fda5ed00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1131bbc00000000100000000000000000000000100000009000000014a7b54c63dd25a532b5fe5045b6d0e1db876e067422f12c9c327333c2c792d9273405ac8bbbc2cce549bbd3d0f9274242085ee257adfdb859b0f8d55bdd16fb000", + expected: fee.Dimensions{ + fee.Bandwidth: 399, + fee.DBRead: 1, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement }, - { - name: "CreateChainTx", - tx: "00000000000f00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263d53e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000197ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269cb1f0000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400096c65742074686572657873766d00000000000000000000000000000000000000000000000000000000000000000000002a000000000000669ae21e000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cffffffffffffffff0000000a0000000100000000000000020000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f8010000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f801", - expected: fee.Dimensions{ - fee.Bandwidth: 509, - fee.DBRead: 2, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, + }, + { + name: "CreateChainTx", + tx: "00000000000f00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263d53e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000197ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269cb1f0000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400096c65742074686572657873766d00000000000000000000000000000000000000000000000000000000000000000000002a000000000000669ae21e000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cffffffffffffffff0000000a0000000100000000000000020000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f8010000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f801", + expected: fee.Dimensions{ + fee.Bandwidth: 509, + fee.DBRead: 2, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement }, - { - name: "CreateSubnetTx", - tx: "00000000001000003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f269cb1f00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc100000000000100000000000000000000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000010000000900000001b3c905e7227e619bd6b98c164a8b2b4a8ce89ac5142bbb1c42b139df2d17fd777c4c76eae66cef3de90800e567407945f58d918978f734f8ca4eda6923c78eb201", - expected: fee.Dimensions{ - fee.Bandwidth: 339, - fee.DBRead: 1, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, + }, + { + name: "CreateSubnetTx", + tx: "00000000001000003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f269cb1f00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc100000000000100000000000000000000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000010000000900000001b3c905e7227e619bd6b98c164a8b2b4a8ce89ac5142bbb1c42b139df2d17fd777c4c76eae66cef3de90800e567407945f58d918978f734f8ca4eda6923c78eb201", + expected: fee.Dimensions{ + fee.Bandwidth: 339, + fee.DBRead: 1, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement }, - { - name: "ExportTx", - tx: "00000000001200003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99dda340000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001f62c03574790b6a31a988f90c3e91c50fdd6f5d93baf200057463021ff23ec5c00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834ed587af800000000100000000000000009d0775f450604bd2fbc49ce0c5c1c6dfeb2dc2acb8c92c26eeae6e6df4502b1900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fa000000010000000900000001129a07c92045e0b9d0a203fcb5b53db7890fabce1397ff6a2ad16c98ef0151891ae72949d240122abf37b1206b95e05ff171df164a98e6bdf2384432eac2c30200", - expected: fee.Dimensions{ - fee.Bandwidth: 435, - fee.DBRead: 1, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, + }, + { + name: "ExportTx", + tx: "00000000001200003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99dda340000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001f62c03574790b6a31a988f90c3e91c50fdd6f5d93baf200057463021ff23ec5c00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834ed587af800000000100000000000000009d0775f450604bd2fbc49ce0c5c1c6dfeb2dc2acb8c92c26eeae6e6df4502b1900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fa000000010000000900000001129a07c92045e0b9d0a203fcb5b53db7890fabce1397ff6a2ad16c98ef0151891ae72949d240122abf37b1206b95e05ff171df164a98e6bdf2384432eac2c30200", + expected: fee.Dimensions{ + fee.Bandwidth: 435, + fee.DBRead: 1, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement }, - { - name: "ImportTx", - tx: "00000000001100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b8b87c0000000000000000100000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000000000000d891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf0000000163684415710a7d65f4ccb095edff59f897106b94d38937fc60e3ffc29892833b00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000003b9aca00000000010000000000000001000000090000000148ea12cb0950e47d852b99765208f5a811d3c8a47fa7b23fd524bd970019d157029f973abb91c31a146752ef8178434deb331db24c8dca5e61c961e6ac2f3b6700", - expected: fee.Dimensions{ - fee.Bandwidth: 335, - fee.DBRead: 1, - fee.DBWrite: 2, - fee.Compute: 0, // TODO: implement - }, + }, + { + name: "ImportTx", + tx: "00000000001100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b8b87c0000000000000000100000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000000000000d891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf0000000163684415710a7d65f4ccb095edff59f897106b94d38937fc60e3ffc29892833b00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000003b9aca00000000010000000000000001000000090000000148ea12cb0950e47d852b99765208f5a811d3c8a47fa7b23fd524bd970019d157029f973abb91c31a146752ef8178434deb331db24c8dca5e61c961e6ac2f3b6700", + expected: fee.Dimensions{ + fee.Bandwidth: 335, + fee.DBRead: 1, + fee.DBWrite: 2, + fee.Compute: 0, // TODO: implement }, - { - name: "RemoveSubnetValidatorTx", - tx: "00000000001700003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99ce6100000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001cd4569cfd044d50636fa597c700710403b3b52d3b75c30c542a111cc52c911ec00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99dda340000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a0000000100000000000000020000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d010000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d01", - expected: fee.Dimensions{ - fee.Bandwidth: 436, - fee.DBRead: 3, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, + }, + { + name: "RemoveSubnetValidatorTx", + tx: "00000000001700003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99ce6100000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001cd4569cfd044d50636fa597c700710403b3b52d3b75c30c542a111cc52c911ec00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99dda340000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a0000000100000000000000020000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d010000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d01", + expected: fee.Dimensions{ + fee.Bandwidth: 436, + fee.DBRead: 3, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement }, - { - name: "TransferSubnetOwnershipTx", - tx: "00000000002100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99bf1ec0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000018f6e5f2840e34f9a375f35627a44bb0b9974285d280dc3220aa9489f97b17ebd00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99ce610000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000b00000000000000000000000000000000000000020000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f010000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f01", - expected: fee.Dimensions{ - fee.Bandwidth: 436, - fee.DBRead: 2, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, + }, + { + name: "TransferSubnetOwnershipTx", + tx: "00000000002100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99bf1ec0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000018f6e5f2840e34f9a375f35627a44bb0b9974285d280dc3220aa9489f97b17ebd00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99ce610000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000b00000000000000000000000000000000000000020000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f010000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f01", + expected: fee.Dimensions{ + fee.Bandwidth: 436, + fee.DBRead: 2, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement }, - } - for _, test := range tests { + }, +} + +func TestTxComplexity(t *testing.T) { + for _, test := range txTests { t.Run(test.name, func(t *testing.T) { require := require.New(t) @@ -155,6 +156,25 @@ func TestTxComplexity(t *testing.T) { } } +func BenchmarkTxComplexity(b *testing.B) { + for _, test := range txTests { + b.Run(test.name, func(b *testing.B) { + require := require.New(b) + + txBytes, err := hex.DecodeString(test.tx) + require.NoError(err) + + tx, err := txs.Parse(txs.Codec, txBytes) + require.NoError(err) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = TxComplexity(tx.Unsigned) + } + }) + } +} + func TestOutputComplexity(t *testing.T) { tests := []struct { name string From 45eb21e331371b6b1d5a59b3c9a8f6abeee3d5cb Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 27 Jul 2024 18:26:27 -0400 Subject: [PATCH 088/100] wip --- vms/platformvm/txs/fee/calculator.go | 11 +- vms/platformvm/txs/fee/calculator_test.go | 286 +++++------------- vms/platformvm/txs/fee/static_calculator.go | 55 +--- .../txs/fee/static_calculator_test.go | 32 ++ vms/platformvm/txs/fee/static_config.go | 7 +- 5 files changed, 130 insertions(+), 261 deletions(-) create mode 100644 vms/platformvm/txs/fee/static_calculator_test.go diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 511bb34ed3c2..e026046aac61 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -3,9 +3,16 @@ package fee -import "github.com/ava-labs/avalanchego/vms/platformvm/txs" +import ( + "errors" -// Calculator is the interfaces that any fee Calculator must implement + "github.com/ava-labs/avalanchego/vms/platformvm/txs" +) + +var ErrUnsupportedTx = errors.New("unsupported transaction type") + +// Calculator calculates the minimum required fee, in nAVAX, that an unsigned +// transaction must pay for valid inclusion into a block. type Calculator interface { CalculateFee(tx txs.UnsignedTx) (uint64, error) } diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 656b9ca0889f..54694633a850 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -3,251 +3,109 @@ package fee -import ( - "testing" - "time" +import "github.com/ava-labs/avalanchego/utils/units" - "github.com/stretchr/testify/require" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" -) - -func TestTxFees(t *testing.T) { - feeTestsDefaultCfg := StaticConfig{ +var ( + testStaticConfig = StaticConfig{ TxFee: 1 * units.Avax, - CreateAssetTxFee: 2 * units.Avax, - CreateSubnetTxFee: 3 * units.Avax, - TransformSubnetTxFee: 4 * units.Avax, - CreateBlockchainTxFee: 5 * units.Avax, - AddPrimaryNetworkValidatorFee: 6 * units.Avax, - AddPrimaryNetworkDelegatorFee: 7 * units.Avax, - AddSubnetValidatorFee: 8 * units.Avax, - AddSubnetDelegatorFee: 9 * units.Avax, - } - - latestForkTime := time.Unix(1713945427, 0) - upgrades := upgrade.Config{ - EUpgradeTime: latestForkTime, - DurangoTime: latestForkTime.Add(-1 * time.Hour), - CortinaTime: latestForkTime.Add(-2 * time.Hour), - BanffTime: latestForkTime.Add(-3 * time.Hour), - ApricotPhase5Time: latestForkTime.Add(-4 * time.Hour), - ApricotPhase3Time: latestForkTime.Add(-5 * time.Hour), + CreateSubnetTxFee: 2 * units.Avax, + TransformSubnetTxFee: 3 * units.Avax, + CreateBlockchainTxFee: 4 * units.Avax, + AddPrimaryNetworkValidatorFee: 5 * units.Avax, + AddPrimaryNetworkDelegatorFee: 6 * units.Avax, + AddSubnetValidatorFee: 7 * units.Avax, + AddSubnetDelegatorFee: 8 * units.Avax, } - // chain times needed to have specific upgrades active - preEUpgradeTime := upgrades.EUpgradeTime.Add(-1 * time.Second) - preApricotPhase3Time := upgrades.ApricotPhase3Time.Add(-1 * time.Second) - - tests := []struct { - name string - chainTime time.Time - unsignedTx func() txs.UnsignedTx - expected uint64 + txTests = []struct { + name string + tx string + expectedStaticFee uint64 + expectedStaticFeeErr error }{ { - name: "AddValidatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: addValidatorTx, - expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, - }, - { - name: "AddSubnetValidatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: addSubnetValidatorTx, - expected: feeTestsDefaultCfg.AddSubnetValidatorFee, + name: "AdvanceTimeTx", + tx: "0000000000130000000066a56fe700000000", + expectedStaticFee: 0, + expectedStaticFeeErr: ErrUnsupportedTx, }, { - name: "AddDelegatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: addDelegatorTx, - expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, + name: "RewardValidatorTx", + tx: "0000000000143d0ad12b8ee8928edf248ca91ca55600fb383f07c32bff1d6dec472b25cf59a700000000", + expectedStaticFee: 0, + expectedStaticFeeErr: ErrUnsupportedTx, }, { - name: "CreateChainTx pre ApricotPhase3", - chainTime: preApricotPhase3Time, - unsignedTx: createChainTx, - expected: feeTestsDefaultCfg.CreateAssetTxFee, + name: "AddValidatorTx", + tx: "00000000000c0000000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000f4b21e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000015000000006134088000000005000001d1a94a200000000001000000000000000400000000b3da694c70b8bee4478051313621c3f2282088b4000000005f6976d500000000614aaa19000001d1a94a20000000000121e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000016000000006134088000000007000001d1a94a20000000000000000000000000010000000120868ed5ac611711b33d2e4f97085347415db1c40000000b0000000000000000000000010000000120868ed5ac611711b33d2e4f97085347415db1c400009c40000000010000000900000001620513952dd17c8726d52e9e621618cb38f09fd194abb4cd7b4ee35ecd10880a562ad968dc81a89beab4e87d88d5d582aa73d0d265c87892d1ffff1f6e00f0ef00", + expectedStaticFee: testStaticConfig.AddPrimaryNetworkValidatorFee, + expectedStaticFeeErr: nil, }, { - name: "CreateChainTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: createChainTx, - expected: feeTestsDefaultCfg.CreateBlockchainTxFee, + name: "AddDelegatorTx", + tx: "00000000000e000000050000000000000000000000000000000000000000000000000000000000000000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000000003b9aca0000000000000000000000000100000001f887b4c7030e95d2495603ae5d8b14cc0a66781a000000011767be999a49ca24fe705de032fa613b682493110fd6468ae7fb56bde1b9d729000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000000012a05f20000000001000000000000000400000000c51c552c49174e2e18b392049d3e4cd48b11490f000000005f692452000000005f73b05200000000ee6b2800000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000700000000ee6b280000000000000000000000000100000001e0cfe8cae22827d032805ded484e393ce51cbedb0000000b00000000000000000000000100000001e0cfe8cae22827d032805ded484e393ce51cbedb00000001000000090000000135cd78758035ed528d230317e5d880083a86a2b68c4a95655571828fe226548f235031c8dabd1fe06366a57613c4370ac26c4c59d1a1c46287a59906ec41b88f00", + expectedStaticFee: testStaticConfig.AddPrimaryNetworkDelegatorFee, + expectedStaticFeeErr: nil, }, { - name: "CreateSubnetTx pre ApricotPhase3", - chainTime: preApricotPhase3Time, - unsignedTx: createSubnetTx, - expected: feeTestsDefaultCfg.CreateAssetTxFee, + name: "AddPermissionlessValidatorTx for primary network", + tx: "00000000001900003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba8b1e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001043c91e9d508169329034e2a68110427a311f945efc53ed3f3493d335b393fd100000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f263d53e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae35f0000000066b692df000001d1a94a200000000000000000000000000000000000000000000000000000000000000000000000001ca3783a891cb41cadbfcf456da149f30e7af972677a162b984bef0779f254baac51ec042df1781d1295df80fb41c801269731fc6c25e1e5940dc3cb8509e30348fa712742cfdc83678acc9f95908eb98b89b28802fb559b4a2a6ff3216707c07f0ceb0b45a95f4f9a9540bbd3331d8ab4f233bffa4abb97fad9d59a1695f31b92a2b89e365facf7ab8c30de7c4a496d1e00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0007a12000000001000000090000000135f122f90bcece0d6c43e07fed1829578a23bc1734f8a4b46203f9f192ea1aec7526f3dca8fddec7418988615e6543012452bae1544275aae435313ec006ec9000", + expectedStaticFee: testStaticConfig.AddPrimaryNetworkValidatorFee, + expectedStaticFeeErr: nil, }, { - name: "CreateSubnetTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: createSubnetTx, - expected: feeTestsDefaultCfg.CreateSubnetTxFee, + name: "AddPermissionlessDelegatorTx for primary network", + tx: "00000000001a00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1140fe00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000017d199179744b3b82d0071c83c2fb7dd6b95a2cdbe9dde295e0ae4f8c2287370300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba8b1e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae6080000000066ad5b08000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000100000009000000012261556f74a29f02ffc2725a567db2c81f75d0892525dbebaa1cf8650534cc70061123533a9553184cb02d899943ff0bf0b39c77b173c133854bc7c8bc7ab9a400", + expectedStaticFee: testStaticConfig.AddPrimaryNetworkDelegatorFee, + expectedStaticFeeErr: nil, }, { - name: "RemoveSubnetValidatorTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: removeSubnetValidatorTx, - expected: feeTestsDefaultCfg.TxFee, + name: "AddSubnetValidatorTx", + tx: "00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1131bbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000138f94d1a0514eaabdaf4c52cad8d62b26cee61eaa951f5b75a5e57c2ee3793c800000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1140fe00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae7c90000000066ad5cc9000000000000c13797ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000200000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb60000000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb600", + expectedStaticFee: testStaticConfig.AddSubnetValidatorFee, + expectedStaticFeeErr: nil, }, { - name: "TransformSubnetTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: transformSubnetTx, - expected: feeTestsDefaultCfg.TransformSubnetTxFee, + name: "BaseTx", + tx: "00000000002200003039000000000000000000000000000000000000000000000000000000000000000000000002dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fadbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834ed587af80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001fa4ff39749d44f29563ed9da03193d4a19ef419da4ce326594817ca266fda5ed00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1131bbc00000000100000000000000000000000100000009000000014a7b54c63dd25a532b5fe5045b6d0e1db876e067422f12c9c327333c2c792d9273405ac8bbbc2cce549bbd3d0f9274242085ee257adfdb859b0f8d55bdd16fb000", + expectedStaticFee: testStaticConfig.TxFee, + expectedStaticFeeErr: nil, }, { - name: "TransferSubnetOwnershipTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: transferSubnetOwnershipTx, - expected: feeTestsDefaultCfg.TxFee, + name: "CreateChainTx", + tx: "00000000000f00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263d53e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000197ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269cb1f0000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400096c65742074686572657873766d00000000000000000000000000000000000000000000000000000000000000000000002a000000000000669ae21e000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cffffffffffffffff0000000a0000000100000000000000020000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f8010000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f801", + expectedStaticFee: testStaticConfig.CreateBlockchainTxFee, + expectedStaticFeeErr: nil, }, { - name: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { - return addPermissionlessValidatorTx(constants.PrimaryNetworkID) - }, - expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, + name: "CreateSubnetTx", + tx: "00000000001000003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f269cb1f00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc100000000000100000000000000000000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000010000000900000001b3c905e7227e619bd6b98c164a8b2b4a8ce89ac5142bbb1c42b139df2d17fd777c4c76eae66cef3de90800e567407945f58d918978f734f8ca4eda6923c78eb201", + expectedStaticFee: testStaticConfig.CreateSubnetTxFee, + expectedStaticFeeErr: nil, }, { - name: "AddPermissionlessValidatorTx Subnet pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { - subnetID := ids.GenerateTestID() - require.NotEqual(t, constants.PrimaryNetworkID, subnetID) - return addPermissionlessValidatorTx(subnetID) - }, - expected: feeTestsDefaultCfg.AddSubnetValidatorFee, + name: "ExportTx", + tx: "00000000001200003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99dda340000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001f62c03574790b6a31a988f90c3e91c50fdd6f5d93baf200057463021ff23ec5c00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834ed587af800000000100000000000000009d0775f450604bd2fbc49ce0c5c1c6dfeb2dc2acb8c92c26eeae6e6df4502b1900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fa000000010000000900000001129a07c92045e0b9d0a203fcb5b53db7890fabce1397ff6a2ad16c98ef0151891ae72949d240122abf37b1206b95e05ff171df164a98e6bdf2384432eac2c30200", + expectedStaticFee: testStaticConfig.TxFee, + expectedStaticFeeErr: nil, }, { - name: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { - return addPermissionlessDelegatorTx(constants.PrimaryNetworkID) - }, - expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, + name: "ImportTx", + tx: "00000000001100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b8b87c0000000000000000100000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000000000000d891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf0000000163684415710a7d65f4ccb095edff59f897106b94d38937fc60e3ffc29892833b00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000003b9aca00000000010000000000000001000000090000000148ea12cb0950e47d852b99765208f5a811d3c8a47fa7b23fd524bd970019d157029f973abb91c31a146752ef8178434deb331db24c8dca5e61c961e6ac2f3b6700", + expectedStaticFee: testStaticConfig.TxFee, + expectedStaticFeeErr: nil, }, { - name: "AddPermissionlessDelegatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { - subnetID := ids.GenerateTestID() - require.NotEqual(t, constants.PrimaryNetworkID, subnetID) - return addPermissionlessDelegatorTx(subnetID) - }, - expected: feeTestsDefaultCfg.AddSubnetDelegatorFee, + name: "RemoveSubnetValidatorTx", + tx: "00000000001700003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99ce6100000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001cd4569cfd044d50636fa597c700710403b3b52d3b75c30c542a111cc52c911ec00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99dda340000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a0000000100000000000000020000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d010000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d01", + expectedStaticFee: testStaticConfig.TxFee, + expectedStaticFeeErr: nil, }, { - name: "BaseTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: baseTx, - expected: feeTestsDefaultCfg.TxFee, + name: "TransferSubnetOwnershipTx", + tx: "00000000002100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99bf1ec0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000018f6e5f2840e34f9a375f35627a44bb0b9974285d280dc3220aa9489f97b17ebd00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99ce610000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000b00000000000000000000000000000000000000020000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f010000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f01", + expectedStaticFee: testStaticConfig.TxFee, + expectedStaticFeeErr: nil, }, - { - name: "ImportTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: importTx, - expected: feeTestsDefaultCfg.TxFee, - }, - { - name: "ExportTx pre EUpgrade", - chainTime: preEUpgradeTime, - unsignedTx: exportTx, - expected: feeTestsDefaultCfg.TxFee, - }, - { - name: "RewardValidatorTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { - return &txs.RewardValidatorTx{ - TxID: ids.GenerateTestID(), - } - }, - expected: 0, - }, - { - name: "AdvanceTimeTx pre EUpgrade", - chainTime: upgrades.EUpgradeTime.Add(-1 * time.Second), - unsignedTx: func() txs.UnsignedTx { - return &txs.AdvanceTimeTx{ - Time: uint64(time.Now().Unix()), - } - }, - expected: 0, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tx := tt.unsignedTx() - fc := NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) - fee, err := fc.CalculateFee(tx) - require.NoError(t, err) - require.Equal(t, tt.expected, fee) - }) } -} - -func addValidatorTx() txs.UnsignedTx { - return &txs.AddValidatorTx{} -} - -func addSubnetValidatorTx() txs.UnsignedTx { - return &txs.AddSubnetValidatorTx{} -} - -func addDelegatorTx() txs.UnsignedTx { - return &txs.AddDelegatorTx{} -} - -func createChainTx() txs.UnsignedTx { - return &txs.CreateChainTx{} -} - -func createSubnetTx() txs.UnsignedTx { - return &txs.CreateSubnetTx{} -} - -func removeSubnetValidatorTx() txs.UnsignedTx { - return &txs.RemoveSubnetValidatorTx{} -} - -func transformSubnetTx() txs.UnsignedTx { - return &txs.TransformSubnetTx{} -} - -func transferSubnetOwnershipTx() txs.UnsignedTx { - return &txs.TransferSubnetOwnershipTx{} -} - -func addPermissionlessValidatorTx(subnetID ids.ID) txs.UnsignedTx { - return &txs.AddPermissionlessValidatorTx{ - Subnet: subnetID, - } -} - -func addPermissionlessDelegatorTx(subnetID ids.ID) txs.UnsignedTx { - return &txs.AddPermissionlessDelegatorTx{ - Subnet: subnetID, - } -} - -func baseTx() txs.UnsignedTx { - return &txs.BaseTx{} -} - -func importTx() txs.UnsignedTx { - return &txs.ImportTx{} -} - -func exportTx() txs.UnsignedTx { - return &txs.ExportTx{} -} +) diff --git a/vms/platformvm/txs/fee/static_calculator.go b/vms/platformvm/txs/fee/static_calculator.go index 6c1b535202f0..9b79e573db70 100644 --- a/vms/platformvm/txs/fee/static_calculator.go +++ b/vms/platformvm/txs/fee/static_calculator.go @@ -4,11 +4,8 @@ package fee import ( - "time" - "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" ) var ( @@ -16,29 +13,19 @@ var ( _ txs.Visitor = (*staticVisitor)(nil) ) -func NewStaticCalculator( - config StaticConfig, - upgradeTimes upgrade.Config, - chainTime time.Time, -) Calculator { +func NewStaticCalculator(config StaticConfig) Calculator { return &staticCalculator{ - upgrades: upgradeTimes, - config: config, - time: chainTime, + config: config, } } type staticCalculator struct { - config StaticConfig - upgrades upgrade.Config - time time.Time + config StaticConfig } func (c *staticCalculator) CalculateFee(tx txs.UnsignedTx) (uint64, error) { v := staticVisitor{ - config: c.config, - upgrades: c.upgrades, - time: c.time, + config: c.config, } err := tx.Visit(&v) return v.fee, err @@ -46,14 +33,20 @@ func (c *staticCalculator) CalculateFee(tx txs.UnsignedTx) (uint64, error) { type staticVisitor struct { // inputs - config StaticConfig - upgrades upgrade.Config - time time.Time + config StaticConfig // outputs fee uint64 } +func (*staticVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + return ErrUnsupportedTx +} + +func (*staticVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { + return ErrUnsupportedTx +} + func (c *staticVisitor) AddValidatorTx(*txs.AddValidatorTx) error { c.fee = c.config.AddPrimaryNetworkValidatorFee return nil @@ -70,30 +63,12 @@ func (c *staticVisitor) AddDelegatorTx(*txs.AddDelegatorTx) error { } func (c *staticVisitor) CreateChainTx(*txs.CreateChainTx) error { - if c.upgrades.IsApricotPhase3Activated(c.time) { - c.fee = c.config.CreateBlockchainTxFee - } else { - c.fee = c.config.CreateAssetTxFee - } + c.fee = c.config.CreateBlockchainTxFee return nil } func (c *staticVisitor) CreateSubnetTx(*txs.CreateSubnetTx) error { - if c.upgrades.IsApricotPhase3Activated(c.time) { - c.fee = c.config.CreateSubnetTxFee - } else { - c.fee = c.config.CreateAssetTxFee - } - return nil -} - -func (c *staticVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - c.fee = 0 // no fees - return nil -} - -func (c *staticVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { - c.fee = 0 // no fees + c.fee = c.config.CreateSubnetTxFee return nil } diff --git a/vms/platformvm/txs/fee/static_calculator_test.go b/vms/platformvm/txs/fee/static_calculator_test.go new file mode 100644 index 000000000000..2cfec596f682 --- /dev/null +++ b/vms/platformvm/txs/fee/static_calculator_test.go @@ -0,0 +1,32 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fee + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/vms/platformvm/txs" +) + +func TestStaticCalculator(t *testing.T) { + calculator := NewStaticCalculator(testStaticConfig) + for _, test := range txTests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + txBytes, err := hex.DecodeString(test.tx) + require.NoError(err) + + tx, err := txs.Parse(txs.Codec, txBytes) + require.NoError(err) + + fee, err := calculator.CalculateFee(tx.Unsigned) + require.Equal(test.expectedStaticFee, fee) + require.ErrorIs(err, test.expectedStaticFeeErr) + }) + } +} diff --git a/vms/platformvm/txs/fee/static_config.go b/vms/platformvm/txs/fee/static_config.go index e03fb701806a..89c793a0b732 100644 --- a/vms/platformvm/txs/fee/static_config.go +++ b/vms/platformvm/txs/fee/static_config.go @@ -7,16 +7,13 @@ type StaticConfig struct { // Fee that is burned by every non-state creating transaction TxFee uint64 `json:"txFee"` - // Fee that must be burned by every state creating transaction before AP3 - CreateAssetTxFee uint64 `json:"createAssetTxFee"` - - // Fee that must be burned by every subnet creating transaction after AP3 + // Fee that must be burned by every subnet creating transaction CreateSubnetTxFee uint64 `json:"createSubnetTxFee"` // Fee that must be burned by every transform subnet transaction TransformSubnetTxFee uint64 `json:"transformSubnetTxFee"` - // Fee that must be burned by every blockchain creating transaction after AP3 + // Fee that must be burned by every blockchain creating transaction CreateBlockchainTxFee uint64 `json:"createBlockchainTxFee"` // Transaction fee for adding a primary network validator From c6162f6fdfa533587b65878f6d50847ba9d41b94 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 27 Jul 2024 19:46:52 -0400 Subject: [PATCH 089/100] Simplify static fee calculator --- api/info/service.go | 41 ++++++++--------- config/config.go | 26 ++++++----- genesis/genesis_fuji.go | 22 +++++----- genesis/genesis_local.go | 22 +++++----- genesis/genesis_mainnet.go | 22 +++++----- genesis/params.go | 17 +++++--- node/config.go | 15 +++---- node/node.go | 20 +++------ tests/antithesis/avalanchego/main.go | 4 +- vms/platformvm/block/executor/verifier.go | 14 +++--- vms/platformvm/config/config.go | 3 +- vms/platformvm/service_test.go | 2 +- vms/platformvm/state/chain_time_helpers.go | 16 ++++++- vms/platformvm/txs/fee/calculator_test.go | 18 ++++++++ vms/platformvm/txs/txstest/context.go | 25 ++++------- wallet/chain/p/builder/builder.go | 30 ++++++------- wallet/chain/p/builder/context.go | 36 +++++++-------- wallet/chain/p/builder_test.go | 51 ++++++++++++---------- 18 files changed, 200 insertions(+), 184 deletions(-) diff --git a/api/info/service.go b/api/info/service.go index fd0117c5a088..714fefe16d96 100644 --- a/api/info/service.go +++ b/api/info/service.go @@ -13,6 +13,7 @@ import ( "go.uber.org/zap" "github.com/ava-labs/avalanchego/chains" + "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/network" "github.com/ava-labs/avalanchego/network/peer" @@ -46,20 +47,12 @@ type Info struct { } type Parameters struct { - Version *version.Application - NodeID ids.NodeID - NodePOP *signer.ProofOfPossession - NetworkID uint32 - TxFee uint64 - CreateAssetTxFee uint64 - CreateSubnetTxFee uint64 - TransformSubnetTxFee uint64 - CreateBlockchainTxFee uint64 - AddPrimaryNetworkValidatorFee uint64 - AddPrimaryNetworkDelegatorFee uint64 - AddSubnetValidatorFee uint64 - AddSubnetDelegatorFee uint64 - VMManager vms.Manager + Version *version.Application + NodeID ids.NodeID + NodePOP *signer.ProofOfPossession + NetworkID uint32 + TxFeeConfig genesis.TxFeeConfig + VMManager vms.Manager } func NewService( @@ -386,8 +379,8 @@ func (i *Info) Acps(_ *http.Request, _ *struct{}, reply *ACPsReply) error { } type GetTxFeeResponse struct { - TxFee json.Uint64 `json:"txFee"` CreateAssetTxFee json.Uint64 `json:"createAssetTxFee"` + TxFee json.Uint64 `json:"txFee"` CreateSubnetTxFee json.Uint64 `json:"createSubnetTxFee"` TransformSubnetTxFee json.Uint64 `json:"transformSubnetTxFee"` CreateBlockchainTxFee json.Uint64 `json:"createBlockchainTxFee"` @@ -404,15 +397,15 @@ func (i *Info) GetTxFee(_ *http.Request, _ *struct{}, reply *GetTxFeeResponse) e zap.String("method", "getTxFee"), ) - reply.TxFee = json.Uint64(i.TxFee) - reply.CreateAssetTxFee = json.Uint64(i.CreateAssetTxFee) - reply.CreateSubnetTxFee = json.Uint64(i.CreateSubnetTxFee) - reply.TransformSubnetTxFee = json.Uint64(i.TransformSubnetTxFee) - reply.CreateBlockchainTxFee = json.Uint64(i.CreateBlockchainTxFee) - reply.AddPrimaryNetworkValidatorFee = json.Uint64(i.AddPrimaryNetworkValidatorFee) - reply.AddPrimaryNetworkDelegatorFee = json.Uint64(i.AddPrimaryNetworkDelegatorFee) - reply.AddSubnetValidatorFee = json.Uint64(i.AddSubnetValidatorFee) - reply.AddSubnetDelegatorFee = json.Uint64(i.AddSubnetDelegatorFee) + reply.CreateAssetTxFee = json.Uint64(i.TxFeeConfig.CreateAssetTxFee) + reply.TxFee = json.Uint64(i.TxFeeConfig.TxFee) + reply.CreateSubnetTxFee = json.Uint64(i.TxFeeConfig.CreateSubnetTxFee) + reply.TransformSubnetTxFee = json.Uint64(i.TxFeeConfig.TransformSubnetTxFee) + reply.CreateBlockchainTxFee = json.Uint64(i.TxFeeConfig.CreateBlockchainTxFee) + reply.AddPrimaryNetworkValidatorFee = json.Uint64(i.TxFeeConfig.AddPrimaryNetworkValidatorFee) + reply.AddPrimaryNetworkDelegatorFee = json.Uint64(i.TxFeeConfig.AddPrimaryNetworkDelegatorFee) + reply.AddSubnetValidatorFee = json.Uint64(i.TxFeeConfig.AddSubnetValidatorFee) + reply.AddSubnetDelegatorFee = json.Uint64(i.TxFeeConfig.AddSubnetDelegatorFee) return nil } diff --git a/config/config.go b/config/config.go index 422eceedb6e9..9c7427225060 100644 --- a/config/config.go +++ b/config/config.go @@ -762,18 +762,20 @@ func getStakingConfig(v *viper.Viper, networkID uint32) (node.StakingConfig, err return config, nil } -func getTxFeeConfig(v *viper.Viper, networkID uint32) fee.StaticConfig { +func getTxFeeConfig(v *viper.Viper, networkID uint32) genesis.TxFeeConfig { if networkID != constants.MainnetID && networkID != constants.FujiID { - return fee.StaticConfig{ - TxFee: v.GetUint64(TxFeeKey), - CreateAssetTxFee: v.GetUint64(CreateAssetTxFeeKey), - CreateSubnetTxFee: v.GetUint64(CreateSubnetTxFeeKey), - TransformSubnetTxFee: v.GetUint64(TransformSubnetTxFeeKey), - CreateBlockchainTxFee: v.GetUint64(CreateBlockchainTxFeeKey), - AddPrimaryNetworkValidatorFee: v.GetUint64(AddPrimaryNetworkValidatorFeeKey), - AddPrimaryNetworkDelegatorFee: v.GetUint64(AddPrimaryNetworkDelegatorFeeKey), - AddSubnetValidatorFee: v.GetUint64(AddSubnetValidatorFeeKey), - AddSubnetDelegatorFee: v.GetUint64(AddSubnetDelegatorFeeKey), + return genesis.TxFeeConfig{ + StaticConfig: fee.StaticConfig{ + TxFee: v.GetUint64(TxFeeKey), + CreateSubnetTxFee: v.GetUint64(CreateSubnetTxFeeKey), + TransformSubnetTxFee: v.GetUint64(TransformSubnetTxFeeKey), + CreateBlockchainTxFee: v.GetUint64(CreateBlockchainTxFeeKey), + AddPrimaryNetworkValidatorFee: v.GetUint64(AddPrimaryNetworkValidatorFeeKey), + AddPrimaryNetworkDelegatorFee: v.GetUint64(AddPrimaryNetworkDelegatorFeeKey), + AddSubnetValidatorFee: v.GetUint64(AddSubnetValidatorFeeKey), + AddSubnetDelegatorFee: v.GetUint64(AddSubnetDelegatorFeeKey), + }, + CreateAssetTxFee: v.GetUint64(CreateAssetTxFeeKey), } } return genesis.GetTxFeeConfig(networkID) @@ -1329,7 +1331,7 @@ func GetNodeConfig(v *viper.Viper) (node.Config, error) { nodeConfig.FdLimit = v.GetUint64(FdLimitKey) // Tx Fee - nodeConfig.StaticConfig = getTxFeeConfig(v, nodeConfig.NetworkID) + nodeConfig.TxFeeConfig = getTxFeeConfig(v, nodeConfig.NetworkID) // Genesis Data genesisStakingCfg := nodeConfig.StakingConfig.StakingConfig diff --git a/genesis/genesis_fuji.go b/genesis/genesis_fuji.go index 06cd2dd143ac..359eb381c65e 100644 --- a/genesis/genesis_fuji.go +++ b/genesis/genesis_fuji.go @@ -19,16 +19,18 @@ var ( // FujiParams are the params used for the fuji testnet FujiParams = Params{ - StaticConfig: fee.StaticConfig{ - TxFee: units.MilliAvax, - CreateAssetTxFee: 10 * units.MilliAvax, - CreateSubnetTxFee: 100 * units.MilliAvax, - TransformSubnetTxFee: 1 * units.Avax, - CreateBlockchainTxFee: 100 * units.MilliAvax, - AddPrimaryNetworkValidatorFee: 0, - AddPrimaryNetworkDelegatorFee: 0, - AddSubnetValidatorFee: units.MilliAvax, - AddSubnetDelegatorFee: units.MilliAvax, + TxFeeConfig: TxFeeConfig{ + StaticConfig: fee.StaticConfig{ + TxFee: units.MilliAvax, + CreateSubnetTxFee: 100 * units.MilliAvax, + TransformSubnetTxFee: 1 * units.Avax, + CreateBlockchainTxFee: 100 * units.MilliAvax, + AddPrimaryNetworkValidatorFee: 0, + AddPrimaryNetworkDelegatorFee: 0, + AddSubnetValidatorFee: units.MilliAvax, + AddSubnetDelegatorFee: units.MilliAvax, + }, + CreateAssetTxFee: 10 * units.MilliAvax, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/genesis_local.go b/genesis/genesis_local.go index 72f180ce3445..6beeed99d8b9 100644 --- a/genesis/genesis_local.go +++ b/genesis/genesis_local.go @@ -37,16 +37,18 @@ var ( // LocalParams are the params used for local networks LocalParams = Params{ - StaticConfig: fee.StaticConfig{ - TxFee: units.MilliAvax, - CreateAssetTxFee: units.MilliAvax, - CreateSubnetTxFee: 100 * units.MilliAvax, - TransformSubnetTxFee: 100 * units.MilliAvax, - CreateBlockchainTxFee: 100 * units.MilliAvax, - AddPrimaryNetworkValidatorFee: 0, - AddPrimaryNetworkDelegatorFee: 0, - AddSubnetValidatorFee: units.MilliAvax, - AddSubnetDelegatorFee: units.MilliAvax, + TxFeeConfig: TxFeeConfig{ + StaticConfig: fee.StaticConfig{ + TxFee: units.MilliAvax, + CreateSubnetTxFee: 100 * units.MilliAvax, + TransformSubnetTxFee: 100 * units.MilliAvax, + CreateBlockchainTxFee: 100 * units.MilliAvax, + AddPrimaryNetworkValidatorFee: 0, + AddPrimaryNetworkDelegatorFee: 0, + AddSubnetValidatorFee: units.MilliAvax, + AddSubnetDelegatorFee: units.MilliAvax, + }, + CreateAssetTxFee: units.MilliAvax, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/genesis_mainnet.go b/genesis/genesis_mainnet.go index 94eae11cb2c8..0d932729e595 100644 --- a/genesis/genesis_mainnet.go +++ b/genesis/genesis_mainnet.go @@ -19,16 +19,18 @@ var ( // MainnetParams are the params used for mainnet MainnetParams = Params{ - StaticConfig: fee.StaticConfig{ - TxFee: units.MilliAvax, - CreateAssetTxFee: 10 * units.MilliAvax, - CreateSubnetTxFee: 1 * units.Avax, - TransformSubnetTxFee: 10 * units.Avax, - CreateBlockchainTxFee: 1 * units.Avax, - AddPrimaryNetworkValidatorFee: 0, - AddPrimaryNetworkDelegatorFee: 0, - AddSubnetValidatorFee: units.MilliAvax, - AddSubnetDelegatorFee: units.MilliAvax, + TxFeeConfig: TxFeeConfig{ + StaticConfig: fee.StaticConfig{ + TxFee: units.MilliAvax, + CreateSubnetTxFee: 1 * units.Avax, + TransformSubnetTxFee: 10 * units.Avax, + CreateBlockchainTxFee: 1 * units.Avax, + AddPrimaryNetworkValidatorFee: 0, + AddPrimaryNetworkDelegatorFee: 0, + AddSubnetValidatorFee: units.MilliAvax, + AddSubnetDelegatorFee: units.MilliAvax, + }, + CreateAssetTxFee: 10 * units.MilliAvax, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/params.go b/genesis/params.go index 6d4f5f4d978f..1975db66ad27 100644 --- a/genesis/params.go +++ b/genesis/params.go @@ -34,21 +34,26 @@ type StakingConfig struct { RewardConfig reward.Config `json:"rewardConfig"` } +type TxFeeConfig struct { + fee.StaticConfig + CreateAssetTxFee uint64 `json:"createAssetTxFee"` +} + type Params struct { + TxFeeConfig StakingConfig - fee.StaticConfig } -func GetTxFeeConfig(networkID uint32) fee.StaticConfig { +func GetTxFeeConfig(networkID uint32) TxFeeConfig { switch networkID { case constants.MainnetID: - return MainnetParams.StaticConfig + return MainnetParams.TxFeeConfig case constants.FujiID: - return FujiParams.StaticConfig + return FujiParams.TxFeeConfig case constants.LocalID: - return LocalParams.StaticConfig + return LocalParams.TxFeeConfig default: - return LocalParams.StaticConfig + return LocalParams.TxFeeConfig } } diff --git a/node/config.go b/node/config.go index 6f8d3e1ec549..7ca0cadee9e1 100644 --- a/node/config.go +++ b/node/config.go @@ -23,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/utils/profiler" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) type APIIndexerConfig struct { @@ -123,13 +122,13 @@ type DatabaseConfig struct { // Config contains all of the configurations of an Avalanche node. type Config struct { - HTTPConfig `json:"httpConfig"` - IPConfig `json:"ipConfig"` - StakingConfig `json:"stakingConfig"` - fee.StaticConfig `json:"txFeeConfig"` - StateSyncConfig `json:"stateSyncConfig"` - BootstrapConfig `json:"bootstrapConfig"` - DatabaseConfig `json:"databaseConfig"` + HTTPConfig `json:"httpConfig"` + IPConfig `json:"ipConfig"` + StakingConfig `json:"stakingConfig"` + genesis.TxFeeConfig `json:"txFeeConfig"` + StateSyncConfig `json:"stateSyncConfig"` + BootstrapConfig `json:"bootstrapConfig"` + DatabaseConfig `json:"databaseConfig"` // Genesis information GenesisBytes []byte `json:"-"` diff --git a/node/node.go b/node/node.go index fe574b17ea52..e37b34ba060d 100644 --- a/node/node.go +++ b/node/node.go @@ -1421,20 +1421,12 @@ func (n *Node) initInfoAPI() error { service, err := info.NewService( info.Parameters{ - Version: version.CurrentApp, - NodeID: n.ID, - NodePOP: signer.NewProofOfPossession(n.Config.StakingSigningKey), - NetworkID: n.Config.NetworkID, - TxFee: n.Config.TxFee, - CreateAssetTxFee: n.Config.CreateAssetTxFee, - CreateSubnetTxFee: n.Config.CreateSubnetTxFee, - TransformSubnetTxFee: n.Config.TransformSubnetTxFee, - CreateBlockchainTxFee: n.Config.CreateBlockchainTxFee, - AddPrimaryNetworkValidatorFee: n.Config.AddPrimaryNetworkValidatorFee, - AddPrimaryNetworkDelegatorFee: n.Config.AddPrimaryNetworkDelegatorFee, - AddSubnetValidatorFee: n.Config.AddSubnetValidatorFee, - AddSubnetDelegatorFee: n.Config.AddSubnetDelegatorFee, - VMManager: n.VMManager, + Version: version.CurrentApp, + NodeID: n.ID, + NodePOP: signer.NewProofOfPossession(n.Config.StakingSigningKey), + NetworkID: n.Config.NetworkID, + TxFeeConfig: n.Config.TxFeeConfig, + VMManager: n.VMManager, }, n.Log, n.vdrs, diff --git a/tests/antithesis/avalanchego/main.go b/tests/antithesis/avalanchego/main.go index a7101b6bc3cb..ae8f0bb051e8 100644 --- a/tests/antithesis/avalanchego/main.go +++ b/tests/antithesis/avalanchego/main.go @@ -412,7 +412,7 @@ func (w *workload) issueXToPTransfer(ctx context.Context) { xBaseTxFee = xContext.BaseTxFee pBuilder = pWallet.Builder() pContext = pBuilder.Context() - pBaseTxFee = pContext.BaseTxFee + pBaseTxFee = pContext.StaticFeeConfig.TxFee txFees = xBaseTxFee + pBaseTxFee neededBalance = txFees + units.Avax ) @@ -484,7 +484,7 @@ func (w *workload) issuePToXTransfer(ctx context.Context) { pContext = pBuilder.Context() avaxAssetID = pContext.AVAXAssetID avaxBalance = balances[avaxAssetID] - pBaseTxFee = pContext.BaseTxFee + pBaseTxFee = pContext.StaticFeeConfig.TxFee xBaseTxFee = xContext.BaseTxFee txFees = pBaseTxFee + xBaseTxFee neededBalance = txFees + units.Schmeckle diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index fcd38a9d72be..5d648344109a 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -168,10 +168,8 @@ func (v *verifier) ApricotProposalBlock(b *block.ApricotProposalBlock) error { } var ( - staticFeeConfig = v.txExecutorBackend.Config.StaticFeeConfig - upgradeConfig = v.txExecutorBackend.Config.UpgradeConfig - timestamp = onCommitState.GetTimestamp() // Equal to parent timestamp - feeCalculator = fee.NewStaticCalculator(staticFeeConfig, upgradeConfig, timestamp) + timestamp = onCommitState.GetTimestamp() // Equal to parent timestamp + feeCalculator = state.NewStaticFeeCalculator(v.txExecutorBackend.Config, timestamp) ) return v.proposalBlock(b, nil, onCommitState, onAbortState, feeCalculator, nil, nil, nil) } @@ -188,10 +186,8 @@ func (v *verifier) ApricotStandardBlock(b *block.ApricotStandardBlock) error { } var ( - staticFeeConfig = v.txExecutorBackend.Config.StaticFeeConfig - upgradeConfig = v.txExecutorBackend.Config.UpgradeConfig - timestamp = onAcceptState.GetTimestamp() // Equal to parent timestamp - feeCalculator = fee.NewStaticCalculator(staticFeeConfig, upgradeConfig, timestamp) + timestamp = onAcceptState.GetTimestamp() // Equal to parent timestamp + feeCalculator = state.NewStaticFeeCalculator(v.txExecutorBackend.Config, timestamp) ) return v.standardBlock(b, feeCalculator, onAcceptState) } @@ -215,7 +211,7 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { ) } - feeCalculator := fee.NewStaticCalculator(v.txExecutorBackend.Config.StaticFeeConfig, v.txExecutorBackend.Config.UpgradeConfig, currentTimestamp) + feeCalculator := state.NewStaticFeeCalculator(v.txExecutorBackend.Config, currentTimestamp) atomicExecutor := executor.AtomicTxExecutor{ Backend: v.txExecutorBackend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 731b079ca425..ee457047e5a6 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -32,7 +32,8 @@ type Config struct { Validators validators.Manager // All static fees config active before E-upgrade - StaticFeeConfig fee.StaticConfig + CreateAssetTxFee uint64 // Override for CreateSubnet and CreateChain before AP3 + StaticFeeConfig fee.StaticConfig // Provides access to the uptime manager as a thread safe data structure UptimeLockedCalculator uptime.LockedCalculator diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 97d7d0466894..d05b698ba971 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -769,7 +769,7 @@ func TestGetBlock(t *testing.T) { service, _, factory := defaultService(t) service.vm.ctx.Lock.Lock() - service.vm.StaticFeeConfig.CreateAssetTxFee = 100 * defaultTxFee + service.vm.Config.CreateAssetTxFee = 100 * defaultTxFee builder, signer := factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) utx, err := builder.NewCreateChainTx( diff --git a/vms/platformvm/state/chain_time_helpers.go b/vms/platformvm/state/chain_time_helpers.go index 22fa97a7ac3c..03d373b346dc 100644 --- a/vms/platformvm/state/chain_time_helpers.go +++ b/vms/platformvm/state/chain_time_helpers.go @@ -77,5 +77,19 @@ func GetNextStakerChangeTime(state Chain) (time.Time, error) { // PickFeeCalculator does not modify [state]. func PickFeeCalculator(cfg *config.Config, state Chain) (fee.Calculator, error) { timestamp := state.GetTimestamp() - return fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, timestamp), nil + return NewStaticFeeCalculator(cfg, timestamp), nil +} + +// PickFeeCalculator creates either a static or a dynamic fee calculator, +// depending on the active upgrade. +// +// PickFeeCalculator does not modify [state]. +func NewStaticFeeCalculator(cfg *config.Config, timestamp time.Time) fee.Calculator { + if !cfg.UpgradeConfig.IsApricotPhase3Activated(timestamp) { + config := cfg.StaticFeeConfig + config.CreateSubnetTxFee = cfg.CreateAssetTxFee + config.CreateBlockchainTxFee = cfg.CreateAssetTxFee + return fee.NewStaticCalculator(config) + } + return fee.NewStaticCalculator(cfg.StaticFeeConfig) } diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 54694633a850..0684acd48737 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -53,12 +53,24 @@ var ( expectedStaticFee: testStaticConfig.AddPrimaryNetworkValidatorFee, expectedStaticFeeErr: nil, }, + { + name: "AddPermissionlessValidatorTx for subnet", + tx: "000000000019000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000070000000000006091000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba6c9980000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000002038b42b73d3dc695c76ca12f966e97fe0681b1200f9a5e28d088720a18ea23c9000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000609b0000000100000000a378b74b3293a9d885bd9961f2cc2e1b3364d393c9be875964f2bd614214572c00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba7bdbc0000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa0000000066a57a160000000066b7ef16000000000000000a97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000001b000000012f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000000a000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000000000000000000000b00000000000000000000000000000000000f4240000000020000000900000001593fc20f88a8ce0b3470b0bb103e5f7e09f65023b6515d36660da53f9a15dedc1037ee27a8c4a27c24e20ad3b0ab4bd1ff3a02a6fcc2cbe04282bfe9902c9ae6000000000900000001593fc20f88a8ce0b3470b0bb103e5f7e09f65023b6515d36660da53f9a15dedc1037ee27a8c4a27c24e20ad3b0ab4bd1ff3a02a6fcc2cbe04282bfe9902c9ae600", + expectedStaticFee: testStaticConfig.AddSubnetValidatorFee, + expectedStaticFeeErr: nil, + }, { name: "AddPermissionlessDelegatorTx for primary network", tx: "00000000001a00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1140fe00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000017d199179744b3b82d0071c83c2fb7dd6b95a2cdbe9dde295e0ae4f8c2287370300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba8b1e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae6080000000066ad5b08000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000100000009000000012261556f74a29f02ffc2725a567db2c81f75d0892525dbebaa1cf8650534cc70061123533a9553184cb02d899943ff0bf0b39c77b173c133854bc7c8bc7ab9a400", expectedStaticFee: testStaticConfig.AddPrimaryNetworkDelegatorFee, expectedStaticFeeErr: nil, }, + { + name: "AddPermissionlessDelegatorTx for subnet", + tx: "00000000001a000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000070000000000006087000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700470c1336195b80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000029494c80361884942e4292c3531e8e790fcf7561e74404ded27eab8634e3fb30f000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000609100000001000000009494c80361884942e4292c3531e8e790fcf7561e74404ded27eab8634e3fb30f00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500470c1336289dc0000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa0000000066a57c1d0000000066b7f11d000000000000000a97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c124000000012f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000000a000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b00000000000000000000000000000000000000020000000900000001764190e2405fef72fce0d355e3dcc58a9f5621e583ae718cb2c23b55957995d1206d0b5efcc3cef99815e17a4b2cccd700147a759b7279a131745b237659666a000000000900000001764190e2405fef72fce0d355e3dcc58a9f5621e583ae718cb2c23b55957995d1206d0b5efcc3cef99815e17a4b2cccd700147a759b7279a131745b237659666a00", + expectedStaticFee: testStaticConfig.AddSubnetDelegatorFee, + expectedStaticFeeErr: nil, + }, { name: "AddSubnetValidatorTx", tx: "00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1131bbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000138f94d1a0514eaabdaf4c52cad8d62b26cee61eaa951f5b75a5e57c2ee3793c800000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1140fe00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae7c90000000066ad5cc9000000000000c13797ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000200000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb60000000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb600", @@ -101,6 +113,12 @@ var ( expectedStaticFee: testStaticConfig.TxFee, expectedStaticFeeErr: nil, }, + { + name: "TransformSubnetTx", + tx: "000000000018000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000609b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263c5fbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000294a113f31a30ee643288277574434f9066e0cdc1d53d6eb2610805c388814134000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000c137000000010000000094a113f31a30ee643288277574434f9066e0cdc1d53d6eb2610805c38881413400000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269bbdcc000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1242f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000000000609b000000000000c1370000000000000001000000000000000a0000000000000001000000000000006400127500001fa40000000001000000000000000a64000000010000000a00000001000000000000000300000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca820000000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca820000000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca8200", + expectedStaticFee: testStaticConfig.TransformSubnetTxFee, + expectedStaticFeeErr: nil, + }, { name: "TransferSubnetOwnershipTx", tx: "00000000002100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99bf1ec0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000018f6e5f2840e34f9a375f35627a44bb0b9974285d280dc3220aa9489f97b17ebd00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99ce610000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000b00000000000000000000000000000000000000020000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f010000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f01", diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index 80507c1a267d..5f453429c226 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -8,8 +8,6 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/vms/platformvm/config" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) @@ -18,22 +16,15 @@ func newContext( cfg *config.Config, timestamp time.Time, ) *builder.Context { - var ( - feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, timestamp) - createSubnetFee, _ = feeCalculator.CalculateFee(&txs.CreateSubnetTx{}) - createChainFee, _ = feeCalculator.CalculateFee(&txs.CreateChainTx{}) - ) + feeConfig := cfg.StaticFeeConfig + if !cfg.UpgradeConfig.IsApricotPhase3Activated(timestamp) { + feeConfig.CreateSubnetTxFee = cfg.CreateAssetTxFee + feeConfig.CreateBlockchainTxFee = cfg.CreateAssetTxFee + } return &builder.Context{ - NetworkID: ctx.NetworkID, - AVAXAssetID: ctx.AVAXAssetID, - BaseTxFee: cfg.StaticFeeConfig.TxFee, - CreateSubnetTxFee: createSubnetFee, - TransformSubnetTxFee: cfg.StaticFeeConfig.TransformSubnetTxFee, - CreateBlockchainTxFee: createChainFee, - AddPrimaryNetworkValidatorFee: cfg.StaticFeeConfig.AddPrimaryNetworkValidatorFee, - AddPrimaryNetworkDelegatorFee: cfg.StaticFeeConfig.AddPrimaryNetworkDelegatorFee, - AddSubnetValidatorFee: cfg.StaticFeeConfig.AddSubnetValidatorFee, - AddSubnetDelegatorFee: cfg.StaticFeeConfig.AddSubnetDelegatorFee, + NetworkID: ctx.NetworkID, + AVAXAssetID: ctx.AVAXAssetID, + StaticFeeConfig: feeConfig, } } diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index ffe6f937b89c..97e7388a3a47 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -311,7 +311,7 @@ func (b *builder) NewBaseTx( options ...common.Option, ) (*txs.BaseTx, error) { toBurn := map[ids.ID]uint64{ - b.context.AVAXAssetID: b.context.BaseTxFee, + b.context.AVAXAssetID: b.context.StaticFeeConfig.TxFee, } for _, out := range outputs { assetID := out.AssetID() @@ -349,7 +349,7 @@ func (b *builder) NewAddValidatorTx( ) (*txs.AddValidatorTx, error) { avaxAssetID := b.context.AVAXAssetID toBurn := map[ids.ID]uint64{ - avaxAssetID: b.context.AddPrimaryNetworkValidatorFee, + avaxAssetID: b.context.StaticFeeConfig.AddPrimaryNetworkValidatorFee, } toStake := map[ids.ID]uint64{ avaxAssetID: vdr.Wght, @@ -382,7 +382,7 @@ func (b *builder) NewAddSubnetValidatorTx( options ...common.Option, ) (*txs.AddSubnetValidatorTx, error) { toBurn := map[ids.ID]uint64{ - b.context.AVAXAssetID: b.context.AddSubnetValidatorFee, + b.context.AVAXAssetID: b.context.StaticFeeConfig.AddSubnetValidatorFee, } toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) @@ -416,7 +416,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( options ...common.Option, ) (*txs.RemoveSubnetValidatorTx, error) { toBurn := map[ids.ID]uint64{ - b.context.AVAXAssetID: b.context.BaseTxFee, + b.context.AVAXAssetID: b.context.StaticFeeConfig.TxFee, } toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) @@ -452,7 +452,7 @@ func (b *builder) NewAddDelegatorTx( ) (*txs.AddDelegatorTx, error) { avaxAssetID := b.context.AVAXAssetID toBurn := map[ids.ID]uint64{ - avaxAssetID: b.context.AddPrimaryNetworkDelegatorFee, + avaxAssetID: b.context.StaticFeeConfig.AddPrimaryNetworkDelegatorFee, } toStake := map[ids.ID]uint64{ avaxAssetID: vdr.Wght, @@ -488,7 +488,7 @@ func (b *builder) NewCreateChainTx( options ...common.Option, ) (*txs.CreateChainTx, error) { toBurn := map[ids.ID]uint64{ - b.context.AVAXAssetID: b.context.CreateBlockchainTxFee, + b.context.AVAXAssetID: b.context.StaticFeeConfig.CreateBlockchainTxFee, } toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) @@ -526,7 +526,7 @@ func (b *builder) NewCreateSubnetTx( options ...common.Option, ) (*txs.CreateSubnetTx, error) { toBurn := map[ids.ID]uint64{ - b.context.AVAXAssetID: b.context.CreateSubnetTxFee, + b.context.AVAXAssetID: b.context.StaticFeeConfig.CreateSubnetTxFee, } toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) @@ -555,7 +555,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( options ...common.Option, ) (*txs.TransferSubnetOwnershipTx, error) { toBurn := map[ids.ID]uint64{ - b.context.AVAXAssetID: b.context.BaseTxFee, + b.context.AVAXAssetID: b.context.StaticFeeConfig.TxFee, } toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) @@ -600,7 +600,7 @@ func (b *builder) NewImportTx( addrs = ops.Addresses(b.addrs) minIssuanceTime = ops.MinIssuanceTime() avaxAssetID = b.context.AVAXAssetID - txFee = b.context.BaseTxFee + txFee = b.context.StaticFeeConfig.TxFee importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) importedAmounts = make(map[ids.ID]uint64) @@ -698,7 +698,7 @@ func (b *builder) NewExportTx( options ...common.Option, ) (*txs.ExportTx, error) { toBurn := map[ids.ID]uint64{ - b.context.AVAXAssetID: b.context.BaseTxFee, + b.context.AVAXAssetID: b.context.StaticFeeConfig.TxFee, } for _, out := range outputs { assetID := out.AssetID() @@ -749,7 +749,7 @@ func (b *builder) NewTransformSubnetTx( options ...common.Option, ) (*txs.TransformSubnetTx, error) { toBurn := map[ids.ID]uint64{ - b.context.AVAXAssetID: b.context.TransformSubnetTxFee, + b.context.AVAXAssetID: b.context.StaticFeeConfig.TransformSubnetTxFee, assetID: maxSupply - initialSupply, } toStake := map[ids.ID]uint64{} @@ -803,9 +803,9 @@ func (b *builder) NewAddPermissionlessValidatorTx( avaxAssetID := b.context.AVAXAssetID toBurn := map[ids.ID]uint64{} if vdr.Subnet == constants.PrimaryNetworkID { - toBurn[avaxAssetID] = b.context.AddPrimaryNetworkValidatorFee + toBurn[avaxAssetID] = b.context.StaticFeeConfig.AddPrimaryNetworkValidatorFee } else { - toBurn[avaxAssetID] = b.context.AddSubnetValidatorFee + toBurn[avaxAssetID] = b.context.StaticFeeConfig.AddSubnetValidatorFee } toStake := map[ids.ID]uint64{ assetID: vdr.Wght, @@ -846,9 +846,9 @@ func (b *builder) NewAddPermissionlessDelegatorTx( avaxAssetID := b.context.AVAXAssetID toBurn := map[ids.ID]uint64{} if vdr.Subnet == constants.PrimaryNetworkID { - toBurn[avaxAssetID] = b.context.AddPrimaryNetworkDelegatorFee + toBurn[avaxAssetID] = b.context.StaticFeeConfig.AddPrimaryNetworkDelegatorFee } else { - toBurn[avaxAssetID] = b.context.AddSubnetDelegatorFee + toBurn[avaxAssetID] = b.context.StaticFeeConfig.AddSubnetDelegatorFee } toStake := map[ids.ID]uint64{ assetID: vdr.Wght, diff --git a/wallet/chain/p/builder/context.go b/wallet/chain/p/builder/context.go index f0da23fdc5f9..33eb5ecf0af5 100644 --- a/wallet/chain/p/builder/context.go +++ b/wallet/chain/p/builder/context.go @@ -12,21 +12,15 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/avm" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) const Alias = "P" type Context struct { - NetworkID uint32 - AVAXAssetID ids.ID - BaseTxFee uint64 - CreateSubnetTxFee uint64 - TransformSubnetTxFee uint64 - CreateBlockchainTxFee uint64 - AddPrimaryNetworkValidatorFee uint64 - AddPrimaryNetworkDelegatorFee uint64 - AddSubnetValidatorFee uint64 - AddSubnetDelegatorFee uint64 + NetworkID uint32 + AVAXAssetID ids.ID + StaticFeeConfig fee.StaticConfig } func NewContextFromURI(ctx context.Context, uri string) (*Context, error) { @@ -56,16 +50,18 @@ func NewContextFromClients( } return &Context{ - NetworkID: networkID, - AVAXAssetID: asset.AssetID, - BaseTxFee: uint64(txFees.TxFee), - CreateSubnetTxFee: uint64(txFees.CreateSubnetTxFee), - TransformSubnetTxFee: uint64(txFees.TransformSubnetTxFee), - CreateBlockchainTxFee: uint64(txFees.CreateBlockchainTxFee), - AddPrimaryNetworkValidatorFee: uint64(txFees.AddPrimaryNetworkValidatorFee), - AddPrimaryNetworkDelegatorFee: uint64(txFees.AddPrimaryNetworkDelegatorFee), - AddSubnetValidatorFee: uint64(txFees.AddSubnetValidatorFee), - AddSubnetDelegatorFee: uint64(txFees.AddSubnetDelegatorFee), + NetworkID: networkID, + AVAXAssetID: asset.AssetID, + StaticFeeConfig: fee.StaticConfig{ + TxFee: uint64(txFees.TxFee), + CreateSubnetTxFee: uint64(txFees.CreateSubnetTxFee), + TransformSubnetTxFee: uint64(txFees.TransformSubnetTxFee), + CreateBlockchainTxFee: uint64(txFees.CreateBlockchainTxFee), + AddPrimaryNetworkValidatorFee: uint64(txFees.AddPrimaryNetworkValidatorFee), + AddPrimaryNetworkDelegatorFee: uint64(txFees.AddPrimaryNetworkDelegatorFee), + AddSubnetValidatorFee: uint64(txFees.AddSubnetValidatorFee), + AddSubnetDelegatorFee: uint64(txFees.AddSubnetDelegatorFee), + }, }, nil } diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index bba5644cbec6..fcc323cb7dd4 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -20,6 +20,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/chain/p/builder" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -34,16 +35,18 @@ var ( subnetAssetID = ids.Empty.Prefix(2024) testContext = &builder.Context{ - NetworkID: constants.UnitTestID, - AVAXAssetID: avaxAssetID, - BaseTxFee: units.MicroAvax, - CreateSubnetTxFee: 19 * units.MicroAvax, - TransformSubnetTxFee: 789 * units.MicroAvax, - CreateBlockchainTxFee: 1234 * units.MicroAvax, - AddPrimaryNetworkValidatorFee: 19 * units.MilliAvax, - AddPrimaryNetworkDelegatorFee: 765 * units.MilliAvax, - AddSubnetValidatorFee: 1010 * units.MilliAvax, - AddSubnetDelegatorFee: 9 * units.Avax, + NetworkID: constants.UnitTestID, + AVAXAssetID: avaxAssetID, + StaticFeeConfig: fee.StaticConfig{ + TxFee: units.MicroAvax, + CreateSubnetTxFee: 19 * units.MicroAvax, + TransformSubnetTxFee: 789 * units.MicroAvax, + CreateBlockchainTxFee: 1234 * units.MicroAvax, + AddPrimaryNetworkValidatorFee: 19 * units.MilliAvax, + AddPrimaryNetworkDelegatorFee: 765 * units.MilliAvax, + AddSubnetValidatorFee: 1010 * units.MilliAvax, + AddSubnetDelegatorFee: 9 * units.Avax, + }, } ) @@ -90,7 +93,7 @@ func TestBaseTx(t *testing.T) { addAmounts( addOutputAmounts(utx.Outs), map[ids.ID]uint64{ - avaxAssetID: testContext.BaseTxFee, + avaxAssetID: testContext.StaticFeeConfig.TxFee, }, ), addInputAmounts(utx.Ins), @@ -148,7 +151,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { addAmounts( addOutputAmounts(utx.Outs), map[ids.ID]uint64{ - avaxAssetID: testContext.AddSubnetValidatorFee, + avaxAssetID: testContext.StaticFeeConfig.AddSubnetValidatorFee, }, ), addInputAmounts(utx.Ins), @@ -200,7 +203,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { addAmounts( addOutputAmounts(utx.Outs), map[ids.ID]uint64{ - avaxAssetID: testContext.BaseTxFee, + avaxAssetID: testContext.StaticFeeConfig.TxFee, }, ), addInputAmounts(utx.Ins), @@ -260,7 +263,7 @@ func TestCreateChainTx(t *testing.T) { addAmounts( addOutputAmounts(utx.Outs), map[ids.ID]uint64{ - avaxAssetID: testContext.CreateBlockchainTxFee, + avaxAssetID: testContext.StaticFeeConfig.CreateBlockchainTxFee, }, ), addInputAmounts(utx.Ins), @@ -309,7 +312,7 @@ func TestCreateSubnetTx(t *testing.T) { addAmounts( addOutputAmounts(utx.Outs), map[ids.ID]uint64{ - avaxAssetID: testContext.CreateSubnetTxFee, + avaxAssetID: testContext.StaticFeeConfig.CreateSubnetTxFee, }, ), addInputAmounts(utx.Ins), @@ -361,7 +364,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { addAmounts( addOutputAmounts(utx.Outs), map[ids.ID]uint64{ - avaxAssetID: testContext.BaseTxFee, + avaxAssetID: testContext.StaticFeeConfig.TxFee, }, ), addInputAmounts(utx.Ins), @@ -412,7 +415,7 @@ func TestImportTx(t *testing.T) { addAmounts( addOutputAmounts(utx.Outs), map[ids.ID]uint64{ - avaxAssetID: testContext.BaseTxFee, + avaxAssetID: testContext.StaticFeeConfig.TxFee, }, ), addInputAmounts(utx.Ins, utx.ImportedInputs), @@ -463,7 +466,7 @@ func TestExportTx(t *testing.T) { addAmounts( addOutputAmounts(utx.Outs, utx.ExportedOutputs), map[ids.ID]uint64{ - avaxAssetID: testContext.BaseTxFee, + avaxAssetID: testContext.StaticFeeConfig.TxFee, }, ), addInputAmounts(utx.Ins), @@ -531,7 +534,7 @@ func TestTransformSubnetTx(t *testing.T) { addAmounts( addOutputAmounts(utx.Outs), map[ids.ID]uint64{ - avaxAssetID: testContext.TransformSubnetTxFee, + avaxAssetID: testContext.StaticFeeConfig.TransformSubnetTxFee, subnetAssetID: maxSupply - initialSupply, }, ), @@ -569,9 +572,9 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { var ( utxos = []*avax.UTXO{ - makeUTXO(testContext.AddPrimaryNetworkValidatorFee), // UTXO to pay the fee - makeUTXO(1 * units.NanoAvax), // small UTXO - makeUTXO(9 * units.Avax), // large UTXO + makeUTXO(testContext.StaticFeeConfig.AddPrimaryNetworkValidatorFee), // UTXO to pay the fee + makeUTXO(1 * units.NanoAvax), // small UTXO + makeUTXO(9 * units.Avax), // large UTXO } chainUTXOs = common.NewDeterministicChainUTXOs(require, map[ids.ID][]*avax.UTXO{ constants.PlatformChainID: utxos, @@ -633,7 +636,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { addAmounts( addOutputAmounts(utx.Outs, utx.StakeOuts), map[ids.ID]uint64{ - avaxAssetID: testContext.AddPrimaryNetworkValidatorFee, + avaxAssetID: testContext.StaticFeeConfig.AddPrimaryNetworkValidatorFee, }, ), addInputAmounts(utx.Ins), @@ -700,7 +703,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { addAmounts( addOutputAmounts(utx.Outs, utx.StakeOuts), map[ids.ID]uint64{ - avaxAssetID: testContext.AddPrimaryNetworkDelegatorFee, + avaxAssetID: testContext.StaticFeeConfig.AddPrimaryNetworkDelegatorFee, }, ), addInputAmounts(utx.Ins), From d09b77daeb436271751eb6ae2f418943b44adbe6 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 27 Jul 2024 19:48:07 -0400 Subject: [PATCH 090/100] reduce diff --- api/info/service.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/info/service.go b/api/info/service.go index 714fefe16d96..072c5223cd52 100644 --- a/api/info/service.go +++ b/api/info/service.go @@ -379,8 +379,8 @@ func (i *Info) Acps(_ *http.Request, _ *struct{}, reply *ACPsReply) error { } type GetTxFeeResponse struct { - CreateAssetTxFee json.Uint64 `json:"createAssetTxFee"` TxFee json.Uint64 `json:"txFee"` + CreateAssetTxFee json.Uint64 `json:"createAssetTxFee"` CreateSubnetTxFee json.Uint64 `json:"createSubnetTxFee"` TransformSubnetTxFee json.Uint64 `json:"transformSubnetTxFee"` CreateBlockchainTxFee json.Uint64 `json:"createBlockchainTxFee"` @@ -397,8 +397,8 @@ func (i *Info) GetTxFee(_ *http.Request, _ *struct{}, reply *GetTxFeeResponse) e zap.String("method", "getTxFee"), ) - reply.CreateAssetTxFee = json.Uint64(i.TxFeeConfig.CreateAssetTxFee) reply.TxFee = json.Uint64(i.TxFeeConfig.TxFee) + reply.CreateAssetTxFee = json.Uint64(i.TxFeeConfig.CreateAssetTxFee) reply.CreateSubnetTxFee = json.Uint64(i.TxFeeConfig.CreateSubnetTxFee) reply.TransformSubnetTxFee = json.Uint64(i.TxFeeConfig.TransformSubnetTxFee) reply.CreateBlockchainTxFee = json.Uint64(i.TxFeeConfig.CreateBlockchainTxFee) From 23d8bbf42b4e7d3747153414cc395148f16ab08d Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 27 Jul 2024 19:49:32 -0400 Subject: [PATCH 091/100] reduce diff --- genesis/params.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/genesis/params.go b/genesis/params.go index 1975db66ad27..b875d8bde325 100644 --- a/genesis/params.go +++ b/genesis/params.go @@ -40,8 +40,8 @@ type TxFeeConfig struct { } type Params struct { - TxFeeConfig StakingConfig + TxFeeConfig } func GetTxFeeConfig(networkID uint32) TxFeeConfig { From 726b6397702dd3ca9cb31010b12922e3f881ff2e Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 27 Jul 2024 19:51:16 -0400 Subject: [PATCH 092/100] populate field --- node/node.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/node.go b/node/node.go index e37b34ba060d..5898f5c60a4e 100644 --- a/node/node.go +++ b/node/node.go @@ -1227,6 +1227,7 @@ func (n *Node) initVMs() error { SybilProtectionEnabled: n.Config.SybilProtectionEnabled, PartialSyncPrimaryNetwork: n.Config.PartialSyncPrimaryNetwork, TrackedSubnets: n.Config.TrackedSubnets, + CreateAssetTxFee: n.Config.CreateAssetTxFee, StaticFeeConfig: n.Config.StaticConfig, UptimePercentage: n.Config.UptimeRequirement, MinValidatorStake: n.Config.MinValidatorStake, From ce017a9255b0155caf321ffb9e9790551fec4a16 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 27 Jul 2024 19:53:30 -0400 Subject: [PATCH 093/100] nit --- vms/platformvm/state/chain_time_helpers.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vms/platformvm/state/chain_time_helpers.go b/vms/platformvm/state/chain_time_helpers.go index 03d373b346dc..d1e5c8f0a7bb 100644 --- a/vms/platformvm/state/chain_time_helpers.go +++ b/vms/platformvm/state/chain_time_helpers.go @@ -80,10 +80,8 @@ func PickFeeCalculator(cfg *config.Config, state Chain) (fee.Calculator, error) return NewStaticFeeCalculator(cfg, timestamp), nil } -// PickFeeCalculator creates either a static or a dynamic fee calculator, -// depending on the active upgrade. -// -// PickFeeCalculator does not modify [state]. +// NewStaticFeeCalculator creates a static fee calculator, with the config set +// to either the pre-AP3 or post-AP3 config. func NewStaticFeeCalculator(cfg *config.Config, timestamp time.Time) fee.Calculator { if !cfg.UpgradeConfig.IsApricotPhase3Activated(timestamp) { config := cfg.StaticFeeConfig From d8228df8171e5e38a1d4dbc253ec57c6d3358010 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 27 Jul 2024 19:54:24 -0400 Subject: [PATCH 094/100] nit --- vms/platformvm/state/chain_time_helpers.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/vms/platformvm/state/chain_time_helpers.go b/vms/platformvm/state/chain_time_helpers.go index d1e5c8f0a7bb..e18bbfd1132d 100644 --- a/vms/platformvm/state/chain_time_helpers.go +++ b/vms/platformvm/state/chain_time_helpers.go @@ -83,11 +83,10 @@ func PickFeeCalculator(cfg *config.Config, state Chain) (fee.Calculator, error) // NewStaticFeeCalculator creates a static fee calculator, with the config set // to either the pre-AP3 or post-AP3 config. func NewStaticFeeCalculator(cfg *config.Config, timestamp time.Time) fee.Calculator { + config := cfg.StaticFeeConfig if !cfg.UpgradeConfig.IsApricotPhase3Activated(timestamp) { - config := cfg.StaticFeeConfig config.CreateSubnetTxFee = cfg.CreateAssetTxFee config.CreateBlockchainTxFee = cfg.CreateAssetTxFee - return fee.NewStaticCalculator(config) } - return fee.NewStaticCalculator(cfg.StaticFeeConfig) + return fee.NewStaticCalculator(config) } From 38c52d66d3c22b164c2bacd0b9b40ed771b36db5 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 27 Jul 2024 20:35:27 -0400 Subject: [PATCH 095/100] merged --- vms/platformvm/txs/fee/calculator_test.go | 149 ++++++++++++++++++---- vms/platformvm/txs/fee/complexity.go | 11 +- vms/platformvm/txs/fee/complexity_test.go | 114 +---------------- 3 files changed, 134 insertions(+), 140 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 0684acd48737..300b328a2ba6 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -3,7 +3,10 @@ package fee -import "github.com/ava-labs/avalanchego/utils/units" +import ( + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/fee" +) var ( testStaticConfig = StaticConfig{ @@ -18,112 +21,208 @@ var ( } txTests = []struct { - name string - tx string - expectedStaticFee uint64 - expectedStaticFeeErr error + name string + tx string + expectedStaticFee uint64 + expectedStaticFeeErr error + expectedComplexity fee.Dimensions + expectedComplexityErr error }{ { - name: "AdvanceTimeTx", - tx: "0000000000130000000066a56fe700000000", - expectedStaticFee: 0, - expectedStaticFeeErr: ErrUnsupportedTx, + name: "AdvanceTimeTx", + tx: "0000000000130000000066a56fe700000000", + expectedStaticFee: 0, + expectedStaticFeeErr: ErrUnsupportedTx, + expectedComplexity: fee.Dimensions{}, + expectedComplexityErr: ErrUnsupportedTx, }, { - name: "RewardValidatorTx", - tx: "0000000000143d0ad12b8ee8928edf248ca91ca55600fb383f07c32bff1d6dec472b25cf59a700000000", - expectedStaticFee: 0, - expectedStaticFeeErr: ErrUnsupportedTx, + name: "RewardValidatorTx", + tx: "0000000000143d0ad12b8ee8928edf248ca91ca55600fb383f07c32bff1d6dec472b25cf59a700000000", + expectedStaticFee: 0, + expectedStaticFeeErr: ErrUnsupportedTx, + expectedComplexity: fee.Dimensions{}, + expectedComplexityErr: ErrUnsupportedTx, }, { - name: "AddValidatorTx", - tx: "00000000000c0000000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000f4b21e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000015000000006134088000000005000001d1a94a200000000001000000000000000400000000b3da694c70b8bee4478051313621c3f2282088b4000000005f6976d500000000614aaa19000001d1a94a20000000000121e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000016000000006134088000000007000001d1a94a20000000000000000000000000010000000120868ed5ac611711b33d2e4f97085347415db1c40000000b0000000000000000000000010000000120868ed5ac611711b33d2e4f97085347415db1c400009c40000000010000000900000001620513952dd17c8726d52e9e621618cb38f09fd194abb4cd7b4ee35ecd10880a562ad968dc81a89beab4e87d88d5d582aa73d0d265c87892d1ffff1f6e00f0ef00", - expectedStaticFee: testStaticConfig.AddPrimaryNetworkValidatorFee, - expectedStaticFeeErr: nil, + name: "AddValidatorTx", + tx: "00000000000c0000000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000f4b21e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000015000000006134088000000005000001d1a94a200000000001000000000000000400000000b3da694c70b8bee4478051313621c3f2282088b4000000005f6976d500000000614aaa19000001d1a94a20000000000121e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000016000000006134088000000007000001d1a94a20000000000000000000000000010000000120868ed5ac611711b33d2e4f97085347415db1c40000000b0000000000000000000000010000000120868ed5ac611711b33d2e4f97085347415db1c400009c40000000010000000900000001620513952dd17c8726d52e9e621618cb38f09fd194abb4cd7b4ee35ecd10880a562ad968dc81a89beab4e87d88d5d582aa73d0d265c87892d1ffff1f6e00f0ef00", + expectedStaticFee: testStaticConfig.AddPrimaryNetworkValidatorFee, + expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{}, + expectedComplexityErr: ErrUnsupportedTx, }, { - name: "AddDelegatorTx", - tx: "00000000000e000000050000000000000000000000000000000000000000000000000000000000000000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000000003b9aca0000000000000000000000000100000001f887b4c7030e95d2495603ae5d8b14cc0a66781a000000011767be999a49ca24fe705de032fa613b682493110fd6468ae7fb56bde1b9d729000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000000012a05f20000000001000000000000000400000000c51c552c49174e2e18b392049d3e4cd48b11490f000000005f692452000000005f73b05200000000ee6b2800000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000700000000ee6b280000000000000000000000000100000001e0cfe8cae22827d032805ded484e393ce51cbedb0000000b00000000000000000000000100000001e0cfe8cae22827d032805ded484e393ce51cbedb00000001000000090000000135cd78758035ed528d230317e5d880083a86a2b68c4a95655571828fe226548f235031c8dabd1fe06366a57613c4370ac26c4c59d1a1c46287a59906ec41b88f00", - expectedStaticFee: testStaticConfig.AddPrimaryNetworkDelegatorFee, - expectedStaticFeeErr: nil, + name: "AddDelegatorTx", + tx: "00000000000e000000050000000000000000000000000000000000000000000000000000000000000000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000000003b9aca0000000000000000000000000100000001f887b4c7030e95d2495603ae5d8b14cc0a66781a000000011767be999a49ca24fe705de032fa613b682493110fd6468ae7fb56bde1b9d729000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000000012a05f20000000001000000000000000400000000c51c552c49174e2e18b392049d3e4cd48b11490f000000005f692452000000005f73b05200000000ee6b2800000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000700000000ee6b280000000000000000000000000100000001e0cfe8cae22827d032805ded484e393ce51cbedb0000000b00000000000000000000000100000001e0cfe8cae22827d032805ded484e393ce51cbedb00000001000000090000000135cd78758035ed528d230317e5d880083a86a2b68c4a95655571828fe226548f235031c8dabd1fe06366a57613c4370ac26c4c59d1a1c46287a59906ec41b88f00", + expectedStaticFee: testStaticConfig.AddPrimaryNetworkDelegatorFee, + expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{}, + expectedComplexityErr: ErrUnsupportedTx, }, { name: "AddPermissionlessValidatorTx for primary network", tx: "00000000001900003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba8b1e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001043c91e9d508169329034e2a68110427a311f945efc53ed3f3493d335b393fd100000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f263d53e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae35f0000000066b692df000001d1a94a200000000000000000000000000000000000000000000000000000000000000000000000001ca3783a891cb41cadbfcf456da149f30e7af972677a162b984bef0779f254baac51ec042df1781d1295df80fb41c801269731fc6c25e1e5940dc3cb8509e30348fa712742cfdc83678acc9f95908eb98b89b28802fb559b4a2a6ff3216707c07f0ceb0b45a95f4f9a9540bbd3331d8ab4f233bffa4abb97fad9d59a1695f31b92a2b89e365facf7ab8c30de7c4a496d1e00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0007a12000000001000000090000000135f122f90bcece0d6c43e07fed1829578a23bc1734f8a4b46203f9f192ea1aec7526f3dca8fddec7418988615e6543012452bae1544275aae435313ec006ec9000", expectedStaticFee: testStaticConfig.AddPrimaryNetworkValidatorFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 691, + fee.DBRead: 2, + fee.DBWrite: 4, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, { name: "AddPermissionlessValidatorTx for subnet", tx: "000000000019000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000070000000000006091000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba6c9980000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000002038b42b73d3dc695c76ca12f966e97fe0681b1200f9a5e28d088720a18ea23c9000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000609b0000000100000000a378b74b3293a9d885bd9961f2cc2e1b3364d393c9be875964f2bd614214572c00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba7bdbc0000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa0000000066a57a160000000066b7ef16000000000000000a97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000001b000000012f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000000a000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000000000000000000000b00000000000000000000000000000000000f4240000000020000000900000001593fc20f88a8ce0b3470b0bb103e5f7e09f65023b6515d36660da53f9a15dedc1037ee27a8c4a27c24e20ad3b0ab4bd1ff3a02a6fcc2cbe04282bfe9902c9ae6000000000900000001593fc20f88a8ce0b3470b0bb103e5f7e09f65023b6515d36660da53f9a15dedc1037ee27a8c4a27c24e20ad3b0ab4bd1ff3a02a6fcc2cbe04282bfe9902c9ae600", expectedStaticFee: testStaticConfig.AddSubnetValidatorFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 748, + fee.DBRead: 3, // TODO: Re-evaluate this number + fee.DBWrite: 6, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, { name: "AddPermissionlessDelegatorTx for primary network", tx: "00000000001a00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1140fe00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000017d199179744b3b82d0071c83c2fb7dd6b95a2cdbe9dde295e0ae4f8c2287370300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba8b1e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae6080000000066ad5b08000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000100000009000000012261556f74a29f02ffc2725a567db2c81f75d0892525dbebaa1cf8650534cc70061123533a9553184cb02d899943ff0bf0b39c77b173c133854bc7c8bc7ab9a400", expectedStaticFee: testStaticConfig.AddPrimaryNetworkDelegatorFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 499, + fee.DBRead: 2, + fee.DBWrite: 4, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, { name: "AddPermissionlessDelegatorTx for subnet", tx: "00000000001a000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000070000000000006087000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700470c1336195b80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000029494c80361884942e4292c3531e8e790fcf7561e74404ded27eab8634e3fb30f000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000609100000001000000009494c80361884942e4292c3531e8e790fcf7561e74404ded27eab8634e3fb30f00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500470c1336289dc0000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa0000000066a57c1d0000000066b7f11d000000000000000a97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c124000000012f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000000a000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b00000000000000000000000000000000000000020000000900000001764190e2405fef72fce0d355e3dcc58a9f5621e583ae718cb2c23b55957995d1206d0b5efcc3cef99815e17a4b2cccd700147a759b7279a131745b237659666a000000000900000001764190e2405fef72fce0d355e3dcc58a9f5621e583ae718cb2c23b55957995d1206d0b5efcc3cef99815e17a4b2cccd700147a759b7279a131745b237659666a00", expectedStaticFee: testStaticConfig.AddSubnetDelegatorFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 720, + fee.DBRead: 3, // TODO: Re-evaluate this number + fee.DBWrite: 6, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, { name: "AddSubnetValidatorTx", tx: "00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1131bbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000138f94d1a0514eaabdaf4c52cad8d62b26cee61eaa951f5b75a5e57c2ee3793c800000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1140fe00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae7c90000000066ad5cc9000000000000c13797ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000200000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb60000000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb600", expectedStaticFee: testStaticConfig.AddSubnetValidatorFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 460, + fee.DBRead: 3, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, { name: "BaseTx", tx: "00000000002200003039000000000000000000000000000000000000000000000000000000000000000000000002dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fadbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834ed587af80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001fa4ff39749d44f29563ed9da03193d4a19ef419da4ce326594817ca266fda5ed00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1131bbc00000000100000000000000000000000100000009000000014a7b54c63dd25a532b5fe5045b6d0e1db876e067422f12c9c327333c2c792d9273405ac8bbbc2cce549bbd3d0f9274242085ee257adfdb859b0f8d55bdd16fb000", expectedStaticFee: testStaticConfig.TxFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 399, + fee.DBRead: 1, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, { name: "CreateChainTx", tx: "00000000000f00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263d53e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000197ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269cb1f0000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400096c65742074686572657873766d00000000000000000000000000000000000000000000000000000000000000000000002a000000000000669ae21e000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cffffffffffffffff0000000a0000000100000000000000020000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f8010000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f801", expectedStaticFee: testStaticConfig.CreateBlockchainTxFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 509, + fee.DBRead: 2, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, { name: "CreateSubnetTx", tx: "00000000001000003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f269cb1f00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc100000000000100000000000000000000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000010000000900000001b3c905e7227e619bd6b98c164a8b2b4a8ce89ac5142bbb1c42b139df2d17fd777c4c76eae66cef3de90800e567407945f58d918978f734f8ca4eda6923c78eb201", expectedStaticFee: testStaticConfig.CreateSubnetTxFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 339, + fee.DBRead: 1, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, { name: "ExportTx", tx: "00000000001200003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99dda340000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001f62c03574790b6a31a988f90c3e91c50fdd6f5d93baf200057463021ff23ec5c00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834ed587af800000000100000000000000009d0775f450604bd2fbc49ce0c5c1c6dfeb2dc2acb8c92c26eeae6e6df4502b1900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fa000000010000000900000001129a07c92045e0b9d0a203fcb5b53db7890fabce1397ff6a2ad16c98ef0151891ae72949d240122abf37b1206b95e05ff171df164a98e6bdf2384432eac2c30200", expectedStaticFee: testStaticConfig.TxFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 435, + fee.DBRead: 1, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, { name: "ImportTx", tx: "00000000001100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b8b87c0000000000000000100000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000000000000d891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf0000000163684415710a7d65f4ccb095edff59f897106b94d38937fc60e3ffc29892833b00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000003b9aca00000000010000000000000001000000090000000148ea12cb0950e47d852b99765208f5a811d3c8a47fa7b23fd524bd970019d157029f973abb91c31a146752ef8178434deb331db24c8dca5e61c961e6ac2f3b6700", expectedStaticFee: testStaticConfig.TxFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 335, + fee.DBRead: 1, + fee.DBWrite: 2, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, { name: "RemoveSubnetValidatorTx", tx: "00000000001700003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99ce6100000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001cd4569cfd044d50636fa597c700710403b3b52d3b75c30c542a111cc52c911ec00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99dda340000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a0000000100000000000000020000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d010000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d01", expectedStaticFee: testStaticConfig.TxFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 436, + fee.DBRead: 3, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, { - name: "TransformSubnetTx", - tx: "000000000018000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000609b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263c5fbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000294a113f31a30ee643288277574434f9066e0cdc1d53d6eb2610805c388814134000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000c137000000010000000094a113f31a30ee643288277574434f9066e0cdc1d53d6eb2610805c38881413400000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269bbdcc000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1242f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000000000609b000000000000c1370000000000000001000000000000000a0000000000000001000000000000006400127500001fa40000000001000000000000000a64000000010000000a00000001000000000000000300000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca820000000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca820000000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca8200", - expectedStaticFee: testStaticConfig.TransformSubnetTxFee, - expectedStaticFeeErr: nil, + name: "TransformSubnetTx", + tx: "000000000018000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000609b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263c5fbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000294a113f31a30ee643288277574434f9066e0cdc1d53d6eb2610805c388814134000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000c137000000010000000094a113f31a30ee643288277574434f9066e0cdc1d53d6eb2610805c38881413400000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269bbdcc000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1242f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000000000609b000000000000c1370000000000000001000000000000000a0000000000000001000000000000006400127500001fa40000000001000000000000000a64000000010000000a00000001000000000000000300000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca820000000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca820000000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca8200", + expectedStaticFee: testStaticConfig.TransformSubnetTxFee, + expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{}, + expectedComplexityErr: ErrUnsupportedTx, }, { name: "TransferSubnetOwnershipTx", tx: "00000000002100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99bf1ec0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000018f6e5f2840e34f9a375f35627a44bb0b9974285d280dc3220aa9489f97b17ebd00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99ce610000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000b00000000000000000000000000000000000000020000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f010000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f01", expectedStaticFee: testStaticConfig.TxFee, expectedStaticFeeErr: nil, + expectedComplexity: fee.Dimensions{ + fee.Bandwidth: 436, + fee.DBRead: 2, + fee.DBWrite: 3, + fee.Compute: 0, // TODO: implement + }, + expectedComplexityErr: nil, }, } ) diff --git a/vms/platformvm/txs/fee/complexity.go b/vms/platformvm/txs/fee/complexity.go index 805fa21abb1b..08a16461f03a 100644 --- a/vms/platformvm/txs/fee/complexity.go +++ b/vms/platformvm/txs/fee/complexity.go @@ -171,7 +171,6 @@ var ( fee.Compute: 0, } - errUnsupportedTx = errors.New("unsupported tx type") errUnsupportedOutput = errors.New("unsupported output type") errUnsupportedInput = errors.New("unsupported input type") errUnsupportedOwner = errors.New("unsupported owner type") @@ -356,23 +355,23 @@ type complexityVisitor struct { } func (*complexityVisitor) AddDelegatorTx(*txs.AddDelegatorTx) error { - return errUnsupportedTx + return ErrUnsupportedTx } func (*complexityVisitor) AddValidatorTx(*txs.AddValidatorTx) error { - return errUnsupportedTx + return ErrUnsupportedTx } func (*complexityVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - return errUnsupportedTx + return ErrUnsupportedTx } func (*complexityVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { - return errUnsupportedTx + return ErrUnsupportedTx } func (*complexityVisitor) TransformSubnetTx(*txs.TransformSubnetTx) error { - return errUnsupportedTx + return ErrUnsupportedTx } func (c *complexityVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { diff --git a/vms/platformvm/txs/fee/complexity_test.go b/vms/platformvm/txs/fee/complexity_test.go index 28b77461babd..d918962fa07b 100644 --- a/vms/platformvm/txs/fee/complexity_test.go +++ b/vms/platformvm/txs/fee/complexity_test.go @@ -23,113 +23,6 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) -var txTests = []struct { - name string - tx string - expected fee.Dimensions -}{ - { - name: "AddPermissionlessValidatorTx", - tx: "00000000001900003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba8b1e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001043c91e9d508169329034e2a68110427a311f945efc53ed3f3493d335b393fd100000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f263d53e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae35f0000000066b692df000001d1a94a200000000000000000000000000000000000000000000000000000000000000000000000001ca3783a891cb41cadbfcf456da149f30e7af972677a162b984bef0779f254baac51ec042df1781d1295df80fb41c801269731fc6c25e1e5940dc3cb8509e30348fa712742cfdc83678acc9f95908eb98b89b28802fb559b4a2a6ff3216707c07f0ceb0b45a95f4f9a9540bbd3331d8ab4f233bffa4abb97fad9d59a1695f31b92a2b89e365facf7ab8c30de7c4a496d1e00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0007a12000000001000000090000000135f122f90bcece0d6c43e07fed1829578a23bc1734f8a4b46203f9f192ea1aec7526f3dca8fddec7418988615e6543012452bae1544275aae435313ec006ec9000", - expected: fee.Dimensions{ - fee.Bandwidth: 691, - fee.DBRead: 2, - fee.DBWrite: 4, - fee.Compute: 0, // TODO: implement - }, - }, - { - name: "AddPermissionlessDelegatorTx", - tx: "00000000001a00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1140fe00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000017d199179744b3b82d0071c83c2fb7dd6b95a2cdbe9dde295e0ae4f8c2287370300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba8b1e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae6080000000066ad5b08000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000100000009000000012261556f74a29f02ffc2725a567db2c81f75d0892525dbebaa1cf8650534cc70061123533a9553184cb02d899943ff0bf0b39c77b173c133854bc7c8bc7ab9a400", - expected: fee.Dimensions{ - fee.Bandwidth: 499, - fee.DBRead: 2, - fee.DBWrite: 4, - fee.Compute: 0, // TODO: implement - }, - }, - { - name: "AddSubnetValidatorTx", - tx: "00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1131bbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000138f94d1a0514eaabdaf4c52cad8d62b26cee61eaa951f5b75a5e57c2ee3793c800000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1140fe00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae7c90000000066ad5cc9000000000000c13797ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000200000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb60000000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb600", - expected: fee.Dimensions{ - fee.Bandwidth: 460, - fee.DBRead: 3, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, - }, - { - name: "BaseTx", - tx: "00000000002200003039000000000000000000000000000000000000000000000000000000000000000000000002dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fadbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834ed587af80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001fa4ff39749d44f29563ed9da03193d4a19ef419da4ce326594817ca266fda5ed00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1131bbc00000000100000000000000000000000100000009000000014a7b54c63dd25a532b5fe5045b6d0e1db876e067422f12c9c327333c2c792d9273405ac8bbbc2cce549bbd3d0f9274242085ee257adfdb859b0f8d55bdd16fb000", - expected: fee.Dimensions{ - fee.Bandwidth: 399, - fee.DBRead: 1, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, - }, - { - name: "CreateChainTx", - tx: "00000000000f00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263d53e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000197ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269cb1f0000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400096c65742074686572657873766d00000000000000000000000000000000000000000000000000000000000000000000002a000000000000669ae21e000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cffffffffffffffff0000000a0000000100000000000000020000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f8010000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f801", - expected: fee.Dimensions{ - fee.Bandwidth: 509, - fee.DBRead: 2, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, - }, - { - name: "CreateSubnetTx", - tx: "00000000001000003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f269cb1f00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc100000000000100000000000000000000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000010000000900000001b3c905e7227e619bd6b98c164a8b2b4a8ce89ac5142bbb1c42b139df2d17fd777c4c76eae66cef3de90800e567407945f58d918978f734f8ca4eda6923c78eb201", - expected: fee.Dimensions{ - fee.Bandwidth: 339, - fee.DBRead: 1, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, - }, - { - name: "ExportTx", - tx: "00000000001200003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99dda340000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001f62c03574790b6a31a988f90c3e91c50fdd6f5d93baf200057463021ff23ec5c00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834ed587af800000000100000000000000009d0775f450604bd2fbc49ce0c5c1c6dfeb2dc2acb8c92c26eeae6e6df4502b1900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fa000000010000000900000001129a07c92045e0b9d0a203fcb5b53db7890fabce1397ff6a2ad16c98ef0151891ae72949d240122abf37b1206b95e05ff171df164a98e6bdf2384432eac2c30200", - expected: fee.Dimensions{ - fee.Bandwidth: 435, - fee.DBRead: 1, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, - }, - { - name: "ImportTx", - tx: "00000000001100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b8b87c0000000000000000100000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000000000000d891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf0000000163684415710a7d65f4ccb095edff59f897106b94d38937fc60e3ffc29892833b00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000003b9aca00000000010000000000000001000000090000000148ea12cb0950e47d852b99765208f5a811d3c8a47fa7b23fd524bd970019d157029f973abb91c31a146752ef8178434deb331db24c8dca5e61c961e6ac2f3b6700", - expected: fee.Dimensions{ - fee.Bandwidth: 335, - fee.DBRead: 1, - fee.DBWrite: 2, - fee.Compute: 0, // TODO: implement - }, - }, - { - name: "RemoveSubnetValidatorTx", - tx: "00000000001700003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99ce6100000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001cd4569cfd044d50636fa597c700710403b3b52d3b75c30c542a111cc52c911ec00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99dda340000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a0000000100000000000000020000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d010000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d01", - expected: fee.Dimensions{ - fee.Bandwidth: 436, - fee.DBRead: 3, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, - }, - { - name: "TransferSubnetOwnershipTx", - tx: "00000000002100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99bf1ec0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000018f6e5f2840e34f9a375f35627a44bb0b9974285d280dc3220aa9489f97b17ebd00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99ce610000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000b00000000000000000000000000000000000000020000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f010000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f01", - expected: fee.Dimensions{ - fee.Bandwidth: 436, - fee.DBRead: 2, - fee.DBWrite: 3, - fee.Compute: 0, // TODO: implement - }, - }, -} - func TestTxComplexity(t *testing.T) { for _, test := range txTests { t.Run(test.name, func(t *testing.T) { @@ -148,8 +41,11 @@ func TestTxComplexity(t *testing.T) { t.Log(string(txJSON)) actual, err := TxComplexity(tx.Unsigned) - require.NoError(err) - require.Equal(test.expected, actual) + require.Equal(test.expectedComplexity, actual) + require.ErrorIs(err, test.expectedComplexityErr) + if err != nil { + return + } require.Len(txBytes, int(actual[fee.Bandwidth])) }) From ba2c8e16866753c80dcffb7696e8270dc75eb3b3 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 29 Jul 2024 15:54:45 -0400 Subject: [PATCH 096/100] cleanup --- api/info/service.go | 16 ++++++++-------- config/config.go | 4 ++-- config/flags.go | 16 ++++++++-------- genesis/genesis_fuji.go | 4 ++-- genesis/genesis_local.go | 4 ++-- genesis/genesis_mainnet.go | 4 ++-- genesis/params.go | 4 ++-- node/node.go | 4 ++-- 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/api/info/service.go b/api/info/service.go index 072c5223cd52..40f5668dfb8f 100644 --- a/api/info/service.go +++ b/api/info/service.go @@ -397,15 +397,15 @@ func (i *Info) GetTxFee(_ *http.Request, _ *struct{}, reply *GetTxFeeResponse) e zap.String("method", "getTxFee"), ) - reply.TxFee = json.Uint64(i.TxFeeConfig.TxFee) + reply.TxFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.TxFee) reply.CreateAssetTxFee = json.Uint64(i.TxFeeConfig.CreateAssetTxFee) - reply.CreateSubnetTxFee = json.Uint64(i.TxFeeConfig.CreateSubnetTxFee) - reply.TransformSubnetTxFee = json.Uint64(i.TxFeeConfig.TransformSubnetTxFee) - reply.CreateBlockchainTxFee = json.Uint64(i.TxFeeConfig.CreateBlockchainTxFee) - reply.AddPrimaryNetworkValidatorFee = json.Uint64(i.TxFeeConfig.AddPrimaryNetworkValidatorFee) - reply.AddPrimaryNetworkDelegatorFee = json.Uint64(i.TxFeeConfig.AddPrimaryNetworkDelegatorFee) - reply.AddSubnetValidatorFee = json.Uint64(i.TxFeeConfig.AddSubnetValidatorFee) - reply.AddSubnetDelegatorFee = json.Uint64(i.TxFeeConfig.AddSubnetDelegatorFee) + reply.CreateSubnetTxFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.CreateSubnetTxFee) + reply.TransformSubnetTxFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.TransformSubnetTxFee) + reply.CreateBlockchainTxFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.CreateBlockchainTxFee) + reply.AddPrimaryNetworkValidatorFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.AddPrimaryNetworkValidatorFee) + reply.AddPrimaryNetworkDelegatorFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.AddPrimaryNetworkDelegatorFee) + reply.AddSubnetValidatorFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.AddSubnetValidatorFee) + reply.AddSubnetDelegatorFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.AddSubnetDelegatorFee) return nil } diff --git a/config/config.go b/config/config.go index 9c7427225060..45ec401517e5 100644 --- a/config/config.go +++ b/config/config.go @@ -765,7 +765,8 @@ func getStakingConfig(v *viper.Viper, networkID uint32) (node.StakingConfig, err func getTxFeeConfig(v *viper.Viper, networkID uint32) genesis.TxFeeConfig { if networkID != constants.MainnetID && networkID != constants.FujiID { return genesis.TxFeeConfig{ - StaticConfig: fee.StaticConfig{ + CreateAssetTxFee: v.GetUint64(CreateAssetTxFeeKey), + StaticTxConfig: fee.StaticConfig{ TxFee: v.GetUint64(TxFeeKey), CreateSubnetTxFee: v.GetUint64(CreateSubnetTxFeeKey), TransformSubnetTxFee: v.GetUint64(TransformSubnetTxFeeKey), @@ -775,7 +776,6 @@ func getTxFeeConfig(v *viper.Viper, networkID uint32) genesis.TxFeeConfig { AddSubnetValidatorFee: v.GetUint64(AddSubnetValidatorFeeKey), AddSubnetDelegatorFee: v.GetUint64(AddSubnetDelegatorFeeKey), }, - CreateAssetTxFee: v.GetUint64(CreateAssetTxFeeKey), } } return genesis.GetTxFeeConfig(networkID) diff --git a/config/flags.go b/config/flags.go index 3fb99e5f03e3..906166aa7742 100644 --- a/config/flags.go +++ b/config/flags.go @@ -99,15 +99,15 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.IntSlice(ACPObjectKey, nil, "ACPs to object adoption") // AVAX fees - fs.Uint64(TxFeeKey, genesis.LocalParams.TxFee, "Transaction fee, in nAVAX") + fs.Uint64(TxFeeKey, genesis.LocalParams.StaticTxConfig.TxFee, "Transaction fee, in nAVAX") fs.Uint64(CreateAssetTxFeeKey, genesis.LocalParams.CreateAssetTxFee, "Transaction fee, in nAVAX, for transactions that create new assets") - fs.Uint64(CreateSubnetTxFeeKey, genesis.LocalParams.CreateSubnetTxFee, "Transaction fee, in nAVAX, for transactions that create new subnets") - fs.Uint64(TransformSubnetTxFeeKey, genesis.LocalParams.TransformSubnetTxFee, "Transaction fee, in nAVAX, for transactions that transform subnets") - fs.Uint64(CreateBlockchainTxFeeKey, genesis.LocalParams.CreateBlockchainTxFee, "Transaction fee, in nAVAX, for transactions that create new blockchains") - fs.Uint64(AddPrimaryNetworkValidatorFeeKey, genesis.LocalParams.AddPrimaryNetworkValidatorFee, "Transaction fee, in nAVAX, for transactions that add new primary network validators") - fs.Uint64(AddPrimaryNetworkDelegatorFeeKey, genesis.LocalParams.AddPrimaryNetworkDelegatorFee, "Transaction fee, in nAVAX, for transactions that add new primary network delegators") - fs.Uint64(AddSubnetValidatorFeeKey, genesis.LocalParams.AddSubnetValidatorFee, "Transaction fee, in nAVAX, for transactions that add new subnet validators") - fs.Uint64(AddSubnetDelegatorFeeKey, genesis.LocalParams.AddSubnetDelegatorFee, "Transaction fee, in nAVAX, for transactions that add new subnet delegators") + fs.Uint64(CreateSubnetTxFeeKey, genesis.LocalParams.StaticTxConfig.CreateSubnetTxFee, "Transaction fee, in nAVAX, for transactions that create new subnets") + fs.Uint64(TransformSubnetTxFeeKey, genesis.LocalParams.StaticTxConfig.TransformSubnetTxFee, "Transaction fee, in nAVAX, for transactions that transform subnets") + fs.Uint64(CreateBlockchainTxFeeKey, genesis.LocalParams.StaticTxConfig.CreateBlockchainTxFee, "Transaction fee, in nAVAX, for transactions that create new blockchains") + fs.Uint64(AddPrimaryNetworkValidatorFeeKey, genesis.LocalParams.StaticTxConfig.AddPrimaryNetworkValidatorFee, "Transaction fee, in nAVAX, for transactions that add new primary network validators") + fs.Uint64(AddPrimaryNetworkDelegatorFeeKey, genesis.LocalParams.StaticTxConfig.AddPrimaryNetworkDelegatorFee, "Transaction fee, in nAVAX, for transactions that add new primary network delegators") + fs.Uint64(AddSubnetValidatorFeeKey, genesis.LocalParams.StaticTxConfig.AddSubnetValidatorFee, "Transaction fee, in nAVAX, for transactions that add new subnet validators") + fs.Uint64(AddSubnetDelegatorFeeKey, genesis.LocalParams.StaticTxConfig.AddSubnetDelegatorFee, "Transaction fee, in nAVAX, for transactions that add new subnet delegators") // Database fs.String(DBTypeKey, leveldb.Name, fmt.Sprintf("Database type to use. Must be one of {%s, %s, %s}", leveldb.Name, memdb.Name, pebbledb.Name)) diff --git a/genesis/genesis_fuji.go b/genesis/genesis_fuji.go index 359eb381c65e..e8bf3eb391c9 100644 --- a/genesis/genesis_fuji.go +++ b/genesis/genesis_fuji.go @@ -20,7 +20,8 @@ var ( // FujiParams are the params used for the fuji testnet FujiParams = Params{ TxFeeConfig: TxFeeConfig{ - StaticConfig: fee.StaticConfig{ + CreateAssetTxFee: 10 * units.MilliAvax, + StaticTxConfig: fee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 100 * units.MilliAvax, TransformSubnetTxFee: 1 * units.Avax, @@ -30,7 +31,6 @@ var ( AddSubnetValidatorFee: units.MilliAvax, AddSubnetDelegatorFee: units.MilliAvax, }, - CreateAssetTxFee: 10 * units.MilliAvax, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/genesis_local.go b/genesis/genesis_local.go index 6beeed99d8b9..0d37e860a95f 100644 --- a/genesis/genesis_local.go +++ b/genesis/genesis_local.go @@ -38,7 +38,8 @@ var ( // LocalParams are the params used for local networks LocalParams = Params{ TxFeeConfig: TxFeeConfig{ - StaticConfig: fee.StaticConfig{ + CreateAssetTxFee: units.MilliAvax, + StaticTxConfig: fee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 100 * units.MilliAvax, TransformSubnetTxFee: 100 * units.MilliAvax, @@ -48,7 +49,6 @@ var ( AddSubnetValidatorFee: units.MilliAvax, AddSubnetDelegatorFee: units.MilliAvax, }, - CreateAssetTxFee: units.MilliAvax, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/genesis_mainnet.go b/genesis/genesis_mainnet.go index 0d932729e595..0094fd2dda11 100644 --- a/genesis/genesis_mainnet.go +++ b/genesis/genesis_mainnet.go @@ -20,7 +20,8 @@ var ( // MainnetParams are the params used for mainnet MainnetParams = Params{ TxFeeConfig: TxFeeConfig{ - StaticConfig: fee.StaticConfig{ + CreateAssetTxFee: 10 * units.MilliAvax, + StaticTxConfig: fee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 1 * units.Avax, TransformSubnetTxFee: 10 * units.Avax, @@ -30,7 +31,6 @@ var ( AddSubnetValidatorFee: units.MilliAvax, AddSubnetDelegatorFee: units.MilliAvax, }, - CreateAssetTxFee: 10 * units.MilliAvax, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/params.go b/genesis/params.go index b875d8bde325..d6c27b16f8bf 100644 --- a/genesis/params.go +++ b/genesis/params.go @@ -35,8 +35,8 @@ type StakingConfig struct { } type TxFeeConfig struct { - fee.StaticConfig - CreateAssetTxFee uint64 `json:"createAssetTxFee"` + CreateAssetTxFee uint64 `json:"createAssetTxFee"` + StaticTxConfig fee.StaticConfig `json:"staticTxConfig"` } type Params struct { diff --git a/node/node.go b/node/node.go index 5898f5c60a4e..0e1b5e233d16 100644 --- a/node/node.go +++ b/node/node.go @@ -1228,7 +1228,7 @@ func (n *Node) initVMs() error { PartialSyncPrimaryNetwork: n.Config.PartialSyncPrimaryNetwork, TrackedSubnets: n.Config.TrackedSubnets, CreateAssetTxFee: n.Config.CreateAssetTxFee, - StaticFeeConfig: n.Config.StaticConfig, + StaticFeeConfig: n.Config.StaticTxConfig, UptimePercentage: n.Config.UptimeRequirement, MinValidatorStake: n.Config.MinValidatorStake, MaxValidatorStake: n.Config.MaxValidatorStake, @@ -1250,7 +1250,7 @@ func (n *Node) initVMs() error { }), n.VMManager.RegisterFactory(context.TODO(), constants.AVMID, &avm.Factory{ Config: avmconfig.Config{ - TxFee: n.Config.TxFee, + TxFee: n.Config.StaticTxConfig.TxFee, CreateAssetTxFee: n.Config.CreateAssetTxFee, EUpgradeTime: eUpgradeTime, }, From 0a826cd0090528fb210691cc6eca2e0fdd3a9b26 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 29 Jul 2024 18:38:11 -0400 Subject: [PATCH 097/100] nit --- api/info/service.go | 16 ++++++++-------- config/config.go | 2 +- config/flags.go | 16 ++++++++-------- genesis/genesis_fuji.go | 2 +- genesis/genesis_local.go | 2 +- genesis/genesis_mainnet.go | 2 +- genesis/params.go | 2 +- node/node.go | 4 ++-- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/api/info/service.go b/api/info/service.go index 40f5668dfb8f..0765c48c2a23 100644 --- a/api/info/service.go +++ b/api/info/service.go @@ -397,15 +397,15 @@ func (i *Info) GetTxFee(_ *http.Request, _ *struct{}, reply *GetTxFeeResponse) e zap.String("method", "getTxFee"), ) - reply.TxFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.TxFee) + reply.TxFee = json.Uint64(i.TxFeeConfig.StaticFeeConfig.TxFee) reply.CreateAssetTxFee = json.Uint64(i.TxFeeConfig.CreateAssetTxFee) - reply.CreateSubnetTxFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.CreateSubnetTxFee) - reply.TransformSubnetTxFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.TransformSubnetTxFee) - reply.CreateBlockchainTxFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.CreateBlockchainTxFee) - reply.AddPrimaryNetworkValidatorFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.AddPrimaryNetworkValidatorFee) - reply.AddPrimaryNetworkDelegatorFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.AddPrimaryNetworkDelegatorFee) - reply.AddSubnetValidatorFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.AddSubnetValidatorFee) - reply.AddSubnetDelegatorFee = json.Uint64(i.TxFeeConfig.StaticTxConfig.AddSubnetDelegatorFee) + reply.CreateSubnetTxFee = json.Uint64(i.TxFeeConfig.StaticFeeConfig.CreateSubnetTxFee) + reply.TransformSubnetTxFee = json.Uint64(i.TxFeeConfig.StaticFeeConfig.TransformSubnetTxFee) + reply.CreateBlockchainTxFee = json.Uint64(i.TxFeeConfig.StaticFeeConfig.CreateBlockchainTxFee) + reply.AddPrimaryNetworkValidatorFee = json.Uint64(i.TxFeeConfig.StaticFeeConfig.AddPrimaryNetworkValidatorFee) + reply.AddPrimaryNetworkDelegatorFee = json.Uint64(i.TxFeeConfig.StaticFeeConfig.AddPrimaryNetworkDelegatorFee) + reply.AddSubnetValidatorFee = json.Uint64(i.TxFeeConfig.StaticFeeConfig.AddSubnetValidatorFee) + reply.AddSubnetDelegatorFee = json.Uint64(i.TxFeeConfig.StaticFeeConfig.AddSubnetDelegatorFee) return nil } diff --git a/config/config.go b/config/config.go index 45ec401517e5..42b2a2be4b78 100644 --- a/config/config.go +++ b/config/config.go @@ -766,7 +766,7 @@ func getTxFeeConfig(v *viper.Viper, networkID uint32) genesis.TxFeeConfig { if networkID != constants.MainnetID && networkID != constants.FujiID { return genesis.TxFeeConfig{ CreateAssetTxFee: v.GetUint64(CreateAssetTxFeeKey), - StaticTxConfig: fee.StaticConfig{ + StaticFeeConfig: fee.StaticConfig{ TxFee: v.GetUint64(TxFeeKey), CreateSubnetTxFee: v.GetUint64(CreateSubnetTxFeeKey), TransformSubnetTxFee: v.GetUint64(TransformSubnetTxFeeKey), diff --git a/config/flags.go b/config/flags.go index 906166aa7742..d7cd925c2573 100644 --- a/config/flags.go +++ b/config/flags.go @@ -99,15 +99,15 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.IntSlice(ACPObjectKey, nil, "ACPs to object adoption") // AVAX fees - fs.Uint64(TxFeeKey, genesis.LocalParams.StaticTxConfig.TxFee, "Transaction fee, in nAVAX") + fs.Uint64(TxFeeKey, genesis.LocalParams.StaticFeeConfig.TxFee, "Transaction fee, in nAVAX") fs.Uint64(CreateAssetTxFeeKey, genesis.LocalParams.CreateAssetTxFee, "Transaction fee, in nAVAX, for transactions that create new assets") - fs.Uint64(CreateSubnetTxFeeKey, genesis.LocalParams.StaticTxConfig.CreateSubnetTxFee, "Transaction fee, in nAVAX, for transactions that create new subnets") - fs.Uint64(TransformSubnetTxFeeKey, genesis.LocalParams.StaticTxConfig.TransformSubnetTxFee, "Transaction fee, in nAVAX, for transactions that transform subnets") - fs.Uint64(CreateBlockchainTxFeeKey, genesis.LocalParams.StaticTxConfig.CreateBlockchainTxFee, "Transaction fee, in nAVAX, for transactions that create new blockchains") - fs.Uint64(AddPrimaryNetworkValidatorFeeKey, genesis.LocalParams.StaticTxConfig.AddPrimaryNetworkValidatorFee, "Transaction fee, in nAVAX, for transactions that add new primary network validators") - fs.Uint64(AddPrimaryNetworkDelegatorFeeKey, genesis.LocalParams.StaticTxConfig.AddPrimaryNetworkDelegatorFee, "Transaction fee, in nAVAX, for transactions that add new primary network delegators") - fs.Uint64(AddSubnetValidatorFeeKey, genesis.LocalParams.StaticTxConfig.AddSubnetValidatorFee, "Transaction fee, in nAVAX, for transactions that add new subnet validators") - fs.Uint64(AddSubnetDelegatorFeeKey, genesis.LocalParams.StaticTxConfig.AddSubnetDelegatorFee, "Transaction fee, in nAVAX, for transactions that add new subnet delegators") + fs.Uint64(CreateSubnetTxFeeKey, genesis.LocalParams.StaticFeeConfig.CreateSubnetTxFee, "Transaction fee, in nAVAX, for transactions that create new subnets") + fs.Uint64(TransformSubnetTxFeeKey, genesis.LocalParams.StaticFeeConfig.TransformSubnetTxFee, "Transaction fee, in nAVAX, for transactions that transform subnets") + fs.Uint64(CreateBlockchainTxFeeKey, genesis.LocalParams.StaticFeeConfig.CreateBlockchainTxFee, "Transaction fee, in nAVAX, for transactions that create new blockchains") + fs.Uint64(AddPrimaryNetworkValidatorFeeKey, genesis.LocalParams.StaticFeeConfig.AddPrimaryNetworkValidatorFee, "Transaction fee, in nAVAX, for transactions that add new primary network validators") + fs.Uint64(AddPrimaryNetworkDelegatorFeeKey, genesis.LocalParams.StaticFeeConfig.AddPrimaryNetworkDelegatorFee, "Transaction fee, in nAVAX, for transactions that add new primary network delegators") + fs.Uint64(AddSubnetValidatorFeeKey, genesis.LocalParams.StaticFeeConfig.AddSubnetValidatorFee, "Transaction fee, in nAVAX, for transactions that add new subnet validators") + fs.Uint64(AddSubnetDelegatorFeeKey, genesis.LocalParams.StaticFeeConfig.AddSubnetDelegatorFee, "Transaction fee, in nAVAX, for transactions that add new subnet delegators") // Database fs.String(DBTypeKey, leveldb.Name, fmt.Sprintf("Database type to use. Must be one of {%s, %s, %s}", leveldb.Name, memdb.Name, pebbledb.Name)) diff --git a/genesis/genesis_fuji.go b/genesis/genesis_fuji.go index e8bf3eb391c9..23af60cfc98c 100644 --- a/genesis/genesis_fuji.go +++ b/genesis/genesis_fuji.go @@ -21,7 +21,7 @@ var ( FujiParams = Params{ TxFeeConfig: TxFeeConfig{ CreateAssetTxFee: 10 * units.MilliAvax, - StaticTxConfig: fee.StaticConfig{ + StaticFeeConfig: fee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 100 * units.MilliAvax, TransformSubnetTxFee: 1 * units.Avax, diff --git a/genesis/genesis_local.go b/genesis/genesis_local.go index 0d37e860a95f..2039eaa99e28 100644 --- a/genesis/genesis_local.go +++ b/genesis/genesis_local.go @@ -39,7 +39,7 @@ var ( LocalParams = Params{ TxFeeConfig: TxFeeConfig{ CreateAssetTxFee: units.MilliAvax, - StaticTxConfig: fee.StaticConfig{ + StaticFeeConfig: fee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 100 * units.MilliAvax, TransformSubnetTxFee: 100 * units.MilliAvax, diff --git a/genesis/genesis_mainnet.go b/genesis/genesis_mainnet.go index 0094fd2dda11..66660c1f2651 100644 --- a/genesis/genesis_mainnet.go +++ b/genesis/genesis_mainnet.go @@ -21,7 +21,7 @@ var ( MainnetParams = Params{ TxFeeConfig: TxFeeConfig{ CreateAssetTxFee: 10 * units.MilliAvax, - StaticTxConfig: fee.StaticConfig{ + StaticFeeConfig: fee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 1 * units.Avax, TransformSubnetTxFee: 10 * units.Avax, diff --git a/genesis/params.go b/genesis/params.go index d6c27b16f8bf..9a3cc04a6eec 100644 --- a/genesis/params.go +++ b/genesis/params.go @@ -36,7 +36,7 @@ type StakingConfig struct { type TxFeeConfig struct { CreateAssetTxFee uint64 `json:"createAssetTxFee"` - StaticTxConfig fee.StaticConfig `json:"staticTxConfig"` + StaticFeeConfig fee.StaticConfig `json:"staticFeeConfig"` } type Params struct { diff --git a/node/node.go b/node/node.go index 0e1b5e233d16..e7d8f0921dba 100644 --- a/node/node.go +++ b/node/node.go @@ -1228,7 +1228,7 @@ func (n *Node) initVMs() error { PartialSyncPrimaryNetwork: n.Config.PartialSyncPrimaryNetwork, TrackedSubnets: n.Config.TrackedSubnets, CreateAssetTxFee: n.Config.CreateAssetTxFee, - StaticFeeConfig: n.Config.StaticTxConfig, + StaticFeeConfig: n.Config.StaticFeeConfig, UptimePercentage: n.Config.UptimeRequirement, MinValidatorStake: n.Config.MinValidatorStake, MaxValidatorStake: n.Config.MaxValidatorStake, @@ -1250,7 +1250,7 @@ func (n *Node) initVMs() error { }), n.VMManager.RegisterFactory(context.TODO(), constants.AVMID, &avm.Factory{ Config: avmconfig.Config{ - TxFee: n.Config.StaticTxConfig.TxFee, + TxFee: n.Config.StaticFeeConfig.TxFee, CreateAssetTxFee: n.Config.CreateAssetTxFee, EUpgradeTime: eUpgradeTime, }, From 62d8d61256df0624650543aaa92fc7831431ace4 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 5 Aug 2024 11:56:59 -0400 Subject: [PATCH 098/100] Address comments --- vms/platformvm/txs/fee/calculator_test.go | 154 +++++++++------------- vms/platformvm/txs/fee/complexity.go | 26 ++-- 2 files changed, 77 insertions(+), 103 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 7f0e23eae0a2..3c9e1ab0dcf2 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -33,198 +33,164 @@ var ( { name: "AdvanceTimeTx", tx: "0000000000130000000066a56fe700000000", - expectedStaticFee: 0, expectedStaticFeeErr: ErrUnsupportedTx, - expectedComplexity: fee.Dimensions{}, expectedComplexityErr: ErrUnsupportedTx, }, { name: "RewardValidatorTx", tx: "0000000000143d0ad12b8ee8928edf248ca91ca55600fb383f07c32bff1d6dec472b25cf59a700000000", - expectedStaticFee: 0, expectedStaticFeeErr: ErrUnsupportedTx, - expectedComplexity: fee.Dimensions{}, expectedComplexityErr: ErrUnsupportedTx, }, { name: "AddValidatorTx", tx: "00000000000c0000000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000f4b21e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000015000000006134088000000005000001d1a94a200000000001000000000000000400000000b3da694c70b8bee4478051313621c3f2282088b4000000005f6976d500000000614aaa19000001d1a94a20000000000121e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000016000000006134088000000007000001d1a94a20000000000000000000000000010000000120868ed5ac611711b33d2e4f97085347415db1c40000000b0000000000000000000000010000000120868ed5ac611711b33d2e4f97085347415db1c400009c40000000010000000900000001620513952dd17c8726d52e9e621618cb38f09fd194abb4cd7b4ee35ecd10880a562ad968dc81a89beab4e87d88d5d582aa73d0d265c87892d1ffff1f6e00f0ef00", expectedStaticFee: testStaticConfig.AddPrimaryNetworkValidatorFee, - expectedStaticFeeErr: nil, - expectedComplexity: fee.Dimensions{}, expectedComplexityErr: ErrUnsupportedTx, }, { name: "AddDelegatorTx", tx: "00000000000e000000050000000000000000000000000000000000000000000000000000000000000000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000000003b9aca0000000000000000000000000100000001f887b4c7030e95d2495603ae5d8b14cc0a66781a000000011767be999a49ca24fe705de032fa613b682493110fd6468ae7fb56bde1b9d729000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000000012a05f20000000001000000000000000400000000c51c552c49174e2e18b392049d3e4cd48b11490f000000005f692452000000005f73b05200000000ee6b2800000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000700000000ee6b280000000000000000000000000100000001e0cfe8cae22827d032805ded484e393ce51cbedb0000000b00000000000000000000000100000001e0cfe8cae22827d032805ded484e393ce51cbedb00000001000000090000000135cd78758035ed528d230317e5d880083a86a2b68c4a95655571828fe226548f235031c8dabd1fe06366a57613c4370ac26c4c59d1a1c46287a59906ec41b88f00", expectedStaticFee: testStaticConfig.AddPrimaryNetworkDelegatorFee, - expectedStaticFeeErr: nil, - expectedComplexity: fee.Dimensions{}, expectedComplexityErr: ErrUnsupportedTx, }, { - name: "AddPermissionlessValidatorTx for primary network", - tx: "00000000001900003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba8b1e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001043c91e9d508169329034e2a68110427a311f945efc53ed3f3493d335b393fd100000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f263d53e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae35f0000000066b692df000001d1a94a200000000000000000000000000000000000000000000000000000000000000000000000001ca3783a891cb41cadbfcf456da149f30e7af972677a162b984bef0779f254baac51ec042df1781d1295df80fb41c801269731fc6c25e1e5940dc3cb8509e30348fa712742cfdc83678acc9f95908eb98b89b28802fb559b4a2a6ff3216707c07f0ceb0b45a95f4f9a9540bbd3331d8ab4f233bffa4abb97fad9d59a1695f31b92a2b89e365facf7ab8c30de7c4a496d1e00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0007a12000000001000000090000000135f122f90bcece0d6c43e07fed1829578a23bc1734f8a4b46203f9f192ea1aec7526f3dca8fddec7418988615e6543012452bae1544275aae435313ec006ec9000", - expectedStaticFee: testStaticConfig.AddPrimaryNetworkValidatorFee, - expectedStaticFeeErr: nil, + name: "AddPermissionlessValidatorTx for primary network", + tx: "00000000001900003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba8b1e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001043c91e9d508169329034e2a68110427a311f945efc53ed3f3493d335b393fd100000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f263d53e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae35f0000000066b692df000001d1a94a200000000000000000000000000000000000000000000000000000000000000000000000001ca3783a891cb41cadbfcf456da149f30e7af972677a162b984bef0779f254baac51ec042df1781d1295df80fb41c801269731fc6c25e1e5940dc3cb8509e30348fa712742cfdc83678acc9f95908eb98b89b28802fb559b4a2a6ff3216707c07f0ceb0b45a95f4f9a9540bbd3331d8ab4f233bffa4abb97fad9d59a1695f31b92a2b89e365facf7ab8c30de7c4a496d1e00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0007a12000000001000000090000000135f122f90bcece0d6c43e07fed1829578a23bc1734f8a4b46203f9f192ea1aec7526f3dca8fddec7418988615e6543012452bae1544275aae435313ec006ec9000", + expectedStaticFee: testStaticConfig.AddPrimaryNetworkValidatorFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 691, - fee.DBRead: 2, - fee.DBWrite: 4, + fee.DBRead: IntrinsicAddPermissionlessValidatorTxComplexities[fee.DBRead] + intrinsicInputDBRead, + fee.DBWrite: IntrinsicAddPermissionlessValidatorTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + 2*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, { - name: "AddPermissionlessValidatorTx for subnet", - tx: "000000000019000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000070000000000006091000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba6c9980000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000002038b42b73d3dc695c76ca12f966e97fe0681b1200f9a5e28d088720a18ea23c9000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000609b0000000100000000a378b74b3293a9d885bd9961f2cc2e1b3364d393c9be875964f2bd614214572c00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba7bdbc0000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa0000000066a57a160000000066b7ef16000000000000000a97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000001b000000012f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000000a000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000000000000000000000b00000000000000000000000000000000000f4240000000020000000900000001593fc20f88a8ce0b3470b0bb103e5f7e09f65023b6515d36660da53f9a15dedc1037ee27a8c4a27c24e20ad3b0ab4bd1ff3a02a6fcc2cbe04282bfe9902c9ae6000000000900000001593fc20f88a8ce0b3470b0bb103e5f7e09f65023b6515d36660da53f9a15dedc1037ee27a8c4a27c24e20ad3b0ab4bd1ff3a02a6fcc2cbe04282bfe9902c9ae600", - expectedStaticFee: testStaticConfig.AddSubnetValidatorFee, - expectedStaticFeeErr: nil, + name: "AddPermissionlessValidatorTx for subnet", + tx: "000000000019000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000070000000000006091000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba6c9980000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000002038b42b73d3dc695c76ca12f966e97fe0681b1200f9a5e28d088720a18ea23c9000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000609b0000000100000000a378b74b3293a9d885bd9961f2cc2e1b3364d393c9be875964f2bd614214572c00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba7bdbc0000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa0000000066a57a160000000066b7ef16000000000000000a97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000001b000000012f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000000a000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000000000000000000000b00000000000000000000000000000000000f4240000000020000000900000001593fc20f88a8ce0b3470b0bb103e5f7e09f65023b6515d36660da53f9a15dedc1037ee27a8c4a27c24e20ad3b0ab4bd1ff3a02a6fcc2cbe04282bfe9902c9ae6000000000900000001593fc20f88a8ce0b3470b0bb103e5f7e09f65023b6515d36660da53f9a15dedc1037ee27a8c4a27c24e20ad3b0ab4bd1ff3a02a6fcc2cbe04282bfe9902c9ae600", + expectedStaticFee: testStaticConfig.AddSubnetValidatorFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 748, - fee.DBRead: 3, // TODO: Re-evaluate this number - fee.DBWrite: 6, + fee.DBRead: IntrinsicAddPermissionlessValidatorTxComplexities[fee.DBRead] + 2*intrinsicInputDBRead, + fee.DBWrite: IntrinsicAddPermissionlessValidatorTxComplexities[fee.DBWrite] + 2*intrinsicInputDBWrite + 3*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, { - name: "AddPermissionlessDelegatorTx for primary network", - tx: "00000000001a00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1140fe00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000017d199179744b3b82d0071c83c2fb7dd6b95a2cdbe9dde295e0ae4f8c2287370300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba8b1e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae6080000000066ad5b08000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000100000009000000012261556f74a29f02ffc2725a567db2c81f75d0892525dbebaa1cf8650534cc70061123533a9553184cb02d899943ff0bf0b39c77b173c133854bc7c8bc7ab9a400", - expectedStaticFee: testStaticConfig.AddPrimaryNetworkDelegatorFee, - expectedStaticFeeErr: nil, + name: "AddPermissionlessDelegatorTx for primary network", + tx: "00000000001a00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1140fe00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000017d199179744b3b82d0071c83c2fb7dd6b95a2cdbe9dde295e0ae4f8c2287370300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba8b1e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae6080000000066ad5b08000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000100000009000000012261556f74a29f02ffc2725a567db2c81f75d0892525dbebaa1cf8650534cc70061123533a9553184cb02d899943ff0bf0b39c77b173c133854bc7c8bc7ab9a400", + expectedStaticFee: testStaticConfig.AddPrimaryNetworkDelegatorFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 499, - fee.DBRead: 2, - fee.DBWrite: 4, + fee.DBRead: IntrinsicAddPermissionlessDelegatorTxComplexities[fee.DBRead] + 1*intrinsicInputDBRead, + fee.DBWrite: IntrinsicAddPermissionlessDelegatorTxComplexities[fee.DBWrite] + 1*intrinsicInputDBWrite + 2*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, { - name: "AddPermissionlessDelegatorTx for subnet", - tx: "00000000001a000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000070000000000006087000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700470c1336195b80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000029494c80361884942e4292c3531e8e790fcf7561e74404ded27eab8634e3fb30f000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000609100000001000000009494c80361884942e4292c3531e8e790fcf7561e74404ded27eab8634e3fb30f00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500470c1336289dc0000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa0000000066a57c1d0000000066b7f11d000000000000000a97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c124000000012f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000000a000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b00000000000000000000000000000000000000020000000900000001764190e2405fef72fce0d355e3dcc58a9f5621e583ae718cb2c23b55957995d1206d0b5efcc3cef99815e17a4b2cccd700147a759b7279a131745b237659666a000000000900000001764190e2405fef72fce0d355e3dcc58a9f5621e583ae718cb2c23b55957995d1206d0b5efcc3cef99815e17a4b2cccd700147a759b7279a131745b237659666a00", - expectedStaticFee: testStaticConfig.AddSubnetDelegatorFee, - expectedStaticFeeErr: nil, + name: "AddPermissionlessDelegatorTx for subnet", + tx: "00000000001a000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000070000000000006087000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700470c1336195b80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000029494c80361884942e4292c3531e8e790fcf7561e74404ded27eab8634e3fb30f000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000609100000001000000009494c80361884942e4292c3531e8e790fcf7561e74404ded27eab8634e3fb30f00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500470c1336289dc0000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa0000000066a57c1d0000000066b7f11d000000000000000a97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c124000000012f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000000a000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b00000000000000000000000000000000000000020000000900000001764190e2405fef72fce0d355e3dcc58a9f5621e583ae718cb2c23b55957995d1206d0b5efcc3cef99815e17a4b2cccd700147a759b7279a131745b237659666a000000000900000001764190e2405fef72fce0d355e3dcc58a9f5621e583ae718cb2c23b55957995d1206d0b5efcc3cef99815e17a4b2cccd700147a759b7279a131745b237659666a00", + expectedStaticFee: testStaticConfig.AddSubnetDelegatorFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 720, - fee.DBRead: 3, // TODO: Re-evaluate this number - fee.DBWrite: 6, + fee.DBRead: IntrinsicAddPermissionlessDelegatorTxComplexities[fee.DBRead] + 2*intrinsicInputDBRead, + fee.DBWrite: IntrinsicAddPermissionlessDelegatorTxComplexities[fee.DBWrite] + 2*intrinsicInputDBWrite + 3*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, { - name: "AddSubnetValidatorTx", - tx: "00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1131bbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000138f94d1a0514eaabdaf4c52cad8d62b26cee61eaa951f5b75a5e57c2ee3793c800000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1140fe00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae7c90000000066ad5cc9000000000000c13797ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000200000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb60000000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb600", - expectedStaticFee: testStaticConfig.AddSubnetValidatorFee, - expectedStaticFeeErr: nil, + name: "AddSubnetValidatorTx", + tx: "00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1131bbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000138f94d1a0514eaabdaf4c52cad8d62b26cee61eaa951f5b75a5e57c2ee3793c800000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1140fe00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae7c90000000066ad5cc9000000000000c13797ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000200000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb60000000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb600", + expectedStaticFee: testStaticConfig.AddSubnetValidatorFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 460, - fee.DBRead: 3, - fee.DBWrite: 3, + fee.DBRead: IntrinsicAddSubnetValidatorTxComplexities[fee.DBRead] + intrinsicInputDBRead, + fee.DBWrite: IntrinsicAddSubnetValidatorTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, { - name: "BaseTx", - tx: "00000000002200003039000000000000000000000000000000000000000000000000000000000000000000000002dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fadbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834ed587af80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001fa4ff39749d44f29563ed9da03193d4a19ef419da4ce326594817ca266fda5ed00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1131bbc00000000100000000000000000000000100000009000000014a7b54c63dd25a532b5fe5045b6d0e1db876e067422f12c9c327333c2c792d9273405ac8bbbc2cce549bbd3d0f9274242085ee257adfdb859b0f8d55bdd16fb000", - expectedStaticFee: testStaticConfig.TxFee, - expectedStaticFeeErr: nil, + name: "BaseTx", + tx: "00000000002200003039000000000000000000000000000000000000000000000000000000000000000000000002dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fadbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834ed587af80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001fa4ff39749d44f29563ed9da03193d4a19ef419da4ce326594817ca266fda5ed00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1131bbc00000000100000000000000000000000100000009000000014a7b54c63dd25a532b5fe5045b6d0e1db876e067422f12c9c327333c2c792d9273405ac8bbbc2cce549bbd3d0f9274242085ee257adfdb859b0f8d55bdd16fb000", + expectedStaticFee: testStaticConfig.TxFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 399, - fee.DBRead: 1, - fee.DBWrite: 3, + fee.DBRead: IntrinsicBaseTxComplexities[fee.DBRead] + intrinsicInputDBRead, + fee.DBWrite: IntrinsicBaseTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + 2*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, { - name: "CreateChainTx", - tx: "00000000000f00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263d53e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000197ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269cb1f0000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400096c65742074686572657873766d00000000000000000000000000000000000000000000000000000000000000000000002a000000000000669ae21e000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cffffffffffffffff0000000a0000000100000000000000020000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f8010000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f801", - expectedStaticFee: testStaticConfig.CreateBlockchainTxFee, - expectedStaticFeeErr: nil, + name: "CreateChainTx", + tx: "00000000000f00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263d53e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000197ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269cb1f0000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400096c65742074686572657873766d00000000000000000000000000000000000000000000000000000000000000000000002a000000000000669ae21e000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cffffffffffffffff0000000a0000000100000000000000020000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f8010000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f801", + expectedStaticFee: testStaticConfig.CreateBlockchainTxFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 509, - fee.DBRead: 2, - fee.DBWrite: 3, + fee.DBRead: IntrinsicCreateChainTxComplexities[fee.DBRead] + intrinsicInputDBRead, + fee.DBWrite: IntrinsicCreateChainTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, { - name: "CreateSubnetTx", - tx: "00000000001000003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f269cb1f00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc100000000000100000000000000000000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000010000000900000001b3c905e7227e619bd6b98c164a8b2b4a8ce89ac5142bbb1c42b139df2d17fd777c4c76eae66cef3de90800e567407945f58d918978f734f8ca4eda6923c78eb201", - expectedStaticFee: testStaticConfig.CreateSubnetTxFee, - expectedStaticFeeErr: nil, + name: "CreateSubnetTx", + tx: "00000000001000003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f269cb1f00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc100000000000100000000000000000000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000010000000900000001b3c905e7227e619bd6b98c164a8b2b4a8ce89ac5142bbb1c42b139df2d17fd777c4c76eae66cef3de90800e567407945f58d918978f734f8ca4eda6923c78eb201", + expectedStaticFee: testStaticConfig.CreateSubnetTxFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 339, - fee.DBRead: 1, - fee.DBWrite: 3, + fee.DBRead: IntrinsicCreateSubnetTxComplexities[fee.DBRead] + intrinsicInputDBRead, + fee.DBWrite: IntrinsicCreateSubnetTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, { - name: "ExportTx", - tx: "00000000001200003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99dda340000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001f62c03574790b6a31a988f90c3e91c50fdd6f5d93baf200057463021ff23ec5c00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834ed587af800000000100000000000000009d0775f450604bd2fbc49ce0c5c1c6dfeb2dc2acb8c92c26eeae6e6df4502b1900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fa000000010000000900000001129a07c92045e0b9d0a203fcb5b53db7890fabce1397ff6a2ad16c98ef0151891ae72949d240122abf37b1206b95e05ff171df164a98e6bdf2384432eac2c30200", - expectedStaticFee: testStaticConfig.TxFee, - expectedStaticFeeErr: nil, + name: "ExportTx", + tx: "00000000001200003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99dda340000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001f62c03574790b6a31a988f90c3e91c50fdd6f5d93baf200057463021ff23ec5c00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834ed587af800000000100000000000000009d0775f450604bd2fbc49ce0c5c1c6dfeb2dc2acb8c92c26eeae6e6df4502b1900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fa000000010000000900000001129a07c92045e0b9d0a203fcb5b53db7890fabce1397ff6a2ad16c98ef0151891ae72949d240122abf37b1206b95e05ff171df164a98e6bdf2384432eac2c30200", + expectedStaticFee: testStaticConfig.TxFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 435, - fee.DBRead: 1, - fee.DBWrite: 3, + fee.DBRead: IntrinsicExportTxComplexities[fee.DBRead] + intrinsicInputDBRead, + fee.DBWrite: IntrinsicExportTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + 2*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, { - name: "ImportTx", - tx: "00000000001100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b8b87c0000000000000000100000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000000000000d891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf0000000163684415710a7d65f4ccb095edff59f897106b94d38937fc60e3ffc29892833b00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000003b9aca00000000010000000000000001000000090000000148ea12cb0950e47d852b99765208f5a811d3c8a47fa7b23fd524bd970019d157029f973abb91c31a146752ef8178434deb331db24c8dca5e61c961e6ac2f3b6700", - expectedStaticFee: testStaticConfig.TxFee, - expectedStaticFeeErr: nil, + name: "ImportTx", + tx: "00000000001100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b8b87c0000000000000000100000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000000000000d891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf0000000163684415710a7d65f4ccb095edff59f897106b94d38937fc60e3ffc29892833b00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000003b9aca00000000010000000000000001000000090000000148ea12cb0950e47d852b99765208f5a811d3c8a47fa7b23fd524bd970019d157029f973abb91c31a146752ef8178434deb331db24c8dca5e61c961e6ac2f3b6700", + expectedStaticFee: testStaticConfig.TxFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 335, - fee.DBRead: 1, - fee.DBWrite: 2, + fee.DBRead: IntrinsicImportTxComplexities[fee.DBRead] + intrinsicInputDBRead, + fee.DBWrite: IntrinsicImportTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, { - name: "RemoveSubnetValidatorTx", - tx: "00000000001700003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99ce6100000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001cd4569cfd044d50636fa597c700710403b3b52d3b75c30c542a111cc52c911ec00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99dda340000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a0000000100000000000000020000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d010000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d01", - expectedStaticFee: testStaticConfig.TxFee, - expectedStaticFeeErr: nil, + name: "RemoveSubnetValidatorTx", + tx: "00000000001700003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99ce6100000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001cd4569cfd044d50636fa597c700710403b3b52d3b75c30c542a111cc52c911ec00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99dda340000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a0000000100000000000000020000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d010000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d01", + expectedStaticFee: testStaticConfig.TxFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 436, - fee.DBRead: 3, - fee.DBWrite: 3, + fee.DBRead: IntrinsicRemoveSubnetValidatorTxComplexities[fee.DBRead] + intrinsicInputDBRead, + fee.DBWrite: IntrinsicRemoveSubnetValidatorTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, { name: "TransformSubnetTx", tx: "000000000018000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000609b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263c5fbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000294a113f31a30ee643288277574434f9066e0cdc1d53d6eb2610805c388814134000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000c137000000010000000094a113f31a30ee643288277574434f9066e0cdc1d53d6eb2610805c38881413400000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269bbdcc000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1242f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000000000609b000000000000c1370000000000000001000000000000000a0000000000000001000000000000006400127500001fa40000000001000000000000000a64000000010000000a00000001000000000000000300000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca820000000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca820000000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca8200", expectedStaticFee: testStaticConfig.TransformSubnetTxFee, - expectedStaticFeeErr: nil, - expectedComplexity: fee.Dimensions{}, expectedComplexityErr: ErrUnsupportedTx, }, { - name: "TransferSubnetOwnershipTx", - tx: "00000000002100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99bf1ec0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000018f6e5f2840e34f9a375f35627a44bb0b9974285d280dc3220aa9489f97b17ebd00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99ce610000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000b00000000000000000000000000000000000000020000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f010000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f01", - expectedStaticFee: testStaticConfig.TxFee, - expectedStaticFeeErr: nil, + name: "TransferSubnetOwnershipTx", + tx: "00000000002100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99bf1ec0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000018f6e5f2840e34f9a375f35627a44bb0b9974285d280dc3220aa9489f97b17ebd00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99ce610000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000b00000000000000000000000000000000000000020000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f010000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f01", + expectedStaticFee: testStaticConfig.TxFee, expectedComplexity: fee.Dimensions{ fee.Bandwidth: 436, - fee.DBRead: 2, - fee.DBWrite: 3, + fee.DBRead: IntrinsicTransferSubnetOwnershipTxComplexities[fee.DBRead] + intrinsicInputDBRead, + fee.DBWrite: IntrinsicTransferSubnetOwnershipTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement }, - expectedComplexityErr: nil, }, } ) diff --git a/vms/platformvm/txs/fee/complexity.go b/vms/platformvm/txs/fee/complexity.go index 08a16461f03a..34b7fb9d3051 100644 --- a/vms/platformvm/txs/fee/complexity.go +++ b/vms/platformvm/txs/fee/complexity.go @@ -64,6 +64,11 @@ const ( intrinsicPoPBandwidth = bls.PublicKeyLen + // public key bls.SignatureLen // signature + + intrinsicInputDBRead = 1 + + intrinsicInputDBWrite = 1 + intrinsicOutputDBWrite = 1 ) var ( @@ -178,14 +183,13 @@ var ( errUnsupportedSigner = errors.New("unsupported signer type") ) -// TODO: Implement compute complexity func TxComplexity(tx txs.UnsignedTx) (fee.Dimensions, error) { c := complexityVisitor{} err := tx.Visit(&c) return c.output, err } -// OutputComplexity returns the complexity outputs adds to a transaction. +// OutputComplexity returns the complexity outputs add to a transaction. func OutputComplexity(outs ...*avax.TransferableOutput) (fee.Dimensions, error) { var complexity fee.Dimensions for _, out := range outs { @@ -206,7 +210,7 @@ func outputComplexity(out *avax.TransferableOutput) (fee.Dimensions, error) { complexity := fee.Dimensions{ fee.Bandwidth: intrinsicOutputBandwidth + intrinsicSECP256k1FxOutputBandwidth, fee.DBRead: 0, - fee.DBWrite: 1, + fee.DBWrite: intrinsicOutputDBWrite, fee.Compute: 0, } @@ -230,7 +234,7 @@ func outputComplexity(out *avax.TransferableOutput) (fee.Dimensions, error) { return complexity, err } -// InputComplexity returns the complexity inputs adds to a transaction. +// InputComplexity returns the complexity inputs add to a transaction. // It includes the complexity that the corresponding credentials will add. func InputComplexity(ins ...*avax.TransferableInput) (fee.Dimensions, error) { var complexity fee.Dimensions @@ -251,9 +255,9 @@ func InputComplexity(ins ...*avax.TransferableInput) (fee.Dimensions, error) { func inputComplexity(in *avax.TransferableInput) (fee.Dimensions, error) { complexity := fee.Dimensions{ fee.Bandwidth: intrinsicInputBandwidth + intrinsicSECP256k1FxTransferableInputBandwidth, - fee.DBRead: 1, - fee.DBWrite: 1, - fee.Compute: 0, + fee.DBRead: intrinsicInputDBRead, + fee.DBWrite: intrinsicInputDBWrite, + fee.Compute: 0, // TODO: Add compute complexity } inIntf := in.In @@ -328,7 +332,7 @@ func AuthComplexity(authIntf verify.Verifiable) (fee.Dimensions, error) { fee.Bandwidth: bandwidth, fee.DBRead: 0, fee.DBWrite: 0, - fee.Compute: 0, + fee.Compute: 0, // TODO: Add compute complexity }, nil } @@ -343,7 +347,7 @@ func SignerComplexity(s signer.Signer) (fee.Dimensions, error) { fee.Bandwidth: intrinsicPoPBandwidth, fee.DBRead: 0, fee.DBWrite: 0, - fee.Compute: 0, + fee.Compute: 0, // TODO: Add compute complexity }, nil default: return fee.Dimensions{}, errUnsupportedSigner @@ -375,6 +379,7 @@ func (*complexityVisitor) TransformSubnetTx(*txs.TransformSubnetTx) error { } func (c *complexityVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { + // TODO: Should we include additional complexity for subnets baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err @@ -406,6 +411,7 @@ func (c *complexityVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionle } func (c *complexityVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { + // TODO: Should we include additional complexity for subnets baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err @@ -508,6 +514,7 @@ func (c *complexityVisitor) ExportTx(tx *txs.ExportTx) error { if err != nil { return err } + // TODO: Should exported outputs be more complex? outputsComplexity, err := OutputComplexity(tx.ExportedOutputs...) if err != nil { return err @@ -524,6 +531,7 @@ func (c *complexityVisitor) ImportTx(tx *txs.ImportTx) error { if err != nil { return err } + // TODO: Should imported inputs be more complex? inputsComplexity, err := InputComplexity(tx.ImportedInputs...) if err != nil { return err From a47594a501cc370a3c849cd5bf77aa7a66d530b8 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 5 Aug 2024 11:58:28 -0400 Subject: [PATCH 099/100] nit --- vms/platformvm/txs/fee/complexity.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vms/platformvm/txs/fee/complexity.go b/vms/platformvm/txs/fee/complexity.go index 34b7fb9d3051..2334230078a8 100644 --- a/vms/platformvm/txs/fee/complexity.go +++ b/vms/platformvm/txs/fee/complexity.go @@ -379,7 +379,7 @@ func (*complexityVisitor) TransformSubnetTx(*txs.TransformSubnetTx) error { } func (c *complexityVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { - // TODO: Should we include additional complexity for subnets + // TODO: Should we include additional complexity for subnets? baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err @@ -411,7 +411,7 @@ func (c *complexityVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionle } func (c *complexityVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { - // TODO: Should we include additional complexity for subnets + // TODO: Should we include additional complexity for subnets? baseTxComplexity, err := baseTxComplexity(&tx.BaseTx) if err != nil { return err From 42aa113d285050996dc3288ddd111255e81f8ddd Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 5 Aug 2024 13:34:42 -0400 Subject: [PATCH 100/100] add comment --- vms/platformvm/txs/fee/calculator_test.go | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 3c9e1ab0dcf2..2e54fd638783 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -59,7 +59,7 @@ var ( tx: "00000000001900003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba8b1e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001043c91e9d508169329034e2a68110427a311f945efc53ed3f3493d335b393fd100000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f263d53e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae35f0000000066b692df000001d1a94a200000000000000000000000000000000000000000000000000000000000000000000000001ca3783a891cb41cadbfcf456da149f30e7af972677a162b984bef0779f254baac51ec042df1781d1295df80fb41c801269731fc6c25e1e5940dc3cb8509e30348fa712742cfdc83678acc9f95908eb98b89b28802fb559b4a2a6ff3216707c07f0ceb0b45a95f4f9a9540bbd3331d8ab4f233bffa4abb97fad9d59a1695f31b92a2b89e365facf7ab8c30de7c4a496d1e00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0007a12000000001000000090000000135f122f90bcece0d6c43e07fed1829578a23bc1734f8a4b46203f9f192ea1aec7526f3dca8fddec7418988615e6543012452bae1544275aae435313ec006ec9000", expectedStaticFee: testStaticConfig.AddPrimaryNetworkValidatorFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 691, + fee.Bandwidth: 691, // The length of the tx in bytes fee.DBRead: IntrinsicAddPermissionlessValidatorTxComplexities[fee.DBRead] + intrinsicInputDBRead, fee.DBWrite: IntrinsicAddPermissionlessValidatorTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + 2*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement @@ -70,7 +70,7 @@ var ( tx: "000000000019000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000070000000000006091000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700238520ba6c9980000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000002038b42b73d3dc695c76ca12f966e97fe0681b1200f9a5e28d088720a18ea23c9000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000609b0000000100000000a378b74b3293a9d885bd9961f2cc2e1b3364d393c9be875964f2bd614214572c00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba7bdbc0000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa0000000066a57a160000000066b7ef16000000000000000a97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000001b000000012f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000000a000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000000000000000000000b00000000000000000000000000000000000f4240000000020000000900000001593fc20f88a8ce0b3470b0bb103e5f7e09f65023b6515d36660da53f9a15dedc1037ee27a8c4a27c24e20ad3b0ab4bd1ff3a02a6fcc2cbe04282bfe9902c9ae6000000000900000001593fc20f88a8ce0b3470b0bb103e5f7e09f65023b6515d36660da53f9a15dedc1037ee27a8c4a27c24e20ad3b0ab4bd1ff3a02a6fcc2cbe04282bfe9902c9ae600", expectedStaticFee: testStaticConfig.AddSubnetValidatorFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 748, + fee.Bandwidth: 748, // The length of the tx in bytes fee.DBRead: IntrinsicAddPermissionlessValidatorTxComplexities[fee.DBRead] + 2*intrinsicInputDBRead, fee.DBWrite: IntrinsicAddPermissionlessValidatorTxComplexities[fee.DBWrite] + 2*intrinsicInputDBWrite + 3*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement @@ -81,7 +81,7 @@ var ( tx: "00000000001a00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1140fe00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000017d199179744b3b82d0071c83c2fb7dd6b95a2cdbe9dde295e0ae4f8c2287370300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500238520ba8b1e00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae6080000000066ad5b08000001d1a94a2000000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000100000009000000012261556f74a29f02ffc2725a567db2c81f75d0892525dbebaa1cf8650534cc70061123533a9553184cb02d899943ff0bf0b39c77b173c133854bc7c8bc7ab9a400", expectedStaticFee: testStaticConfig.AddPrimaryNetworkDelegatorFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 499, + fee.Bandwidth: 499, // The length of the tx in bytes fee.DBRead: IntrinsicAddPermissionlessDelegatorTxComplexities[fee.DBRead] + 1*intrinsicInputDBRead, fee.DBWrite: IntrinsicAddPermissionlessDelegatorTxComplexities[fee.DBWrite] + 1*intrinsicInputDBWrite + 2*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement @@ -92,7 +92,7 @@ var ( tx: "00000000001a000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000070000000000006087000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700470c1336195b80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000029494c80361884942e4292c3531e8e790fcf7561e74404ded27eab8634e3fb30f000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000609100000001000000009494c80361884942e4292c3531e8e790fcf7561e74404ded27eab8634e3fb30f00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500470c1336289dc0000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa0000000066a57c1d0000000066b7f11d000000000000000a97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c124000000012f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000000a000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b00000000000000000000000000000000000000020000000900000001764190e2405fef72fce0d355e3dcc58a9f5621e583ae718cb2c23b55957995d1206d0b5efcc3cef99815e17a4b2cccd700147a759b7279a131745b237659666a000000000900000001764190e2405fef72fce0d355e3dcc58a9f5621e583ae718cb2c23b55957995d1206d0b5efcc3cef99815e17a4b2cccd700147a759b7279a131745b237659666a00", expectedStaticFee: testStaticConfig.AddSubnetDelegatorFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 720, + fee.Bandwidth: 720, // The length of the tx in bytes fee.DBRead: IntrinsicAddPermissionlessDelegatorTxComplexities[fee.DBRead] + 2*intrinsicInputDBRead, fee.DBWrite: IntrinsicAddPermissionlessDelegatorTxComplexities[fee.DBWrite] + 2*intrinsicInputDBWrite + 3*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement @@ -103,7 +103,7 @@ var ( tx: "00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834f1131bbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000138f94d1a0514eaabdaf4c52cad8d62b26cee61eaa951f5b75a5e57c2ee3793c800000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1140fe00000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa00000000669ae7c90000000066ad5cc9000000000000c13797ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000200000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb60000000009000000012127130d37877fb1ec4b2374ef72571d49cd7b0319a3769e5da19041a138166c10b1a5c07cf5ccf0419066cbe3bab9827cf29f9fa6213ebdadf19d4849501eb600", expectedStaticFee: testStaticConfig.AddSubnetValidatorFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 460, + fee.Bandwidth: 460, // The length of the tx in bytes fee.DBRead: IntrinsicAddSubnetValidatorTxComplexities[fee.DBRead] + intrinsicInputDBRead, fee.DBWrite: IntrinsicAddSubnetValidatorTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement @@ -114,7 +114,7 @@ var ( tx: "00000000002200003039000000000000000000000000000000000000000000000000000000000000000000000002dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fadbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834ed587af80000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001fa4ff39749d44f29563ed9da03193d4a19ef419da4ce326594817ca266fda5ed00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834f1131bbc00000000100000000000000000000000100000009000000014a7b54c63dd25a532b5fe5045b6d0e1db876e067422f12c9c327333c2c792d9273405ac8bbbc2cce549bbd3d0f9274242085ee257adfdb859b0f8d55bdd16fb000", expectedStaticFee: testStaticConfig.TxFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 399, + fee.Bandwidth: 399, // The length of the tx in bytes fee.DBRead: IntrinsicBaseTxComplexities[fee.DBRead] + intrinsicInputDBRead, fee.DBWrite: IntrinsicBaseTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + 2*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement @@ -125,7 +125,7 @@ var ( tx: "00000000000f00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263d53e00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000197ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269cb1f0000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c12400096c65742074686572657873766d00000000000000000000000000000000000000000000000000000000000000000000002a000000000000669ae21e000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cffffffffffffffff0000000a0000000100000000000000020000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f8010000000900000001cf8104877b1a59b472f4f34d360c0e4f38e92c5fa334215430d0b99cf78eae8f621b6daf0b0f5c3a58a9497601f978698a1e5545d1873db8f2f38ecb7496c2f801", expectedStaticFee: testStaticConfig.CreateBlockchainTxFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 509, + fee.Bandwidth: 509, // The length of the tx in bytes fee.DBRead: IntrinsicCreateChainTxComplexities[fee.DBRead] + intrinsicInputDBRead, fee.DBWrite: IntrinsicCreateChainTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement @@ -136,7 +136,7 @@ var ( tx: "00000000001000003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f269cb1f00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc100000000000100000000000000000000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000010000000900000001b3c905e7227e619bd6b98c164a8b2b4a8ce89ac5142bbb1c42b139df2d17fd777c4c76eae66cef3de90800e567407945f58d918978f734f8ca4eda6923c78eb201", expectedStaticFee: testStaticConfig.CreateSubnetTxFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 339, + fee.Bandwidth: 339, // The length of the tx in bytes fee.DBRead: IntrinsicCreateSubnetTxComplexities[fee.DBRead] + intrinsicInputDBRead, fee.DBWrite: IntrinsicCreateSubnetTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement @@ -147,7 +147,7 @@ var ( tx: "00000000001200003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99dda340000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001f62c03574790b6a31a988f90c3e91c50fdd6f5d93baf200057463021ff23ec5c00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834ed587af800000000100000000000000009d0775f450604bd2fbc49ce0c5c1c6dfeb2dc2acb8c92c26eeae6e6df4502b1900000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b9aca00000000000000000100000002000000024a177205df5c29929d06db9d941f83d5ea985de3e902a9a86640bfdb1cd0e36c0cc982b83e5765fa000000010000000900000001129a07c92045e0b9d0a203fcb5b53db7890fabce1397ff6a2ad16c98ef0151891ae72949d240122abf37b1206b95e05ff171df164a98e6bdf2384432eac2c30200", expectedStaticFee: testStaticConfig.TxFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 435, + fee.Bandwidth: 435, // The length of the tx in bytes fee.DBRead: IntrinsicExportTxComplexities[fee.DBRead] + intrinsicInputDBRead, fee.DBWrite: IntrinsicExportTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + 2*intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement @@ -158,7 +158,7 @@ var ( tx: "00000000001100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000000003b8b87c0000000000000000100000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000000000000d891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf0000000163684415710a7d65f4ccb095edff59f897106b94d38937fc60e3ffc29892833b00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000000003b9aca00000000010000000000000001000000090000000148ea12cb0950e47d852b99765208f5a811d3c8a47fa7b23fd524bd970019d157029f973abb91c31a146752ef8178434deb331db24c8dca5e61c961e6ac2f3b6700", expectedStaticFee: testStaticConfig.TxFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 335, + fee.Bandwidth: 335, // The length of the tx in bytes fee.DBRead: IntrinsicImportTxComplexities[fee.DBRead] + intrinsicInputDBRead, fee.DBWrite: IntrinsicImportTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement @@ -169,7 +169,7 @@ var ( tx: "00000000001700003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99ce6100000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001cd4569cfd044d50636fa597c700710403b3b52d3b75c30c542a111cc52c911ec00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99dda340000000010000000000000000c582872c37c81efa2c94ea347af49cdc23a830aa97ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a0000000100000000000000020000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d010000000900000001673ee3e5a3a1221935274e8ff5c45b27ebe570e9731948e393a8ebef6a15391c189a54de7d2396095492ae171103cd4bfccfc2a4dafa001d48c130694c105c2d01", expectedStaticFee: testStaticConfig.TxFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 436, + fee.Bandwidth: 436, // The length of the tx in bytes fee.DBRead: IntrinsicRemoveSubnetValidatorTxComplexities[fee.DBRead] + intrinsicInputDBRead, fee.DBWrite: IntrinsicRemoveSubnetValidatorTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement @@ -186,7 +186,7 @@ var ( tx: "00000000002100003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000070023834e99bf1ec0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000018f6e5f2840e34f9a375f35627a44bb0b9974285d280dc3220aa9489f97b17ebd00000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000050023834e99ce610000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1240000000a00000001000000000000000b00000000000000000000000000000000000000020000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f010000000900000001e3479034ed8134dd23e154e1ec6e61b25073a20750ebf808e50ec1aae180ef430f8151347afdf6606bc7866f7f068b01719e4dad12e2976af1159fb048f73f7f01", expectedStaticFee: testStaticConfig.TxFee, expectedComplexity: fee.Dimensions{ - fee.Bandwidth: 436, + fee.Bandwidth: 436, // The length of the tx in bytes fee.DBRead: IntrinsicTransferSubnetOwnershipTxComplexities[fee.DBRead] + intrinsicInputDBRead, fee.DBWrite: IntrinsicTransferSubnetOwnershipTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite, fee.Compute: 0, // TODO: implement