From 95df851a503a9d93d0e0f870daf4ede1d91763f5 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 4 Feb 2024 21:35:55 +0100 Subject: [PATCH 001/120] wip: meter P-chain txs --- scripts/mocks.mockgen.txt | 2 + tests/e2e/p/staking_rewards.go | 23 +- tests/e2e/p/workflow.go | 38 +- vms/components/fees/dimensions.go | 38 + vms/components/fees/helpers.go | 71 + vms/components/fees/manager.go | 92 + vms/platformvm/block/builder/builder.go | 13 +- vms/platformvm/block/builder/helpers_test.go | 10 +- vms/platformvm/block/executor/helpers_test.go | 10 +- vms/platformvm/block/executor/manager.go | 11 +- .../block/executor/proposal_block_test.go | 1 + .../block/executor/standard_block_test.go | 2 + vms/platformvm/block/executor/verifier.go | 12 +- .../block/executor/verifier_test.go | 6 + vms/platformvm/config/config.go | 2 +- vms/platformvm/config/dynamic_fees_config.go | 45 + vms/platformvm/txs/builder/builder.go | 682 +++++-- .../txs/executor/atomic_tx_executor.go | 10 +- .../txs/executor/create_chain_test.go | 42 +- .../txs/executor/create_subnet_test.go | 10 +- vms/platformvm/txs/executor/helpers_test.go | 10 +- .../txs/executor/proposal_tx_executor.go | 11 +- .../txs/executor/staker_tx_verification.go | 92 +- .../executor/staker_tx_verification_test.go | 15 +- .../txs/executor/standard_tx_executor.go | 74 +- .../txs/executor/standard_tx_executor_test.go | 235 ++- vms/platformvm/txs/fees/calculator.go | 331 +++- vms/platformvm/txs/fees/calculator_test.go | 1685 +++++++++++++++++ vms/platformvm/txs/tx.go | 16 +- vms/platformvm/utxo/handler.go | 355 ++++ vms/platformvm/utxo/handler_test.go | 680 +++++++ vms/platformvm/validator_set_property_test.go | 1 + wallet/chain/p/builder_dynamic_fees.go | 1205 ++++++++++++ wallet/chain/p/builder_dynamic_fees_test.go | 1038 ++++++++++ wallet/chain/p/mocks/mock_builder_backend.go | 213 +++ wallet/chain/p/mocks/mock_signer_backend.go | 73 + wallet/chain/p/wallet.go | 303 ++- wallet/subnet/primary/wallet.go | 3 +- 38 files changed, 7052 insertions(+), 408 deletions(-) create mode 100644 vms/components/fees/dimensions.go create mode 100644 vms/components/fees/helpers.go create mode 100644 vms/components/fees/manager.go create mode 100644 vms/platformvm/config/dynamic_fees_config.go create mode 100644 vms/platformvm/txs/fees/calculator_test.go create mode 100644 wallet/chain/p/builder_dynamic_fees.go create mode 100644 wallet/chain/p/builder_dynamic_fees_test.go create mode 100644 wallet/chain/p/mocks/mock_builder_backend.go create mode 100644 wallet/chain/p/mocks/mock_signer_backend.go diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index ba2be886b0b6..701da0a02ac9 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -40,5 +40,7 @@ github.com/ava-labs/avalanchego/vms/proposervm=PostForkBlock=vms/proposervm/mock github.com/ava-labs/avalanchego/vms/registry=VMGetter=vms/registry/mock_vm_getter.go github.com/ava-labs/avalanchego/vms/registry=VMRegistry=vms/registry/mock_vm_registry.go github.com/ava-labs/avalanchego/vms=Factory,Manager=vms/mock_manager.go +github.com/ava-labs/avalanchego/wallet/chain/p=BuilderBackend=wallet/chain/p/mocks/mock_builder_backend.go +github.com/ava-labs/avalanchego/wallet/chain/p=SignerBackend=wallet/chain/p/mocks/mock_signer_backend.go github.com/ava-labs/avalanchego/x/sync=Client=x/sync/mock_client.go github.com/ava-labs/avalanchego/x/sync=NetworkClient=x/sync/mock_network_client.go diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index 43b64456de96..43e3e7161355 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -237,6 +237,17 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { delegatorData := data[0].Delegators[0] actualGammaDelegationPeriod := time.Duration(delegatorData.EndTime-delegatorData.StartTime) * time.Second + preRewardBalances := make(map[ids.ShortID]uint64, len(rewardKeys)) + for _, rewardKey := range rewardKeys { + keychain := secp256k1fx.NewKeychain(rewardKey) + baseWallet := e2e.NewWallet(keychain, nodeURI) + pWallet := baseWallet.P() + balances, err := pWallet.Builder().GetBalance() + require.NoError(err) + preRewardBalances[rewardKey.Address()] = balances[pWallet.AVAXAssetID()] + } + require.Len(preRewardBalances, len(rewardKeys)) + ginkgo.By("waiting until all validation periods are over") // The beta validator was the last added and so has the latest end time. The // delegation periods are shorter than the validation periods. @@ -290,12 +301,12 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { ginkgo.By("checking expected rewards against actual rewards") expectedRewardBalances := map[ids.ShortID]uint64{ - alphaValidationRewardKey.Address(): expectedValidationReward, - alphaDelegationRewardKey.Address(): expectedDelegationFee, - betaValidationRewardKey.Address(): 0, // Validator didn't meet uptime requirement - betaDelegationRewardKey.Address(): 0, // Validator didn't meet uptime requirement - gammaDelegationRewardKey.Address(): expectedDelegatorReward, - deltaDelegationRewardKey.Address(): 0, // Validator didn't meet uptime requirement + alphaValidationRewardKey.Address(): preRewardBalances[alphaValidationRewardKey.Address()] + expectedValidationReward, + alphaDelegationRewardKey.Address(): preRewardBalances[alphaDelegationRewardKey.Address()] + expectedDelegationFee, + betaValidationRewardKey.Address(): preRewardBalances[betaValidationRewardKey.Address()] + 0, // Validator didn't meet uptime requirement + betaDelegationRewardKey.Address(): preRewardBalances[betaDelegationRewardKey.Address()] + 0, // Validator didn't meet uptime requirement + gammaDelegationRewardKey.Address(): preRewardBalances[gammaDelegationRewardKey.Address()] + expectedDelegatorReward, + deltaDelegationRewardKey.Address(): preRewardBalances[deltaDelegationRewardKey.Address()] + 0, // Validator didn't meet uptime requirement } for address := range expectedRewardBalances { require.Equal(expectedRewardBalances[address], rewardBalances[address]) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 27301cd299ae..58617f63e5dd 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -20,9 +20,13 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) // PChainWorkflow is an integration test for normal P-Chain operations @@ -51,25 +55,18 @@ var _ = e2e.DescribePChain("[Workflow]", func() { tests.Outf("{{green}} minimal validator stake: %d {{/}}\n", minValStake) tests.Outf("{{green}} minimal delegator stake: %d {{/}}\n", minDelStake) - tests.Outf("{{blue}} fetching tx fee {{/}}\n") + tests.Outf("{{blue}} fetching X-chain tx fee {{/}}\n") infoClient := info.NewClient(nodeURI.URI) - fees, err := infoClient.GetTxFee(e2e.DefaultContext()) + xchainFees, err := infoClient.GetTxFee(e2e.DefaultContext()) require.NoError(err) - txFees := uint64(fees.TxFee) - tests.Outf("{{green}} txFee: %d {{/}}\n", txFees) + xChainTxFees := uint64(xchainFees.TxFee) + tests.Outf("{{green}} X-chain TxFee: %d {{/}}\n", xChainTxFees) // amount to transfer from P to X chain toTransfer := 1 * units.Avax pShortAddr := keychain.Keys[0].Address() xTargetAddr := keychain.Keys[1].Address() - ginkgo.By("check selected keys have sufficient funds", func() { - pBalances, err := pWallet.Builder().GetBalance() - pBalance := pBalances[avaxAssetID] - minBalance := minValStake + txFees + minDelStake + txFees + toTransfer + txFees - require.NoError(err) - require.GreaterOrEqual(pBalance, minBalance) - }) // Use a random node ID to ensure that repeated test runs // will succeed against a network that persists across runs. @@ -139,8 +136,9 @@ var _ = e2e.DescribePChain("[Workflow]", func() { OutputOwners: outputOwner, } + pChainExportFee := uint64(0) ginkgo.By("export avax from P to X chain", func() { - _, err := pWallet.IssueExportTx( + tx, err := pWallet.IssueExportTx( xWallet.BlockchainID(), []*avax.TransferableOutput{ { @@ -153,6 +151,18 @@ var _ = e2e.DescribePChain("[Workflow]", func() { e2e.WithDefaultContext(), ) require.NoError(err) + + // retrieve fees paid for the tx + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: tx.Creds, + } + + require.NoError(tx.Unsigned.Visit(&feeCalc)) + pChainExportFee = feeCalc.Fee }) // check balances post export @@ -167,7 +177,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { tests.Outf("{{blue}} X-chain balance after P->X export: %d {{/}}\n", xPreImportBalance) require.Equal(xPreImportBalance, xStartBalance) // import not performed yet - require.Equal(pPreImportBalance, pStartBalance-toTransfer-txFees) + require.Equal(pPreImportBalance, pStartBalance-toTransfer-pChainExportFee) ginkgo.By("import avax from P into X chain", func() { _, err := xWallet.IssueImportTx( @@ -189,7 +199,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { xFinalBalance := xBalances[avaxAssetID] tests.Outf("{{blue}} X-chain balance after P->X import: %d {{/}}\n", xFinalBalance) - require.Equal(xFinalBalance, xPreImportBalance+toTransfer-txFees) // import not performed yet + require.Equal(xFinalBalance, xPreImportBalance+toTransfer-xChainTxFees) // import not performed yet require.Equal(pFinalBalance, pPreImportBalance) }) }) diff --git a/vms/components/fees/dimensions.go b/vms/components/fees/dimensions.go new file mode 100644 index 000000000000..6f6b68128ef7 --- /dev/null +++ b/vms/components/fees/dimensions.go @@ -0,0 +1,38 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fees + +import ( + "github.com/ava-labs/avalanchego/utils/math" +) + +const ( + Bandwidth Dimension = 0 + UTXORead Dimension = 1 + UTXOWrite Dimension = 2 // includes delete + Compute Dimension = 3 // signatures checks, tx-specific + + FeeDimensions = 4 + + uint64Len = 8 +) + +var Empty = Dimensions{} // helps avoiding reading unit fees from db for some pre E fork processing + +type ( + Dimension int + Dimensions [FeeDimensions]uint64 +) + +func Add(lhs, rhs Dimensions) (Dimensions, error) { + var res Dimensions + for i := 0; i < FeeDimensions; i++ { + v, err := math.Add64(lhs[i], rhs[i]) + if err != nil { + return res, err + } + res[i] = v + } + return res, nil +} diff --git a/vms/components/fees/helpers.go b/vms/components/fees/helpers.go new file mode 100644 index 000000000000..dfdee15325eb --- /dev/null +++ b/vms/components/fees/helpers.go @@ -0,0 +1,71 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fees + +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 GetInputsDimensions(c codec.Manager, v uint16, ins []*avax.TransferableInput) (Dimensions, error) { + var consumedUnits Dimensions + for _, in := range ins { + cost, err := in.In.Cost() + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving cost of input %s: %w", in.ID, err) + } + + inSize, err := c.Size(v, in) + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving size of input %s: %w", in.ID, err) + } + uInSize := uint64(inSize) + + consumedUnits[Bandwidth] += uInSize - codec.CodecVersionSize + consumedUnits[UTXORead] += cost + uInSize // inputs are read + consumedUnits[UTXOWrite] += uInSize // inputs are deleted + } + return consumedUnits, nil +} + +func GetOutputsDimensions(c codec.Manager, v uint16, outs []*avax.TransferableOutput) (Dimensions, error) { + var consumedUnits Dimensions + for _, out := range outs { + outSize, err := c.Size(v, out) + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving size of output %s: %w", out.ID, err) + } + uOutSize := uint64(outSize) + + consumedUnits[Bandwidth] += uOutSize - codec.CodecVersionSize + consumedUnits[UTXOWrite] += uOutSize + } + return consumedUnits, nil +} + +func GetCredentialsDimensions(c codec.Manager, v uint16, inputSigIndices []uint32) (Dimensions, error) { + var consumedUnits Dimensions + + // Workaround to ensure that codec picks interface instead of the pointer to evaluate size. + // TODO ABENEGIA: fix this + creds := make([]verify.Verifiable, 0, 1) + creds = append(creds, &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, len(inputSigIndices)), + }) + + credSize, err := c.Size(v, creds) + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving size of credentials: %w", err) + } + credSize -= wrappers.IntLen // length of the slice, we want the single credential + + consumedUnits[Bandwidth] += uint64(credSize) - codec.CodecVersionSize + return consumedUnits, nil +} diff --git a/vms/components/fees/manager.go b/vms/components/fees/manager.go new file mode 100644 index 000000000000..644cf37fa9b1 --- /dev/null +++ b/vms/components/fees/manager.go @@ -0,0 +1,92 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fees + +import ( + "fmt" + + safemath "github.com/ava-labs/avalanchego/utils/math" +) + +type Manager struct { + // Avax denominated unit fees for all fee dimensions + unitFees Dimensions + + // cumulatedUnits helps aggregating the units consumed by a block + // so that we can verify it's not too big/build it properly. + cumulatedUnits Dimensions +} + +func NewManager(unitFees Dimensions) *Manager { + return &Manager{ + unitFees: unitFees, + } +} + +func (m *Manager) GetUnitFees() Dimensions { + return m.unitFees +} + +// CalculateFee must be a stateless method +func (m *Manager) CalculateFee(units Dimensions) (uint64, error) { + fee := uint64(0) + + for i := Dimension(0); i < FeeDimensions; i++ { + contribution, err := safemath.Mul64(m.unitFees[i], units[i]) + if err != nil { + return 0, err + } + fee, err = safemath.Add64(contribution, fee) + if err != nil { + return 0, err + } + } + return fee, nil +} + +// CumulateUnits tries to cumulate the consumed units [units]. Before +// actually cumulating them, it checks whether the result would breach [bounds]. +// If so, it returns the first dimension to breach bounds. +func (m *Manager) CumulateUnits(units, bounds Dimensions) (bool, Dimension) { + // Ensure we can consume (don't want partial update of values) + for i := Dimension(0); i < FeeDimensions; i++ { + consumed, err := safemath.Add64(m.cumulatedUnits[i], units[i]) + if err != nil { + return true, i + } + if consumed > bounds[i] { + return true, i + } + } + + // Commit to consumption + for i := Dimension(0); i < FeeDimensions; i++ { + consumed, err := safemath.Add64(m.cumulatedUnits[i], units[i]) + if err != nil { + return true, i + } + m.cumulatedUnits[i] = consumed + } + return false, 0 +} + +// Sometimes, e.g. while building a tx, we'd like freedom to speculatively add units +// and to remove them later on. [RemoveUnits] grants this freedom +func (m *Manager) RemoveUnits(unitsToRm Dimensions) error { + var revertedUnits Dimensions + for i := Dimension(0); i < FeeDimensions; i++ { + prev, err := safemath.Sub(m.cumulatedUnits[i], unitsToRm[i]) + if err != nil { + return fmt.Errorf("%w: dimension %d", err, i) + } + revertedUnits[i] = prev + } + + m.cumulatedUnits = revertedUnits + return nil +} + +func (m *Manager) GetCumulatedUnits() Dimensions { + return m.cumulatedUnits +} diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 77f39fbd0296..85122ec7d77a 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -18,7 +18,9 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -349,6 +351,9 @@ func packBlockTxs( } var ( + feeCfg = config.EUpgradeDynamicFeesConfig + feeMan = fees.NewManager(feeCfg.UnitFees) + blockTxs []*txs.Tx inputs set.Set[ids.ID] ) @@ -372,9 +377,11 @@ func packBlockTxs( } executor := &txexecutor.StandardTxExecutor{ - Backend: backend, - State: txDiff, - Tx: tx, + Backend: backend, + BlkFeeManager: feeMan, + UnitCaps: feeCfg.BlockUnitsCap, + State: txDiff, + 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 92892df75ae2..c46fb1163a23 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -36,6 +36,7 @@ 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/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" @@ -253,10 +254,13 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(genesisID, env.blkManager) require.NoError(err) + feeCfg := config.EUpgradeDynamicFeesConfig executor := txexecutor.StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: testSubnet1, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, + State: stateDiff, + 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 9b98681c44cd..a49dfe9af778 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -38,6 +38,7 @@ 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/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" @@ -274,10 +275,13 @@ func addSubnet(env *environment) { panic(err) } + feeCfg := config.EUpgradeDynamicFeesConfig executor := executor.StandardTxExecutor{ - Backend: env.backend, - State: stateDiff, - Tx: testSubnet1, + Backend: env.backend, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, + State: stateDiff, + 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 27d35a7641ad..cc6b72a2813e 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -9,7 +9,9 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -142,10 +144,13 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } + feesCfg := config.EUpgradeDynamicFeesConfig err = tx.Unsigned.Visit(&executor.StandardTxExecutor{ - Backend: m.txExecutorBackend, - State: stateDiff, - Tx: tx, + Backend: m.txExecutorBackend, + BlkFeeManager: fees.NewManager(feesCfg.UnitFees), + UnitCaps: feesCfg.BlockUnitsCap, + State: stateDiff, + Tx: tx, }) // We ignore [errFutureStakeTime] here because the time will be advanced // when this transaction is issued. diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 33a3877fc24b..118cece1937f 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -143,6 +143,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { env.clk.Set(defaultGenesisTime) env.config.BanffTime = time.Time{} // activate Banff env.config.DurangoTime = mockable.MaxTime // deactivate Durango + env.config.EUpgradeTime = mockable.MaxTime // create parentBlock. It's a standard one for simplicity parentTime := defaultGenesisTime diff --git a/vms/platformvm/block/executor/standard_block_test.go b/vms/platformvm/block/executor/standard_block_test.go index 3e0122c9123d..63dc7b2646c7 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -87,6 +87,8 @@ func TestBanffStandardBlockTimeVerification(t *testing.T) { now := env.clk.Time() env.clk.Set(now) env.config.BanffTime = time.Time{} // activate Banff + env.config.DurangoTime = time.Time{} + env.config.EUpgradeTime = time.Time{} // setup and store parent block // it's a standard block for simplicity diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index b35d2ecdd55c..e4f325912cc6 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -10,7 +10,9 @@ import ( "github.com/ava-labs/avalanchego/chains/atomic" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -438,6 +440,8 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID error, ) { var ( + feesCfg = config.EUpgradeDynamicFeesConfig + onAcceptFunc func() inputs set.Set[ids.ID] funcs = make([]func(), 0, len(txs)) @@ -445,9 +449,11 @@ 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, + BlkFeeManager: fees.NewManager(feesCfg.UnitFees), + UnitCaps: feesCfg.BlockUnitsCap, + State: state, + Tx: tx, } if err := tx.Unsigned.Visit(&txExecutor); err != nil { txID := tx.ID() diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index ccac3da3b7e3..732c2a034f29 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -232,6 +232,9 @@ func TestVerifierVisitStandardBlock(t *testing.T) { Config: &config.Config{ ApricotPhase5Time: time.Now().Add(time.Hour), BanffTime: mockable.MaxTime, // banff is not activated + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }, Clk: &mockable.Clock{}, }, @@ -714,6 +717,9 @@ func TestVerifierVisitStandardBlockWithDuplicateInputs(t *testing.T) { Config: &config.Config{ ApricotPhase5Time: time.Now().Add(time.Hour), BanffTime: mockable.MaxTime, // banff is not activated + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, }, Clk: &mockable.Clock{}, }, diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 0ac37f81f08e..91927e0b44f4 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) IsEUpgradeActivated(timestamp time.Time) bool { return !timestamp.Before(c.EUpgradeTime) } diff --git a/vms/platformvm/config/dynamic_fees_config.go b/vms/platformvm/config/dynamic_fees_config.go new file mode 100644 index 000000000000..d7994896c7da --- /dev/null +++ b/vms/platformvm/config/dynamic_fees_config.go @@ -0,0 +1,45 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package config + +import ( + "math" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" +) + +// Dynamic fees configs become relevant with dynamic fees introduction in E-fork +// We cannot easily include then in Config since they do not come from genesis +// They don't feel like an execution config either, since we need a fork upgrade +// to update them (testing is a different story). +// I am setting them in a separate config object, but will access it via Config +// so to have fork control over which dynamic fees is picked + +// EUpgradeDynamicFeesConfig to be tuned TODO ABENEGIA +var EUpgradeDynamicFeesConfig = DynamicFeesConfig{ + UnitFees: commonfees.Dimensions{ + 1, + 2, + 3, + 4, + }, + + BlockUnitsCap: commonfees.Dimensions{ + math.MaxUint64, + math.MaxUint64, + math.MaxUint64, + math.MaxUint64, + }, +} + +type DynamicFeesConfig struct { + // UnitFees contains, per each fee dimension, the + // unit fees valid as soon as fork introducing dynamic fees + // activates. Unit fees will be then updated by the dynamic fees algo. + UnitFees commonfees.Dimensions + + // BlockUnitsCap contains, per each fee dimension, the + // maximal complexity a valid P-chain block can host + BlockUnitsCap commonfees.Dimensions +} diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 37422ff301f1..1d7770764bef 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -20,8 +20,11 @@ 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/fees" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) // Max number of items allowed in a page @@ -260,6 +263,16 @@ func (b *builder) NewImportTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { + // 1. Build core transaction without utxos + utx := &txs.ImportTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.ctx.NetworkID, + BlockchainID: b.ctx.ChainID, + }}, + SourceChain: from, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) kc := secp256k1fx.NewKeychain(keys...) atomicUTXOs, _, _, err := b.GetAtomicUTXOs(from, kc.Addresses(), ids.ShortEmpty, ids.Empty, MaxPageSize) @@ -267,11 +280,14 @@ func (b *builder) NewImportTx( return nil, fmt.Errorf("problem retrieving atomic UTXOs: %w", err) } - importedInputs := []*avax.TransferableInput{} - signers := [][]*secp256k1.PrivateKey{} + var ( + importedInputs = []*avax.TransferableInput{} + signers = [][]*secp256k1.PrivateKey{} + outs = []*avax.TransferableOutput{} - importedAmounts := make(map[ids.ID]uint64) - now := b.clk.Unix() + importedAmounts = make(map[ids.ID]uint64) + now = b.clk.Unix() + ) for _, utxo := range atomicUTXOs { inputIntf, utxoSigners, err := kc.Spend(utxo.Out, now) if err != nil { @@ -293,32 +309,21 @@ func (b *builder) NewImportTx( }) signers = append(signers, utxoSigners) } - avax.SortTransferableInputsWithSigners(importedInputs, signers) - if len(importedAmounts) == 0 { return nil, ErrNoFunds // No imported UTXOs were spendable } - importedAVAX := importedAmounts[b.ctx.AVAXAssetID] - - ins := []*avax.TransferableInput{} - outs := []*avax.TransferableOutput{} - switch { - case importedAVAX < b.cfg.TxFee: // imported amount goes toward paying tx fee - var baseSigners [][]*secp256k1.PrivateKey - ins, outs, _, baseSigners, err = b.Spend(b.state, keys, 0, b.cfg.TxFee-importedAVAX, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - signers = append(baseSigners, signers...) - delete(importedAmounts, b.ctx.AVAXAssetID) - case importedAVAX == b.cfg.TxFee: - delete(importedAmounts, b.ctx.AVAXAssetID) - default: - importedAmounts[b.ctx.AVAXAssetID] -= b.cfg.TxFee - } + // Sort and add imported txs to utx. Imported txs must not be + // changed here in after + avax.SortTransferableInputsWithSigners(importedInputs, signers) + utx.ImportedInputs = importedInputs + // add non avax-denominated outputs. Avax-denominated utxos + // are used to pay fees whose amount is calculated later on for assetID, amount := range importedAmounts { + if assetID == b.ctx.AVAXAssetID { + continue + } outs = append(outs, &avax.TransferableOutput{ Asset: avax.Asset{ID: assetID}, Out: &secp256k1fx.TransferOutput{ @@ -330,21 +335,127 @@ func (b *builder) NewImportTx( }, }, }) + delete(importedAmounts, assetID) } - avax.SortTransferableOutputs(outs, txs.Codec) // sort imported outputs + var ( + ins []*avax.TransferableInput - // Create the transaction - utx := &txs.ImportTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Outs: outs, - Ins: ins, - }}, - SourceChain: from, - ImportedInputs: importedInputs, + importedAVAX = importedAmounts[b.ctx.AVAXAssetID] // the only entry left in importedAmounts + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ) + if isEForkActive { + // while outs are not ordered we add them to get current fees. We'll fix ordering later on + utx.BaseTx.Outs = outs + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.ImportTx(utx); err != nil { + return nil, err + } + + if feeCalc.Fee >= importedAVAX { + // all imported avax will be burned to pay taxes. + // Fees are scaled back accordingly. + feeCalc.Fee -= importedAVAX + } else { + // imported inputs may be enough to pay taxes by themselves + changeOut := &avax.TransferableOutput{ + Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + // Amt: importedAVAX, // SET IT AFTER CONSIDERING ITS OWN FEES + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{to}, + }, + }, + } + + // update fees to target given the extra input added + outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) + if err != nil { + return nil, fmt.Errorf("failed calculating output size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(outDimensions) + if err != nil { + return nil, fmt.Errorf("account for output fees: %w", err) + } + + if addedFees >= importedAVAX { + // imported avax are not enough to pay fees + // Drop the changeOut and finance the tx + if _, err := feeCalc.RemoveFeesFor(outDimensions); err != nil { + return nil, fmt.Errorf("failed reverting change output: %w", err) + } + feeCalc.Fee -= importedAVAX + + var ( + financeOut []*avax.TransferableOutput + financeSigner [][]*secp256k1.PrivateKey + ) + ins, financeOut, _, financeSigner, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + outs = append(financeOut, outs...) + signers = append(financeSigner, signers...) + } else { + changeOut.Out.(*secp256k1fx.TransferOutput).Amt = importedAVAX - feeCalc.Fee + outs = append(outs, changeOut) + } + } + } else { + switch { + case importedAVAX < b.cfg.TxFee: // imported amount goes toward paying tx fee + var ( + baseOuts []*avax.TransferableOutput + baseSigners [][]*secp256k1.PrivateKey + ) + ins, baseOuts, _, baseSigners, err = b.Spend(b.state, keys, 0, b.cfg.TxFee-importedAVAX, changeAddr) + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + outs = append(baseOuts, outs...) + signers = append(baseSigners, signers...) + delete(importedAmounts, b.ctx.AVAXAssetID) + case importedAVAX == b.cfg.TxFee: + delete(importedAmounts, b.ctx.AVAXAssetID) + default: + importedAVAX -= b.cfg.TxFee + outs = append(outs, &avax.TransferableOutput{ + Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: importedAVAX, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{to}, + }, + }, + }) + } } + + avax.SortTransferableOutputs(outs, txs.Codec) // sort imported outputs + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + + // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -360,22 +471,11 @@ func (b *builder) NewExportTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - toBurn, err := math.Add64(amount, b.cfg.TxFee) - if err != nil { - return nil, fmt.Errorf("amount (%d) + tx fee(%d) overflows", amount, b.cfg.TxFee) - } - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, toBurn, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - - // Create the transaction + // 1. Build core transaction without utxos utx := &txs.ExportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, // Non-exported outputs }}, DestinationChain: chainID, ExportedOutputs: []*avax.TransferableOutput{{ // Exported to X-Chain @@ -390,6 +490,53 @@ func (b *builder) NewExportTx( }, }}, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput + outs []*avax.TransferableOutput + signers [][]*secp256k1.PrivateKey + err error + ) + if isEForkActive { + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.ExportTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + } else { + var toBurn uint64 + toBurn, err = math.Add64(amount, b.cfg.TxFee) + if err != nil { + return nil, fmt.Errorf("amount (%d) + tx fee(%d) overflows", amount, b.cfg.TxFee) + } + ins, outs, _, signers, err = b.Spend(b.state, keys, 0, toBurn, changeAddr) + } + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + + // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -406,29 +553,18 @@ func (b *builder) NewCreateChainTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - timestamp := b.state.GetTimestamp() - createBlockchainTxFee := b.cfg.GetCreateBlockchainTxFee(timestamp) - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, createBlockchainTxFee, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - + // 1. Build core transaction without utxos subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) if err != nil { return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) } - signers = append(signers, subnetSigners) - // Sort the provided fxIDs - utils.Sort(fxIDs) + utils.Sort(fxIDs) // sort the provided fxIDs - // Create the tx utx := &txs.CreateChainTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, }}, SubnetID: subnetID, ChainName: chainName, @@ -437,6 +573,50 @@ func (b *builder) NewCreateChainTx( GenesisData: genesisData, SubnetAuth: subnetAuth, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput + outs []*avax.TransferableOutput + signers [][]*secp256k1.PrivateKey + ) + if isEForkActive { + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.CreateChainTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + } else { + timestamp := b.state.GetTimestamp() + createBlockchainTxFee := b.cfg.GetCreateBlockchainTxFee(timestamp) + ins, outs, _, signers, err = b.Spend(b.state, keys, 0, createBlockchainTxFee, changeAddr) + } + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + + // 3. Sign the tx + signers = append(signers, subnetSigners) tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -450,29 +630,62 @@ func (b *builder) NewCreateSubnetTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - timestamp := b.state.GetTimestamp() - createSubnetTxFee := b.cfg.GetCreateSubnetTxFee(timestamp) - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, createSubnetTxFee, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } + // 1. Build core transaction without utxos + utils.Sort(ownerAddrs) // sort control addresses - // Sort control addresses - utils.Sort(ownerAddrs) - - // Create the tx utx := &txs.CreateSubnetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, }}, Owner: &secp256k1fx.OutputOwners{ Threshold: threshold, Addrs: ownerAddrs, }, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput + outs []*avax.TransferableOutput + signers [][]*secp256k1.PrivateKey + err error + ) + if isEForkActive { + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.CreateSubnetTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + } else { + createSubnetTxFee := b.cfg.GetCreateSubnetTxFee(chainTime) + ins, outs, _, signers, err = b.Spend(b.state, keys, 0, createSubnetTxFee, changeAddr) + } + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + + // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -490,17 +703,11 @@ func (b *builder) NewAddValidatorTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - ins, unstakedOuts, stakedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkValidatorFee, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - // Create the tx + // 1. Build core transaction without utxos utx := &txs.AddValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, }}, Validator: txs.Validator{ NodeID: nodeID, @@ -508,7 +715,6 @@ func (b *builder) NewAddValidatorTx( End: endTime, Wght: stakeAmount, }, - StakeOuts: stakedOuts, RewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, @@ -516,6 +722,50 @@ func (b *builder) NewAddValidatorTx( }, DelegationShares: shares, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput + outs []*avax.TransferableOutput + stakedOuts []*avax.TransferableOutput + signers [][]*secp256k1.PrivateKey + err error + ) + if isEForkActive { + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.AddValidatorTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + } else { + ins, outs, stakedOuts, signers, err = b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkValidatorFee, changeAddr) + } + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + utx.StakeOuts = stakedOuts + + // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -583,17 +833,11 @@ func (b *builder) NewAddDelegatorTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - ins, unlockedOuts, lockedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkDelegatorFee, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - // Create the tx + // 1. Build core transaction without utxos utx := &txs.AddDelegatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: unlockedOuts, }}, Validator: txs.Validator{ NodeID: nodeID, @@ -601,13 +845,56 @@ func (b *builder) NewAddDelegatorTx( End: endTime, Wght: stakeAmount, }, - StakeOuts: lockedOuts, DelegationRewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{rewardAddress}, }, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput + outs []*avax.TransferableOutput + stakedOuts []*avax.TransferableOutput + signers [][]*secp256k1.PrivateKey + err error + ) + if isEForkActive { + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.AddDelegatorTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + } else { + ins, outs, stakedOuts, signers, err = b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkDelegatorFee, changeAddr) + } + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + utx.StakeOuts = stakedOuts + + // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -666,24 +953,15 @@ func (b *builder) NewAddSubnetValidatorTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - + // 1. Build core transaction without utxos subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) if err != nil { return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) } - signers = append(signers, subnetSigners) - - // Create the tx utx := &txs.AddSubnetValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, }}, SubnetValidator: txs.SubnetValidator{ Validator: txs.Validator{ @@ -696,6 +974,48 @@ func (b *builder) NewAddSubnetValidatorTx( }, SubnetAuth: subnetAuth, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput + outs []*avax.TransferableOutput + signers [][]*secp256k1.PrivateKey + ) + if isEForkActive { + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.AddSubnetValidatorTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + } else { + ins, outs, _, signers, err = b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) + } + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + + // 3. Sign the tx + signers = append(signers, subnetSigners) tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -709,29 +1029,62 @@ func (b *builder) NewRemoveSubnetValidatorTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - + // 1. Build core transaction without utxos subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) if err != nil { return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) } - signers = append(signers, subnetSigners) - - // Create the tx utx := &txs.RemoveSubnetValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, }}, Subnet: subnetID, NodeID: nodeID, SubnetAuth: subnetAuth, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput + outs []*avax.TransferableOutput + signers [][]*secp256k1.PrivateKey + ) + if isEForkActive { + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.RemoveSubnetValidatorTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + } else { + ins, outs, _, signers, err = b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) + } + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + + // 3. Sign the tx + signers = append(signers, subnetSigners) tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -746,23 +1099,15 @@ func (b *builder) NewTransferSubnetOwnershipTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - + // 1. Build core transaction without utxos subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) if err != nil { return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) } - signers = append(signers, subnetSigners) - utx := &txs.TransferSubnetOwnershipTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, }}, Subnet: subnetID, SubnetAuth: subnetAuth, @@ -771,6 +1116,48 @@ func (b *builder) NewTransferSubnetOwnershipTx( Addrs: ownerAddrs, }, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput + outs []*avax.TransferableOutput + signers [][]*secp256k1.PrivateKey + ) + if isEForkActive { + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.TransferSubnetOwnershipTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + } else { + ins, outs, _, signers, err = b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) + } + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + + // 3. Sign the tx + signers = append(signers, subnetSigners) tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -784,11 +1171,52 @@ func (b *builder) NewBaseTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - toBurn, err := math.Add64(amount, b.cfg.TxFee) - if err != nil { - return nil, fmt.Errorf("amount (%d) + tx fee(%d) overflows", amount, b.cfg.TxFee) + // 1. Build core transaction without utxos + utx := &txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: b.ctx.NetworkID, + BlockchainID: b.ctx.ChainID, + }, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput + outs []*avax.TransferableOutput + signers [][]*secp256k1.PrivateKey + err error + ) + if isEForkActive { + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.BaseTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + } else { + var toBurn uint64 + toBurn, err = math.Add64(amount, b.cfg.TxFee) + if err != nil { + return nil, fmt.Errorf("amount (%d) + tx fee(%d) overflows", amount, b.cfg.TxFee) + } + ins, outs, _, signers, err = b.Spend(b.state, keys, 0, toBurn, changeAddr) } - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, toBurn, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -803,14 +1231,10 @@ func (b *builder) NewBaseTx( avax.SortTransferableOutputs(outs, txs.Codec) - utx := &txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, - }, - } + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + + // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err diff --git a/vms/platformvm/txs/executor/atomic_tx_executor.go b/vms/platformvm/txs/executor/atomic_tx_executor.go index 2a35cb45eeab..a00d8381d7db 100644 --- a/vms/platformvm/txs/executor/atomic_tx_executor.go +++ b/vms/platformvm/txs/executor/atomic_tx_executor.go @@ -9,6 +9,8 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var _ txs.Visitor = (*AtomicTxExecutor)(nil) @@ -99,9 +101,11 @@ func (e *AtomicTxExecutor) atomicTx(tx txs.UnsignedTx) error { e.OnAccept = onAccept executor := StandardTxExecutor{ - Backend: e.Backend, - State: e.OnAccept, - Tx: e.Tx, + Backend: e.Backend, + BlkFeeManager: commonfees.NewManager(commonfees.Empty), + UnitCaps: commonfees.Empty, + State: e.OnAccept, + 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 0342c8dc1cfe..eabf9d3f9239 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -20,6 +20,8 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) // Ensure Execute fails when there are not enough control sigs @@ -47,9 +49,11 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(commonfees.Empty), + UnitCaps: commonfees.Empty, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -86,9 +90,11 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(commonfees.Empty), + UnitCaps: commonfees.Empty, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -119,9 +125,11 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(commonfees.Empty), + UnitCaps: commonfees.Empty, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, database.ErrNotFound) @@ -149,9 +157,11 @@ func TestCreateChainTxValid(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(commonfees.Empty), + UnitCaps: commonfees.Empty, + State: stateDiff, + Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) } @@ -220,9 +230,11 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(commonfees.Empty), + UnitCaps: commonfees.Empty, + 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 6d968daa4df0..d084fe473506 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -16,6 +16,8 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) func TestCreateSubnetTxAP3FeeChange(t *testing.T) { @@ -76,9 +78,11 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(commonfees.Empty), + UnitCaps: commonfees.Empty, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, test.expectedErr) diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 3d6683529cca..489741cdec2a 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -35,6 +35,7 @@ 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/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" @@ -228,10 +229,13 @@ func addSubnet( stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := config.EUpgradeDynamicFeesConfig executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: testSubnet1, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, + State: stateDiff, + Tx: testSubnet1, } require.NoError(testSubnet1.Unsigned.Visit(&executor)) diff --git a/vms/platformvm/txs/executor/proposal_tx_executor.go b/vms/platformvm/txs/executor/proposal_tx_executor.go index 0f082cb8b296..0aaab27c5b4b 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor.go @@ -16,6 +16,8 @@ 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" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) const ( @@ -45,7 +47,8 @@ var ( type ProposalTxExecutor struct { // inputs, to be filled before visitor methods are called *Backend - Tx *txs.Tx + BlkFeeManager *commonfees.Manager + 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 +117,8 @@ func (e *ProposalTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error { onAbortOuts, err := verifyAddValidatorTx( e.Backend, + e.BlkFeeManager, + commonfees.Empty, e.OnCommitState, e.Tx, tx, @@ -161,6 +166,8 @@ func (e *ProposalTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) if err := verifyAddSubnetValidatorTx( e.Backend, + e.BlkFeeManager, + commonfees.Empty, e.OnCommitState, e.Tx, tx, @@ -207,6 +214,8 @@ func (e *ProposalTxExecutor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { onAbortOuts, err := verifyAddDelegatorTx( e.Backend, + e.BlkFeeManager, + commonfees.Empty, e.OnCommitState, e.Tx, tx, diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 092333fb9dc4..2fd34ea1a28f 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" safemath "github.com/ava-labs/avalanchego/utils/math" + commonFees "github.com/ava-labs/avalanchego/vms/components/fees" ) var ( @@ -91,6 +92,8 @@ func verifySubnetValidatorPrimaryNetworkRequirements( // added to the staking set. func verifyAddValidatorTx( backend *Backend, + feeManager *commonFees.Manager, + unitCaps commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddValidatorTx, @@ -98,8 +101,11 @@ func verifyAddValidatorTx( []*avax.TransferableOutput, error, ) { - currentTimestamp := chainState.GetTimestamp() - if backend.Config.IsDurangoActivated(currentTimestamp) { + var ( + currentTimestamp = chainState.GetTimestamp() + isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + ) + if isDurangoActive { return nil, ErrAddValidatorTxPostDurango } @@ -144,7 +150,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 } @@ -166,8 +172,12 @@ func verifyAddValidatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: currentTimestamp, + IsEUpgradeActive: false, + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + ConsumedUnitsCap: unitCaps, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return nil, err @@ -195,6 +205,8 @@ func verifyAddValidatorTx( // AddSubnetValidatorTx. func verifyAddSubnetValidatorTx( backend *Backend, + feeManager *commonFees.Manager, + unitCaps commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddSubnetValidatorTx, @@ -264,8 +276,12 @@ func verifyAddSubnetValidatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: currentTimestamp, + IsEUpgradeActive: backend.Config.IsEUpgradeActivated(currentTimestamp), + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + ConsumedUnitsCap: unitCaps, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -299,6 +315,8 @@ func verifyAddSubnetValidatorTx( // * The flow checker passes. func verifyRemoveSubnetValidatorTx( backend *Backend, + feeManager *commonFees.Manager, + unitCaps commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.RemoveSubnetValidatorTx, @@ -349,8 +367,12 @@ func verifyRemoveSubnetValidatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: chainState.GetTimestamp(), + IsEUpgradeActive: backend.Config.IsEUpgradeActivated(currentTimestamp), + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + ConsumedUnitsCap: unitCaps, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return nil, false, err @@ -377,6 +399,8 @@ func verifyRemoveSubnetValidatorTx( // added to the staking set. func verifyAddDelegatorTx( backend *Backend, + feeManager *commonFees.Manager, + unitCaps commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddDelegatorTx, @@ -384,8 +408,11 @@ func verifyAddDelegatorTx( []*avax.TransferableOutput, error, ) { - currentTimestamp := chainState.GetTimestamp() - if backend.Config.IsDurangoActivated(currentTimestamp) { + var ( + currentTimestamp = chainState.GetTimestamp() + isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + ) + if isDurangoActive { return nil, ErrAddDelegatorTxPostDurango } @@ -394,7 +421,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 } @@ -425,7 +452,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 } @@ -472,8 +499,12 @@ func verifyAddDelegatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: chainState.GetTimestamp(), + IsEUpgradeActive: false, + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + ConsumedUnitsCap: unitCaps, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return nil, err @@ -501,6 +532,8 @@ func verifyAddDelegatorTx( // AddPermissionlessValidatorTx. func verifyAddPermissionlessValidatorTx( backend *Backend, + feeManager *commonFees.Manager, + unitCaps commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddPermissionlessValidatorTx, @@ -599,8 +632,12 @@ func verifyAddPermissionlessValidatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: currentTimestamp, + IsEUpgradeActive: backend.Config.IsEUpgradeActivated(currentTimestamp), + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + ConsumedUnitsCap: unitCaps, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -628,6 +665,8 @@ func verifyAddPermissionlessValidatorTx( // AddPermissionlessDelegatorTx. func verifyAddPermissionlessDelegatorTx( backend *Backend, + feeManager *commonFees.Manager, + unitCaps commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddPermissionlessDelegatorTx, @@ -751,8 +790,12 @@ func verifyAddPermissionlessDelegatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: currentTimestamp, + IsEUpgradeActive: backend.Config.IsEUpgradeActivated(currentTimestamp), + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + ConsumedUnitsCap: unitCaps, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -784,6 +827,8 @@ func verifyAddPermissionlessDelegatorTx( // * The flow checker passes. func verifyTransferSubnetOwnershipTx( backend *Backend, + feeManager *commonFees.Manager, + unitCaps commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.TransferSubnetOwnershipTx, @@ -812,9 +857,14 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck + currentTimestamp := chainState.GetTimestamp() feeCalculator := fees.Calculator{ - Config: backend.Config, - ChainTime: chainState.GetTimestamp(), + IsEUpgradeActive: backend.Config.IsEUpgradeActivated(currentTimestamp), + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + ConsumedUnitsCap: unitCaps, + Credentials: sTx.Creds, } 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 aa602725083f..0c270359eaa7 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" @@ -507,10 +508,10 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ FlowChecker: flowChecker, Config: &config.Config{ + AddSubnetValidatorFee: 1, CortinaTime: activeForkTime, DurangoTime: mockable.MaxTime, EUpgradeTime: mockable.MaxTime, - AddSubnetValidatorFee: 1, }, Ctx: ctx, Bootstrapped: bootstrapped, @@ -542,7 +543,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { expectedErr: ErrFutureStakeTime, }, { - name: "success", + name: "success pre EUpgrade", backendF: func(ctrl *gomock.Controller) *Backend { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) @@ -596,12 +597,14 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { var ( backend = tt.backendF(ctrl) - state = tt.stateF(ctrl) - sTx = tt.sTxF() - tx = tt.txF() + + feeManager = fees.NewManager(fees.Empty) + state = tt.stateF(ctrl) + sTx = tt.sTxF() + tx = tt.txF() ) - err := verifyAddPermissionlessValidatorTx(backend, state, sTx, tx) + err := verifyAddPermissionlessValidatorTx(backend, feeManager, fees.Empty, 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 29220ffee0b4..d18930a39a72 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -20,6 +20,8 @@ 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/fees" + + commonFees "github.com/ava-labs/avalanchego/vms/components/fees" ) var ( @@ -33,8 +35,10 @@ 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 + BlkFeeManager *commonFees.Manager + UnitCaps commonFees.Dimensions + State state.Diff // state is expected to be modified + Tx *txs.Tx // outputs of visitor execution OnAccept func() // may be nil @@ -70,8 +74,12 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { // Verify the flowcheck feeCalculator := fees.Calculator{ - Config: e.Backend.Config, - ChainTime: e.State.GetTimestamp(), + IsEUpgradeActive: e.Backend.Config.IsEUpgradeActivated(currentTimestamp), + Config: e.Backend.Config, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + ConsumedUnitsCap: e.UnitCaps, + Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -123,8 +131,12 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { // Verify the flowcheck feeCalculator := fees.Calculator{ - Config: e.Backend.Config, - ChainTime: e.State.GetTimestamp(), + IsEUpgradeActive: e.Backend.Config.IsEUpgradeActivated(currentTimestamp), + Config: e.Backend.Config, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + ConsumedUnitsCap: e.UnitCaps, + Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -210,9 +222,17 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck + var ( + cfg = e.Backend.Config + currentTimestamp = e.State.GetTimestamp() + ) feeCalculator := fees.Calculator{ - Config: e.Backend.Config, - ChainTime: e.State.GetTimestamp(), + IsEUpgradeActive: cfg.IsEUpgradeActivated(currentTimestamp), + Config: cfg, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + ConsumedUnitsCap: e.UnitCaps, + Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -275,8 +295,12 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { // Verify the flowcheck feeCalculator := fees.Calculator{ - Config: e.Backend.Config, - ChainTime: e.State.GetTimestamp(), + IsEUpgradeActive: e.Backend.Config.IsEUpgradeActivated(currentTimestamp), + Config: e.Backend.Config, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + ConsumedUnitsCap: e.UnitCaps, + Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -346,6 +370,8 @@ func (e *StandardTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error { if _, err := verifyAddValidatorTx( e.Backend, + e.BlkFeeManager, + e.UnitCaps, e.State, e.Tx, tx, @@ -375,6 +401,8 @@ func (e *StandardTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error { func (e *StandardTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { if err := verifyAddSubnetValidatorTx( e.Backend, + e.BlkFeeManager, + e.UnitCaps, e.State, e.Tx, tx, @@ -395,6 +423,8 @@ func (e *StandardTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) func (e *StandardTxExecutor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { if _, err := verifyAddDelegatorTx( e.Backend, + e.BlkFeeManager, + e.UnitCaps, e.State, e.Tx, tx, @@ -420,6 +450,8 @@ func (e *StandardTxExecutor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { func (e *StandardTxExecutor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { staker, isCurrentValidator, err := verifyRemoveSubnetValidatorTx( e.Backend, + e.BlkFeeManager, + e.UnitCaps, e.State, e.Tx, tx, @@ -469,8 +501,12 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error totalRewardAmount := tx.MaximumSupply - tx.InitialSupply feeCalculator := fees.Calculator{ - Config: e.Backend.Config, - ChainTime: currentTimestamp, + IsEUpgradeActive: e.Backend.Config.IsEUpgradeActivated(currentTimestamp), + Config: e.Backend.Config, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + ConsumedUnitsCap: e.UnitCaps, + Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -507,6 +543,8 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error func (e *StandardTxExecutor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { if err := verifyAddPermissionlessValidatorTx( e.Backend, + e.BlkFeeManager, + e.UnitCaps, e.State, e.Tx, tx, @@ -539,6 +577,8 @@ func (e *StandardTxExecutor) AddPermissionlessValidatorTx(tx *txs.AddPermissionl func (e *StandardTxExecutor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { if err := verifyAddPermissionlessDelegatorTx( e.Backend, + e.BlkFeeManager, + e.UnitCaps, e.State, e.Tx, tx, @@ -563,6 +603,8 @@ func (e *StandardTxExecutor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionl func (e *StandardTxExecutor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { err := verifyTransferSubnetOwnershipTx( e.Backend, + e.BlkFeeManager, + e.UnitCaps, e.State, e.Tx, tx, @@ -599,8 +641,12 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { currentTimestamp = e.State.GetTimestamp() ) feeCalculator := fees.Calculator{ - Config: cfg, - ChainTime: currentTimestamp, + IsEUpgradeActive: cfg.IsEUpgradeActivated(currentTimestamp), + Config: cfg, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + ConsumedUnitsCap: e.UnitCaps, + Credentials: e.Tx.Creds, } 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 eacd9ac57dc8..43d2498391ec 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -25,6 +25,7 @@ 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/components/fees" "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" @@ -90,9 +91,11 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, test.expectedError) @@ -346,9 +349,11 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { freshTH.config.BanffTime = onAcceptState.GetTimestamp() executor := StandardTxExecutor{ - Backend: &freshTH.backend, - State: onAcceptState, - Tx: tx, + Backend: &freshTH.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, tt.expectedExecutionErr) @@ -384,9 +389,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrPeriodMismatch) @@ -412,9 +419,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) } @@ -454,9 +463,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrNotValidator) @@ -497,9 +508,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrPeriodMismatch) @@ -523,9 +536,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrPeriodMismatch) @@ -548,9 +563,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) } @@ -576,9 +593,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrTimestampNotBeforeStartTime) @@ -632,9 +651,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: duplicateSubnetTx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: duplicateSubnetTx, } err = duplicateSubnetTx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrDuplicateValidator) @@ -669,9 +690,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, secp256k1fx.ErrInputIndicesNotSortedUnique) @@ -702,9 +725,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -733,9 +758,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -774,9 +801,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrDuplicateValidator) @@ -809,9 +838,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrTimestampNotBeforeStartTime) @@ -835,9 +866,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { require.NoError(err) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrFutureStakeTime) @@ -874,9 +907,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.AddTx(tx, status.Committed) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrAlreadyValidator) @@ -910,9 +945,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.AddTx(tx, status.Committed) executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrAlreadyValidator) @@ -945,9 +982,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { } executor := StandardTxExecutor{ - Backend: &env.backend, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrFlowCheckFailed) @@ -1735,7 +1774,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) @@ -1761,8 +1800,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1791,8 +1832,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1822,8 +1865,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1856,8 +1901,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1888,8 +1935,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1919,8 +1968,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1952,8 +2003,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1965,7 +2018,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) @@ -1988,8 +2041,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -2148,8 +2203,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -2178,8 +2235,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -2210,8 +2269,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -2247,8 +2308,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -2289,8 +2352,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(fees.Empty), + UnitCaps: fees.Empty, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index 123052577e54..86f3e92821a3 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -4,47 +4,125 @@ package fees import ( + "errors" + "fmt" "time" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/fees" + "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/txs" ) -var _ txs.Visitor = (*Calculator)(nil) +var ( + _ txs.Visitor = (*Calculator)(nil) + + errFailedFeeCalculation = errors.New("failed fee calculation") + errFailedConsumedUnitsCumulation = errors.New("failed cumulating consumed units") +) type Calculator struct { + // setup + IsEUpgradeActive bool + // Pre E-fork inputs Config *config.Config ChainTime time.Time + // Post E-fork inputs + FeeManager *fees.Manager + ConsumedUnitsCap fees.Dimensions + + // common inputs + Credentials []verify.Verifiable + // outputs of visitor execution Fee uint64 } -func (fc *Calculator) AddValidatorTx(*txs.AddValidatorTx) error { - fc.Fee = fc.Config.AddPrimaryNetworkValidatorFee - return nil +func (fc *Calculator) AddValidatorTx(tx *txs.AddValidatorTx) error { + if !fc.IsEUpgradeActive { + fc.Fee = fc.Config.AddPrimaryNetworkValidatorFee + return nil + } + + outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.StakeOuts)) + copy(outs, tx.Outs) + copy(outs[len(tx.Outs):], tx.StakeOuts) + + consumedUnits, err := fc.commonConsumedUnits(tx, outs, tx.Ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err } -func (fc *Calculator) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { - fc.Fee = fc.Config.AddSubnetValidatorFee - return nil +func (fc *Calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { + if !fc.IsEUpgradeActive { + fc.Fee = fc.Config.AddSubnetValidatorFee + return nil + } + + consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err } -func (fc *Calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { - fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee - return nil +func (fc *Calculator) AddDelegatorTx(tx *txs.AddDelegatorTx) error { + if !fc.IsEUpgradeActive { + fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee + return nil + } + + outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.StakeOuts)) + copy(outs, tx.Outs) + copy(outs[len(tx.Outs):], tx.StakeOuts) + + consumedUnits, err := fc.commonConsumedUnits(tx, outs, tx.Ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err } -func (fc *Calculator) CreateChainTx(*txs.CreateChainTx) error { - fc.Fee = fc.Config.GetCreateBlockchainTxFee(fc.ChainTime) - return nil +func (fc *Calculator) CreateChainTx(tx *txs.CreateChainTx) error { + if !fc.IsEUpgradeActive { + fc.Fee = fc.Config.GetCreateBlockchainTxFee(fc.ChainTime) + return nil + } + + consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err } -func (fc *Calculator) CreateSubnetTx(*txs.CreateSubnetTx) error { - fc.Fee = fc.Config.GetCreateSubnetTxFee(fc.ChainTime) - return nil +func (fc *Calculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { + if !fc.IsEUpgradeActive { + fc.Fee = fc.Config.GetCreateSubnetTxFee(fc.ChainTime) + return nil + } + + consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err } func (*Calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { @@ -55,50 +133,215 @@ 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) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { + if !fc.IsEUpgradeActive { + fc.Fee = fc.Config.TxFee + return nil + } + + consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err } -func (fc *Calculator) TransformSubnetTx(*txs.TransformSubnetTx) error { - fc.Fee = fc.Config.TransformSubnetTxFee - return nil +func (fc *Calculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { + if !fc.IsEUpgradeActive { + fc.Fee = fc.Config.TransformSubnetTxFee + return nil + } + + consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err } -func (fc *Calculator) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { - fc.Fee = fc.Config.TxFee - return nil +func (fc *Calculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { + if !fc.IsEUpgradeActive { + fc.Fee = fc.Config.TxFee + return nil + } + + consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err } func (fc *Calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { - if tx.Subnet != constants.PrimaryNetworkID { - fc.Fee = fc.Config.AddSubnetValidatorFee - } else { - fc.Fee = fc.Config.AddPrimaryNetworkValidatorFee + if !fc.IsEUpgradeActive { + if tx.Subnet != constants.PrimaryNetworkID { + fc.Fee = fc.Config.AddSubnetValidatorFee + } else { + fc.Fee = fc.Config.AddPrimaryNetworkValidatorFee + } + return nil } - return nil + + outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.StakeOuts)) + copy(outs, tx.Outs) + copy(outs[len(tx.Outs):], tx.StakeOuts) + + consumedUnits, err := fc.commonConsumedUnits(tx, outs, tx.Ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err } func (fc *Calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { - if tx.Subnet != constants.PrimaryNetworkID { - fc.Fee = fc.Config.AddSubnetDelegatorFee - } else { - fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee + if !fc.IsEUpgradeActive { + if tx.Subnet != constants.PrimaryNetworkID { + fc.Fee = fc.Config.AddSubnetDelegatorFee + } else { + fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee + } + return nil + } + + outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.StakeOuts)) + copy(outs, tx.Outs) + copy(outs[len(tx.Outs):], tx.StakeOuts) + + consumedUnits, err := fc.commonConsumedUnits(tx, outs, tx.Ins) + if err != nil { + return err } - return nil + + _, err = fc.AddFeesFor(consumedUnits) + return err } -func (fc *Calculator) BaseTx(*txs.BaseTx) error { - fc.Fee = fc.Config.TxFee - return nil +func (fc *Calculator) BaseTx(tx *txs.BaseTx) error { + if !fc.IsEUpgradeActive { + fc.Fee = fc.Config.TxFee + return nil + } + + consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err } -func (fc *Calculator) ImportTx(*txs.ImportTx) error { - fc.Fee = fc.Config.TxFee - return nil +func (fc *Calculator) ImportTx(tx *txs.ImportTx) error { + if !fc.IsEUpgradeActive { + fc.Fee = fc.Config.TxFee + return nil + } + + ins := make([]*avax.TransferableInput, len(tx.Ins)+len(tx.ImportedInputs)) + copy(ins, tx.Ins) + copy(ins[len(tx.Ins):], tx.ImportedInputs) + + consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err +} + +func (fc *Calculator) ExportTx(tx *txs.ExportTx) error { + if !fc.IsEUpgradeActive { + fc.Fee = fc.Config.TxFee + return nil + } + + outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.ExportedOutputs)) + copy(outs, tx.Outs) + copy(outs[len(tx.Outs):], tx.ExportedOutputs) + + consumedUnits, err := fc.commonConsumedUnits(tx, outs, tx.Ins) + if err != nil { + return err + } + + _, err = fc.AddFeesFor(consumedUnits) + return err } -func (fc *Calculator) ExportTx(*txs.ExportTx) error { - fc.Fee = fc.Config.TxFee - return nil +func (fc *Calculator) commonConsumedUnits( + uTx txs.UnsignedTx, + allOuts []*avax.TransferableOutput, + allIns []*avax.TransferableInput, +) (fees.Dimensions, error) { + var consumedUnits fees.Dimensions + + uTxSize, err := txs.Codec.Size(txs.CodecVersion, uTx) + if err != nil { + return consumedUnits, fmt.Errorf("couldn't calculate UnsignedTx marshal length: %w", err) + } + credsSize, err := txs.Codec.Size(txs.CodecVersion, fc.Credentials) + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving size of credentials: %w", err) + } + consumedUnits[fees.Bandwidth] = uint64(uTxSize + credsSize) + + inputDimensions, err := fees.GetInputsDimensions(txs.Codec, txs.CodecVersion, allIns) + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving size of inputs: %w", err) + } + inputDimensions[fees.Bandwidth] = 0 // inputs bandwidth is already accounted for above, so we zero it + consumedUnits, err = fees.Add(consumedUnits, inputDimensions) + if err != nil { + return consumedUnits, fmt.Errorf("failed adding inputs: %w", err) + } + + outputDimensions, err := fees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, allOuts) + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving size of outputs: %w", err) + } + outputDimensions[fees.Bandwidth] = 0 // outputs bandwidth is already accounted for above, so we zero it + consumedUnits, err = fees.Add(consumedUnits, outputDimensions) + if err != nil { + return consumedUnits, fmt.Errorf("failed adding outputs: %w", err) + } + + return consumedUnits, nil +} + +func (fc *Calculator) AddFeesFor(consumedUnits fees.Dimensions) (uint64, error) { + boundBreached, dimension := fc.FeeManager.CumulateUnits(consumedUnits, fc.ConsumedUnitsCap) + if boundBreached { + return 0, fmt.Errorf("%w: breached dimension %d", errFailedConsumedUnitsCumulation, dimension) + } + + fee, err := fc.FeeManager.CalculateFee(consumedUnits) + if err != nil { + return 0, fmt.Errorf("%w: %w", errFailedFeeCalculation, err) + } + + fc.Fee += fee + return fee, nil +} + +func (fc *Calculator) RemoveFeesFor(unitsToRm fees.Dimensions) (uint64, error) { + if err := fc.FeeManager.RemoveUnits(unitsToRm); err != nil { + return 0, fmt.Errorf("failed removing units: %w", err) + } + + fee, err := fc.FeeManager.CalculateFee(unitsToRm) + if err != nil { + return 0, fmt.Errorf("%w: %w", errFailedFeeCalculation, err) + } + + fc.Fee -= fee + return fee, nil } diff --git a/vms/platformvm/txs/fees/calculator_test.go b/vms/platformvm/txs/fees/calculator_test.go new file mode 100644 index 000000000000..9d1d0cb3126f --- /dev/null +++ b/vms/platformvm/txs/fees/calculator_test.go @@ -0,0 +1,1685 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fees + +import ( + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/codec" + "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/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/fees" + "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 ( + testUnitFees = fees.Dimensions{ + 1 * units.MicroAvax, + 2 * units.MicroAvax, + 3 * units.MicroAvax, + 4 * units.MicroAvax, + } + testBlockMaxConsumedUnits = fees.Dimensions{ + 3000, + 3500, + 1000, + 1000, + } + + 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) + consumedUnitCapsF func() fees.Dimensions + expectedError error + checksF func(*testing.T, *Calculator) +} + +func TestAddAndRemoveFees(t *testing.T) { + r := require.New(t) + + fc := &Calculator{ + IsEUpgradeActive: true, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + + var ( + units = fees.Dimensions{1, 2, 3, 4} + doubleUnits = fees.Dimensions{2, 4, 6, 8} + ) + + feeDelta, err := fc.AddFeesFor(units) + r.NoError(err) + r.Equal(units, fc.FeeManager.GetCumulatedUnits()) + r.NotZero(feeDelta) + r.Equal(feeDelta, fc.Fee) + + feeDelta2, err := fc.AddFeesFor(units) + r.NoError(err) + r.Equal(doubleUnits, fc.FeeManager.GetCumulatedUnits()) + r.Equal(feeDelta, feeDelta2) + r.Equal(feeDelta+feeDelta2, fc.Fee) + + feeDelta3, err := fc.RemoveFeesFor(units) + r.NoError(err) + r.Equal(units, fc.FeeManager.GetCumulatedUnits()) + r.Equal(feeDelta, feeDelta3) + r.Equal(feeDelta, fc.Fee) + + feeDelta4, err := fc.RemoveFeesFor(units) + r.NoError(err) + r.Zero(fc.FeeManager.GetCumulatedUnits()) + r.Equal(feeDelta, feeDelta4) + r.Zero(fc.Fee) +} + +func TestUTXOsAreAdditiveInSize(t *testing.T) { + // Show that including utxos of size [S] into a tx of size [T] + // result in a tx of size [S+T-CodecVersion] + // This is key to calculate fees correctly while building a tx + + uTx := &txs.AddValidatorTx{ + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: rand.Uint32(), //#nosec G404 + BlockchainID: ids.GenerateTestID(), + Memo: []byte{'a', 'b', 'c'}, + Ins: make([]*avax.TransferableInput, 0), + Outs: make([]*avax.TransferableOutput, 0), + }, + }, + } + + uTxNakedSize := 105 + uTxSize, err := txs.Codec.Size(txs.CodecVersion, uTx) + require.NoError(t, err) + require.Equal(t, uTxNakedSize, uTxSize) + + // input to add + input := &avax.TransferableInput{ + UTXOID: avax.UTXOID{ + TxID: ids.ID{'t', 'x', 'I', 'D'}, + OutputIndex: 2, + }, + Asset: avax.Asset{ID: ids.GenerateTestID()}, + In: &secp256k1fx.TransferInput{ + Amt: uint64(5678), + Input: secp256k1fx.Input{SigIndices: []uint32{0}}, + }, + } + inSize, err := txs.Codec.Size(txs.CodecVersion, input) + require.NoError(t, err) + + // include input in uTx and check that sizes add + uTx.BaseTx.BaseTx.Ins = append(uTx.BaseTx.BaseTx.Ins, input) + uTxSize, err = txs.Codec.Size(txs.CodecVersion, uTx) + require.NoError(t, err) + require.Equal(t, uTxNakedSize+(inSize-codec.CodecVersionSize), uTxSize) + + // output to add + output := &avax.TransferableOutput{ + Asset: avax.Asset{ + ID: ids.GenerateTestID(), + }, + Out: &stakeable.LockOut{ + Locktime: 87654321, + TransferableOut: &secp256k1fx.TransferOutput{ + Amt: 1, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 12345678, + Threshold: 0, + Addrs: []ids.ShortID{}, + }, + }, + }, + } + outSize, err := txs.Codec.Size(txs.CodecVersion, output) + require.NoError(t, err) + + // include output in uTx and check that sizes add + uTx.BaseTx.BaseTx.Outs = append(uTx.BaseTx.BaseTx.Outs, output) + uTxSize, err = txs.Codec.Size(txs.CodecVersion, uTx) + require.NoError(t, err) + require.Equal(t, uTxNakedSize+(inSize-codec.CodecVersionSize)+(outSize-codec.CodecVersionSize), uTxSize) + + // include output in uTx as stake and check that sizes add + uTx.StakeOuts = append(uTx.StakeOuts, output) + uTxSize, err = txs.Codec.Size(txs.CodecVersion, uTx) + require.NoError(t, err) + require.Equal(t, uTxNakedSize+(inSize-codec.CodecVersionSize)+(outSize-codec.CodecVersionSize)+(outSize-codec.CodecVersionSize), uTxSize) +} + +func TestAddValidatorTxFees(t *testing.T) { + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.AddPrimaryNetworkValidatorFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3719*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 741, + 1090, + 266, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, bandwidth cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.Bandwidth] = 741 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestAddSubnetValidatorTxFees(t *testing.T) { + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.AddSubnetValidatorFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3345*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 649, + 1090, + 172, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestAddDelegatorTxFees(t *testing.T) { + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.AddPrimaryNetworkDelegatorFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3715*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 737, + 1090, + 266, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestCreateChainTxFees(t *testing.T) { + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.CreateBlockchainTxFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3388*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 692, + 1090, + 172, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestCreateSubnetTxFees(t *testing.T) { + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.CreateSubnetTxFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3293*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 597, + 1090, + 172, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestRemoveSubnetValidatorTxFees(t *testing.T) { + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.TxFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3321*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 625, + 1090, + 172, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestTransformSubnetTxFees(t *testing.T) { + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.TransformSubnetTxFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3406*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 710, + 1090, + 172, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestTransferSubnetOwnershipTxFees(t *testing.T) { + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.TxFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3337*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 641, + 1090, + 172, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestAddPermissionlessValidatorTxFees(t *testing.T) { + 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: ids.GenerateTestID(), + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.AddSubnetValidatorFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3939*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 961, + 1090, + 266, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestAddPermissionlessDelegatorTxFees(t *testing.T) { + 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: ids.GenerateTestID(), + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.AddSubnetDelegatorFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3747*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 769, + 1090, + 266, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestBaseTxFees(t *testing.T) { + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.TxFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3253*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 557, + 1090, + 172, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestImportTxFees(t *testing.T) { + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.TxFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 5827*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 681, + 2180, + 262, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +func TestExportTxFees(t *testing.T) { + 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) + + tests := []feeTests{ + { + description: "pre E fork", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(-1 * time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, fc.Config.TxFee, fc.Fee) + }, + }, + { + description: "post E fork, success", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + expectedError: nil, + checksF: func(t *testing.T, fc *Calculator) { + require.Equal(t, 3663*units.MicroAvax, fc.Fee) + require.Equal(t, + fees.Dimensions{ + 685, + 1090, + 266, + 0, + }, + fc.FeeManager.GetCumulatedUnits(), + ) + }, + }, + { + description: "post E fork, utxos read cap breached", + cfgAndChainTimeF: func() (*config.Config, time.Time) { + eForkTime := time.Now().Truncate(time.Second) + chainTime := eForkTime.Add(time.Second) + + cfg := feeTestsDefaultCfg + cfg.DurangoTime = durangoTime + cfg.EUpgradeTime = eForkTime + + return &cfg, chainTime + }, + consumedUnitCapsF: func() fees.Dimensions { + caps := testBlockMaxConsumedUnits + caps[fees.UTXORead] = 1090 - 1 + return caps + }, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + cfg, chainTime := tt.cfgAndChainTimeF() + + consumedUnitCaps := testBlockMaxConsumedUnits + if tt.consumedUnitCapsF != nil { + consumedUnitCaps = tt.consumedUnitCapsF() + } + + fc := &Calculator{ + IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + ConsumedUnitsCap: consumedUnitCaps, + Credentials: sTx.Creds, + } + err := uTx.Visit(fc) + r.ErrorIs(err, tt.expectedError) + tt.checksF(t, fc) + }) + } +} + +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/tx.go b/vms/platformvm/txs/tx.go index 9874f66e0468..c33f67c8cba3 100644 --- a/vms/platformvm/txs/tx.go +++ b/vms/platformvm/txs/tx.go @@ -138,8 +138,10 @@ func (tx *Tx) Sign(c codec.Manager, signers [][]*secp256k1.PrivateKey) error { } // Attach credentials + tx.Creds = EmptyCredentials(signers) + hash := hashing.ComputeHash256(unsignedBytes) - for _, keys := range signers { + for i, keys := range signers { cred := &secp256k1fx.Credential{ Sigs: make([][secp256k1.SignatureLen]byte, len(keys)), } @@ -150,7 +152,7 @@ func (tx *Tx) Sign(c codec.Manager, signers [][]*secp256k1.PrivateKey) error { } copy(cred.Sigs[i][:], sig) } - tx.Creds = append(tx.Creds, cred) // Attach credential + tx.Creds[i] = cred // Attach credential } signedBytes, err := c.Marshal(CodecVersion, tx) @@ -160,3 +162,13 @@ func (tx *Tx) Sign(c codec.Manager, signers [][]*secp256k1.PrivateKey) error { tx.SetBytes(unsignedBytes, signedBytes) return nil } + +func EmptyCredentials(signers [][]*secp256k1.PrivateKey) []verify.Verifiable { + creds := make([]verify.Verifiable, 0, len(signers)) + for i := 0; i < len(signers); i++ { + creds = append(creds, &secp256k1fx.Credential{ + Sigs: make([][secp256k1.SignatureLen]byte, len(signers)), + }) + } + return creds +} diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index f22a76fd0b8f..c2179f921ad3 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -22,7 +22,10 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "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/secp256k1fx" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var ( @@ -69,6 +72,20 @@ type Spender interface { error, ) + FinanceTx( + utxoReader avax.UTXOReader, + keys []*secp256k1.PrivateKey, + amount uint64, + feeCalc *fees.Calculator, + changeAddr ids.ShortID, + ) ( + []*avax.TransferableInput, // inputs + []*avax.TransferableOutput, // returnedOutputs + []*avax.TransferableOutput, // stakedOutputs + [][]*secp256k1.PrivateKey, // signers + error, + ) + // Authorize an operation on behalf of the named subnet with the provided // keys. Authorize( @@ -390,6 +407,344 @@ func (h *handler) Spend( return ins, returnedOuts, stakedOuts, signers, nil } +func (h *handler) FinanceTx( + utxoReader avax.UTXOReader, + keys []*secp256k1.PrivateKey, + amount uint64, + feeCalc *fees.Calculator, + changeAddr ids.ShortID, +) ( + []*avax.TransferableInput, // inputs + []*avax.TransferableOutput, // returnedOutputs + []*avax.TransferableOutput, // stakedOutputs + [][]*secp256k1.PrivateKey, // signers + error, +) { + addrs := set.NewSet[ids.ShortID](len(keys)) // The addresses controlled by [keys] + for _, key := range keys { + addrs.Add(key.PublicKey().Address()) + } + utxos, err := avax.GetAllUTXOs(utxoReader, addrs) // The UTXOs controlled by [keys] + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("couldn't get UTXOs: %w", err) + } + + kc := secp256k1fx.NewKeychain(keys...) // Keychain consumes UTXOs and creates new ones + + // Minimum time this transaction will be issued at + now := uint64(h.clk.Time().Unix()) + + ins := []*avax.TransferableInput{} + returnedOuts := []*avax.TransferableOutput{} + stakedOuts := []*avax.TransferableOutput{} + signers := [][]*secp256k1.PrivateKey{} + + targetFee := feeCalc.Fee + + // Amount of AVAX that has been staked + amountStaked := uint64(0) + + // Consume locked UTXOs + for _, utxo := range utxos { + // If we have consumed more AVAX than we are trying to stake, then we + // have no need to consume more locked AVAX + if amountStaked >= amount { + break + } + + if assetID := utxo.AssetID(); assetID != h.ctx.AVAXAssetID { + continue // We only care about staking AVAX, so ignore other assets + } + + out, ok := utxo.Out.(*stakeable.LockOut) + if !ok { + // This output isn't locked, so it will be handled during the next + // iteration of the UTXO set + continue + } + if out.Locktime <= now { + // This output is no longer locked, so it will be handled during the + // next iteration of the UTXO set + continue + } + + inner, ok := out.TransferableOut.(*secp256k1fx.TransferOutput) + if !ok { + // We only know how to clone secp256k1 outputs for now + continue + } + + inIntf, inSigners, err := kc.Spend(out.TransferableOut, now) + if err != nil { + // We couldn't spend the output, so move on to the next one + continue + } + in, ok := inIntf.(avax.TransferableIn) + if !ok { // should never happen + h.ctx.Log.Warn("wrong input type", + zap.String("expectedType", "avax.TransferableIn"), + zap.String("actualType", fmt.Sprintf("%T", inIntf)), + ) + continue + } + input := &avax.TransferableInput{ + UTXOID: utxo.UTXOID, + Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, + In: &stakeable.LockIn{ + Locktime: out.Locktime, + TransferableIn: in, + }, + } + + // The remaining value is initially the full value of the input + remainingValue := in.Amount() + + // update fees to target given the extra input added + insDimensions, err := commonfees.GetInputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("failed calculating input size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(insDimensions) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("account for input fees: %w", err) + } + targetFee += addedFees + + // Stake any value that should be staked + amountToStake := math.Min( + amount-amountStaked, // Amount we still need to stake + remainingValue, // Amount available to stake + ) + amountStaked += amountToStake + remainingValue -= amountToStake + + // Add the input to the consumed inputs + ins = append(ins, input) + + stakedOut := &avax.TransferableOutput{ + Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, + Out: &stakeable.LockOut{ + Locktime: out.Locktime, + TransferableOut: &secp256k1fx.TransferOutput{ + Amt: amountToStake, + OutputOwners: inner.OutputOwners, + }, + }, + } + + // update fees to target given the staked output added + outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{stakedOut}) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("failed calculating stakedOut size: %w", err) + } + addedFees, err = feeCalc.AddFeesFor(outDimensions) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("account for stakedOut fees: %w", err) + } + targetFee += addedFees + + // Add the output to the staked outputs + stakedOuts = append(stakedOuts, stakedOut) + + if remainingValue > 0 { + // This input provided more value than was needed to be locked. + // Some of it must be returned + changeOut := &avax.TransferableOutput{ + Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, + Out: &stakeable.LockOut{ + Locktime: out.Locktime, + TransferableOut: &secp256k1fx.TransferOutput{ + Amt: remainingValue, + OutputOwners: inner.OutputOwners, + }, + }, + } + + // update fees to target given the change output added + outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("failed calculating changeOut size: %w", err) + } + addedFees, err = feeCalc.AddFeesFor(outDimensions) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("account for stakedOut fees: %w", err) + } + targetFee += addedFees + + returnedOuts = append(returnedOuts, changeOut) + } + + // Add the signers needed for this input to the set of signers + signers = append(signers, inSigners) + } + + // Amount of AVAX that has been burned + amountBurned := uint64(0) + + for _, utxo := range utxos { + // If we have consumed more AVAX than we are trying to stake, + // and we have burned more AVAX than we need to, + // then we have no need to consume more AVAX + if amountBurned >= targetFee && amountStaked >= amount { + break + } + + if assetID := utxo.AssetID(); assetID != h.ctx.AVAXAssetID { + continue // We only care about burning AVAX, so ignore other assets + } + + out := utxo.Out + inner, ok := out.(*stakeable.LockOut) + if ok { + if inner.Locktime > now { + // This output is currently locked, so this output can't be + // burned. Additionally, it may have already been consumed + // above. Regardless, we skip to the next UTXO + continue + } + out = inner.TransferableOut + } + + inIntf, inSigners, err := kc.Spend(out, now) + if err != nil { + // We couldn't spend this UTXO, so we skip to the next one + continue + } + in, ok := inIntf.(avax.TransferableIn) + if !ok { + // Because we only use the secp Fx right now, this should never + // happen + continue + } + input := &avax.TransferableInput{ + UTXOID: utxo.UTXOID, + Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, + In: in, + } + + // The remaining value is initially the full value of the input + remainingValue := in.Amount() + + // update fees to target given the extra input added + insDimensions, err := commonfees.GetInputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("failed calculating input size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(insDimensions) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("account for input fees: %w", err) + } + targetFee += addedFees + + // Burn any value that should be burned + amountToBurn := math.Min( + targetFee-amountBurned, // Amount we still need to burn + remainingValue, // Amount available to burn + ) + amountBurned += amountToBurn + remainingValue -= amountToBurn + + // Stake any value that should be staked + amountToStake := math.Min( + amount-amountStaked, // Amount we still need to stake + remainingValue, // Amount available to stake + ) + amountStaked += amountToStake + remainingValue -= amountToStake + + // Add the input to the consumed inputs + ins = append(ins, input) + + if amountToStake > 0 { + // Some of this input was put for staking + stakedOut := &avax.TransferableOutput{ + Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: amountToStake, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }, + }, + } + + // update fees to target given the extra input added + outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{stakedOut}) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("failed calculating output size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(outDimensions) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("account for output fees: %w", err) + } + targetFee += addedFees + + amountToBurn := math.Min( + targetFee-amountBurned, // Amount we still need to burn + remainingValue, // Amount available to burn + ) + amountBurned += amountToBurn + remainingValue -= amountToBurn + + stakedOuts = append(stakedOuts, stakedOut) + } + + if remainingValue > 0 { + changeOut := &avax.TransferableOutput{ + Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + // Amt: remainingValue, // SET IT AFTER CONSIDERING ITS OWN FEES + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }, + }, + } + + // update fees to target given the extra input added + outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("failed calculating output size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(outDimensions) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("account for output fees: %w", err) + } + + if remainingValue > addedFees { + targetFee += addedFees + amountBurned += addedFees + remainingValue -= addedFees + + changeOut.Out.(*secp256k1fx.TransferOutput).Amt = remainingValue + // This input had extra value, so some of it must be returned + returnedOuts = append(returnedOuts, changeOut) + } + + // If this UTXO has not enough value to cover for its own taxes, + // we fully consume it (no output) and move to the next UTXO to pay for it. + } + + // Add the signers needed for this input to the set of signers + signers = append(signers, inSigners) + } + + if amountBurned < targetFee || amountStaked < amount { + return nil, nil, nil, nil, fmt.Errorf( + "%w (unlocked, locked) (%d, %d) but need (%d, %d)", + ErrInsufficientFunds, amountBurned, amountStaked, targetFee, amount, + ) + } + + avax.SortTransferableInputsWithSigners(ins, signers) // sort inputs and keys + avax.SortTransferableOutputs(returnedOuts, txs.Codec) // sort outputs + avax.SortTransferableOutputs(stakedOuts, txs.Codec) // sort outputs + + return ins, returnedOuts, stakedOuts, signers, nil +} + func (h *handler) Authorize( state state.Chain, subnetID ids.ID, diff --git a/vms/platformvm/utxo/handler_test.go b/vms/platformvm/utxo/handler_test.go index d0224ed4666a..08379e9b2f5b 100644 --- a/vms/platformvm/utxo/handler_test.go +++ b/vms/platformvm/utxo/handler_test.go @@ -9,18 +9,24 @@ import ( "time" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/snowtest" "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/components/verify" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" + "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/secp256k1fx" safemath "github.com/ava-labs/avalanchego/utils/math" + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var _ txs.UnsignedTx = (*dummyUnsignedTx)(nil) @@ -33,6 +39,680 @@ func (*dummyUnsignedTx) Visit(txs.Visitor) error { return nil } +func TestVerifyFinanceTx(t *testing.T) { + fx := &secp256k1fx.Fx{} + require.NoError(t, fx.InitializeVM(&secp256k1fx.TestVM{})) + require.NoError(t, fx.Bootstrapped()) + + ctx := snowtest.Context(t, snowtest.PChainID) + keys := secp256k1.TestKeys() + + h := &handler{ + ctx: ctx, + clk: &mockable.Clock{}, + fx: fx, + } + + testUnitFees := commonfees.Dimensions{ + 1 * units.MicroAvax, + 2 * units.MicroAvax, + 3 * units.MicroAvax, + 4 * units.MicroAvax, + } + testBlockMaxConsumedUnits := commonfees.Dimensions{ + math.MaxUint64, + math.MaxUint64, + math.MaxUint64, + math.MaxUint64, + } + + var ( + amountToStake = units.MilliAvax + + bigUtxoTxID = ids.ID{0x0, 0x1} + bigUtxoKey = keys[0] + bigUtxoAddr = bigUtxoKey.PublicKey().Address() + bigUtxoAmount = 10 * units.MilliAvax + bigUtxo = &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: bigUtxoTxID, + OutputIndex: 0, + }, + Asset: avax.Asset{ID: ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: bigUtxoAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Addrs: []ids.ShortID{bigUtxoAddr}, + Threshold: 1, + }, + }, + } + bigUtxoID = bigUtxo.InputID() + + smallUtxoTxID = ids.ID{0x0, 0x2} + smallUtxoKey = keys[1] + smallUtxoAddr = smallUtxoKey.PublicKey().Address() + smallUtxoAmount = 2 * units.MilliAvax + smallUtxo = &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: smallUtxoTxID, + OutputIndex: 0, + }, + Asset: avax.Asset{ID: ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: smallUtxoAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Addrs: []ids.ShortID{smallUtxoAddr}, + Threshold: 1, + }, + }, + } + smallUtxoID = smallUtxo.InputID() + + lockedUtxoTxID = ids.ID{'c'} + lockedUtxoKey = keys[2] + lockedUtxoAddr = lockedUtxoKey.PublicKey().Address() + lockedUtxoAmount = amountToStake + + lockedUtxo = &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: lockedUtxoTxID, + OutputIndex: 0, + }, + Asset: avax.Asset{ID: ctx.AVAXAssetID}, + Out: &stakeable.LockOut{ + Locktime: uint64(time.Now().Add(time.Hour).Unix()), + TransferableOut: &secp256k1fx.TransferOutput{ + Amt: lockedUtxoAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Addrs: []ids.ShortID{lockedUtxoAddr}, + Threshold: 1, + }, + }, + }, + } + lockedUtxoID = lockedUtxo.InputID() + + bigLockedUtxoTxID = ids.ID{'d'} + bigLockedUtxoKey = keys[2] + bigLockedUtxoAddr = bigLockedUtxoKey.PublicKey().Address() + bigLockedUtxoAmount = amountToStake * 10 + + bigLockedUtxo = &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: bigLockedUtxoTxID, + OutputIndex: 0, + }, + Asset: avax.Asset{ID: ctx.AVAXAssetID}, + Out: &stakeable.LockOut{ + Locktime: uint64(time.Now().Add(time.Hour).Unix()), + TransferableOut: &secp256k1fx.TransferOutput{ + Amt: bigLockedUtxoAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Addrs: []ids.ShortID{bigLockedUtxoAddr}, + Threshold: 1, + }, + }, + }, + } + bigLockedUtxoID = bigLockedUtxo.InputID() + ) + + // this UTXOs ordering ensures that smallUtxo will be picked first, + // even if bigUtxo would be enough finance the whole tx + require.True(t, smallUtxoID.Compare(bigUtxoID) < 0) + + tests := []struct { + description string + utxoReaderF func(ctrl *gomock.Controller) avax.UTXOReader + + // keysF simplifies the utxoReade mock setup. We just specify here + // the only keys referenced by the test scenario + keysF func() []*secp256k1.PrivateKey + amountToStake uint64 + uTxF func(t *testing.T) txs.UnsignedTx + + expectedErr error + checksF func(*testing.T, txs.UnsignedTx, []*avax.TransferableInput, []*avax.TransferableOutput, []*avax.TransferableOutput) + }{ + { + description: "Tx, stake outputs, single locked UTXO and multiple UTXOs", + utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { + s := state.NewMockState(ctrl) + s.EXPECT().UTXOIDs(smallUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{smallUtxoID}, nil).AnyTimes() + s.EXPECT().GetUTXO(smallUtxoID).Return(smallUtxo, nil).AnyTimes() + + s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() + s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() + + s.EXPECT().UTXOIDs(bigLockedUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigLockedUtxoID}, nil).AnyTimes() + s.EXPECT().GetUTXO(bigLockedUtxoID).Return(bigLockedUtxo, nil).AnyTimes() + + return s + }, + keysF: func() []*secp256k1.PrivateKey { + return []*secp256k1.PrivateKey{smallUtxoKey, bigUtxoKey, bigLockedUtxoKey} + }, + + amountToStake: units.MilliAvax, + uTxF: func(t *testing.T) txs.UnsignedTx { + uTx := &txs.AddValidatorTx{ + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: ctx.NetworkID, + BlockchainID: ctx.ChainID, + Ins: make([]*avax.TransferableInput, 0), + Outs: make([]*avax.TransferableOutput, 0), + Memo: []byte{'a', 'b', 'c'}, + }, + }, + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: 0, + End: uint64(time.Now().Unix()), + Wght: amountToStake, + }, + StakeOuts: make([]*avax.TransferableOutput, 0), + RewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + DelegationShares: reward.PercentDenominator, + } + + bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) + require.NoError(t, err) + + uTx.SetBytes(bytes) + return uTx + }, + expectedErr: nil, + checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { + r := require.New(t) + + fm := commonfees.NewManager(testUnitFees) + calc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: fm, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: []verify.Verifiable{}, + } + + expectedFee := 8911 * units.MicroAvax + + // complete uTx with the utxos + addVal, ok := uTx.(*txs.AddValidatorTx) + r.True(ok) + + addVal.Ins = ins + addVal.Outs = outs + addVal.StakeOuts = staked + + r.NoError(uTx.Visit(calc)) + r.Equal(expectedFee, calc.Fee) + + r.Len(ins, 3) + r.Len(staked, 1) + r.Len(outs, 2) + + r.Equal(amountToStake, staked[0].Out.Amount()) + r.Equal(amountToStake, ins[0].In.Amount()-outs[1].Out.Amount()) + r.Equal(expectedFee, ins[1].In.Amount()+ins[2].In.Amount()-outs[0].Out.Amount()) + }, + }, + { + description: "Tx, stake outputs, single locked and unlocked UTXOs", + utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { + s := state.NewMockState(ctrl) + s.EXPECT().UTXOIDs(lockedUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{lockedUtxoID}, nil).AnyTimes() + s.EXPECT().GetUTXO(lockedUtxoID).Return(lockedUtxo, nil).AnyTimes() + s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() + s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() + return s + }, + keysF: func() []*secp256k1.PrivateKey { + return []*secp256k1.PrivateKey{lockedUtxoKey, bigUtxoKey} + }, + + amountToStake: units.MilliAvax, + uTxF: func(t *testing.T) txs.UnsignedTx { + uTx := &txs.AddValidatorTx{ + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: ctx.NetworkID, + BlockchainID: ctx.ChainID, + Ins: make([]*avax.TransferableInput, 0), + Outs: make([]*avax.TransferableOutput, 0), + Memo: []byte{'a', 'b', 'c'}, + }, + }, + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: 0, + End: uint64(time.Now().Unix()), + Wght: amountToStake, + }, + StakeOuts: make([]*avax.TransferableOutput, 0), + RewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + DelegationShares: reward.PercentDenominator, + } + + bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) + require.NoError(t, err) + + uTx.SetBytes(bytes) + return uTx + }, + expectedErr: nil, + checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { + r := require.New(t) + + fm := commonfees.NewManager(testUnitFees) + calc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: fm, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: []verify.Verifiable{}, + } + + expectedFee := 5999 * units.MicroAvax + + // complete uTx with the utxos + addVal, ok := uTx.(*txs.AddValidatorTx) + r.True(ok) + + addVal.Ins = ins + addVal.Outs = outs + addVal.StakeOuts = staked + + r.NoError(uTx.Visit(calc)) + r.Equal(expectedFee, calc.Fee) + + r.Len(ins, 2) + r.Len(staked, 1) + r.Len(outs, 1) + + r.Equal(amountToStake, staked[0].Out.Amount()) + r.Equal(amountToStake, ins[1].In.Amount()) + r.Equal(expectedFee, ins[0].In.Amount()-outs[0].Out.Amount()) + }, + }, + { + description: "Tx, stake outputs, multiple UTXOs", + utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { + s := state.NewMockState(ctrl) + s.EXPECT().UTXOIDs(smallUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{smallUtxoID}, nil).AnyTimes() + s.EXPECT().GetUTXO(smallUtxoID).Return(smallUtxo, nil).AnyTimes() + + s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() + s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() + + return s + }, + keysF: func() []*secp256k1.PrivateKey { + return []*secp256k1.PrivateKey{smallUtxoKey, bigUtxoKey} + }, + + amountToStake: units.MilliAvax, + uTxF: func(t *testing.T) txs.UnsignedTx { + uTx := &txs.AddValidatorTx{ + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: ctx.NetworkID, + BlockchainID: ctx.ChainID, + Ins: make([]*avax.TransferableInput, 0), + Outs: make([]*avax.TransferableOutput, 0), + Memo: []byte{'a', 'b', 'c'}, + }, + }, + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: 0, + End: uint64(time.Now().Unix()), + Wght: amountToStake, + }, + StakeOuts: make([]*avax.TransferableOutput, 0), + RewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + DelegationShares: reward.PercentDenominator, + } + + bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) + require.NoError(t, err) + + uTx.SetBytes(bytes) + return uTx + }, + expectedErr: nil, + checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { + r := require.New(t) + + fm := commonfees.NewManager(testUnitFees) + calc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: fm, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: []verify.Verifiable{}, + } + + expectedFee := 5879 * units.MicroAvax + + // complete uTx with the utxos + addVal, ok := uTx.(*txs.AddValidatorTx) + r.True(ok) + + addVal.Ins = ins + addVal.Outs = outs + addVal.StakeOuts = staked + + r.NoError(uTx.Visit(calc)) + r.Equal(expectedFee, calc.Fee) + + r.Len(ins, 2) + r.Len(staked, 1) + r.Len(outs, 1) + + r.Equal(amountToStake, staked[0].Out.Amount()) + r.Equal(expectedFee, ins[0].In.Amount()+ins[1].In.Amount()-amountToStake-outs[0].Out.Amount()) + }, + }, + { + description: "Tx, stake outputs, single UTXO", + utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { + s := state.NewMockState(ctrl) + s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() + s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() + return s + }, + keysF: func() []*secp256k1.PrivateKey { + return []*secp256k1.PrivateKey{bigUtxoKey} + }, + + amountToStake: units.MilliAvax, + uTxF: func(t *testing.T) txs.UnsignedTx { + uTx := &txs.AddValidatorTx{ + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: ctx.NetworkID, + BlockchainID: ctx.ChainID, + Ins: make([]*avax.TransferableInput, 0), + Outs: make([]*avax.TransferableOutput, 0), + Memo: []byte{'a', 'b', 'c'}, + }, + }, + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: 0, + End: uint64(time.Now().Unix()), + Wght: amountToStake, + }, + StakeOuts: make([]*avax.TransferableOutput, 0), + RewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + DelegationShares: reward.PercentDenominator, + } + + bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) + require.NoError(t, err) + + uTx.SetBytes(bytes) + return uTx + }, + expectedErr: nil, + checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { + r := require.New(t) + + fm := commonfees.NewManager(testUnitFees) + calc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: fm, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: []verify.Verifiable{}, + } + + expectedFee := 3341 * units.MicroAvax + + // complete uTx with the utxos + addVal, ok := uTx.(*txs.AddValidatorTx) + r.True(ok) + + addVal.Ins = ins + addVal.Outs = outs + addVal.StakeOuts = staked + + r.NoError(uTx.Visit(calc)) + r.Equal(expectedFee, calc.Fee) + + r.Len(ins, 1) + r.Len(staked, 1) + r.Len(outs, 1) + + r.Equal(amountToStake, staked[0].Out.Amount()) + r.Equal(expectedFee, ins[0].In.Amount()-amountToStake-outs[0].Out.Amount()) + }, + }, + { + description: "Tx, no stake outputs, single UTXO", + utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { + s := state.NewMockState(ctrl) + s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() + s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() + return s + }, + keysF: func() []*secp256k1.PrivateKey { + return []*secp256k1.PrivateKey{bigUtxoKey} + }, + + amountToStake: 0, + uTxF: func(t *testing.T) txs.UnsignedTx { + uTx := &txs.CreateChainTx{ + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: ctx.NetworkID, + BlockchainID: ctx.ChainID, + Ins: make([]*avax.TransferableInput, 0), + Outs: make([]*avax.TransferableOutput, 0), + Memo: []byte{'a', 'b', 'c'}, + }, + }, + SubnetID: ids.GenerateTestID(), + ChainName: "testChain", + VMID: ids.GenerateTestID(), + SubnetAuth: &secp256k1fx.Input{}, + } + + bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) + require.NoError(t, err) + + uTx.SetBytes(bytes) + return uTx + }, + expectedErr: nil, + checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { + r := require.New(t) + + fm := commonfees.NewManager(testUnitFees) + calc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: fm, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: []verify.Verifiable{}, + } + + expectedFee := 3014 * units.MicroAvax + + // complete uTx with the utxos + addVal, ok := uTx.(*txs.CreateChainTx) + r.True(ok) + + addVal.Ins = ins + addVal.Outs = outs + + r.NoError(uTx.Visit(calc)) + r.Equal(expectedFee, calc.Fee) + + r.Len(ins, 1) + r.Len(outs, 1) + r.Equal(expectedFee, ins[0].In.Amount()-outs[0].Out.Amount()) + r.Empty(staked) + }, + }, + { + description: "Tx, no stake outputs, multiple UTXOs", + utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { + s := state.NewMockState(ctrl) + s.EXPECT().UTXOIDs(smallUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{smallUtxoID}, nil).AnyTimes() + s.EXPECT().GetUTXO(smallUtxoID).Return(smallUtxo, nil).AnyTimes() + + s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() + s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() + + return s + }, + keysF: func() []*secp256k1.PrivateKey { + return []*secp256k1.PrivateKey{smallUtxoKey, bigUtxoKey} + }, + + amountToStake: 0, + uTxF: func(t *testing.T) txs.UnsignedTx { + uTx := &txs.CreateChainTx{ + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: ctx.NetworkID, + BlockchainID: ctx.ChainID, + Ins: make([]*avax.TransferableInput, 0), + Outs: make([]*avax.TransferableOutput, 0), + Memo: []byte{'a', 'b', 'c'}, + }, + }, + SubnetID: ids.GenerateTestID(), + ChainName: "testChain", + VMID: ids.GenerateTestID(), + SubnetAuth: &secp256k1fx.Input{}, + } + + bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) + require.NoError(t, err) + + uTx.SetBytes(bytes) + return uTx + }, + expectedErr: nil, + checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { + r := require.New(t) + + fm := commonfees.NewManager(testUnitFees) + calc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: fm, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: []verify.Verifiable{}, + } + + expectedFee := 5552 * units.MicroAvax + + // complete uTx with the utxos + addVal, ok := uTx.(*txs.CreateChainTx) + r.True(ok) + + addVal.Ins = ins + addVal.Outs = outs + + r.NoError(uTx.Visit(calc)) + r.Equal(expectedFee, calc.Fee) + + r.Len(ins, 2) + r.Len(outs, 1) + r.Equal(expectedFee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + r.Empty(staked) + }, + }, + { + description: "no inputs, no outputs, no fee", + utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { + s := state.NewMockState(ctrl) + s.EXPECT().UTXOIDs(gomock.Any(), gomock.Any(), gomock.Any()).Return([]ids.ID{}, nil).AnyTimes() + return s + }, + keysF: func() []*secp256k1.PrivateKey { + return []*secp256k1.PrivateKey{} + }, + amountToStake: 0, + uTxF: func(t *testing.T) txs.UnsignedTx { + unsignedTx := dummyUnsignedTx{ + BaseTx: txs.BaseTx{}, + } + unsignedTx.SetBytes([]byte{0}) + return &unsignedTx + }, + expectedErr: nil, + checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { + r := require.New(t) + + fm := commonfees.NewManager(testUnitFees) + calc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: fm, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: []verify.Verifiable{}, + } + + r.NoError(uTx.Visit(calc)) + r.Zero(calc.Fee) + + r.Empty(ins) + r.Empty(outs) + r.Empty(staked) + }, + }, + } + + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + r := require.New(t) + ctrl := gomock.NewController(t) + + uTx := test.uTxF(t) + + fm := commonfees.NewManager(testUnitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: fm, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: []verify.Verifiable{}, + } + + // init fee calc with the uTx data + r.NoError(uTx.Visit(feeCalc)) + + ins, outs, staked, _, err := h.FinanceTx( + test.utxoReaderF(ctrl), + test.keysF(), + test.amountToStake, + feeCalc, + ids.GenerateTestShortID(), + ) + r.ErrorIs(err, test.expectedErr) + test.checksF(t, uTx, ins, outs, staked) + }) + } +} + func TestVerifySpendUTXOs(t *testing.T) { fx := &secp256k1fx.Fx{} diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 9a0fd7f88528..1cc68bcc1553 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -625,6 +625,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { ApricotPhase5Time: forkTime, BanffTime: forkTime, CortinaTime: forkTime, + DurangoTime: forkTime, EUpgradeTime: mockable.MaxTime, }} vm.clock.Set(forkTime.Add(time.Second)) diff --git a/wallet/chain/p/builder_dynamic_fees.go b/wallet/chain/p/builder_dynamic_fees.go new file mode 100644 index 000000000000..945bdfa1510d --- /dev/null +++ b/wallet/chain/p/builder_dynamic_fees.go @@ -0,0 +1,1205 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package p + +import ( + "fmt" + "time" + + "golang.org/x/exp/slices" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "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/fees" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" +) + +type DynamicFeesBuilder struct { + addrs set.Set[ids.ShortID] + backend BuilderBackend +} + +func NewDynamicFeesBuilder(addrs set.Set[ids.ShortID], backend BuilderBackend) *DynamicFeesBuilder { + return &DynamicFeesBuilder{ + addrs: addrs, + backend: backend, + } +} + +func (b *DynamicFeesBuilder) NewBaseTx( + outputs []*avax.TransferableOutput, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.BaseTx, error) { + // 1. Build core transaction without utxos + ops := common.NewOptions(options) + + utx := &txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + Outs: outputs, // not sorted yet, we'll sort later on when we have all the outputs + }, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + for _, out := range outputs { + assetID := out.AssetID() + amountToBurn, err := math.Add64(toBurn[assetID], out.Out.Amount()) + if err != nil { + return nil, err + } + toBurn[assetID] = amountToBurn + } + + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.BaseTx(utx); err != nil { + return nil, err + } + + inputs, changeOuts, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + outputs = append(outputs, changeOuts...) + avax.SortTransferableOutputs(outputs, txs.Codec) + utx.Ins = inputs + utx.Outs = outputs + + return utx, b.initCtx(utx) +} + +func (b *DynamicFeesBuilder) NewAddValidatorTx( + vdr *txs.Validator, + rewardsOwner *secp256k1fx.OutputOwners, + shares uint32, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.AddValidatorTx, error) { + ops := common.NewOptions(options) + utils.Sort(rewardsOwner.Addrs) + utx := &txs.AddValidatorTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + Validator: *vdr, + RewardsOwner: rewardsOwner, + DelegationShares: shares, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{ + b.backend.AVAXAssetID(): vdr.Wght, + } + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddValidatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + utx.StakeOuts = stakeOutputs + + return utx, b.initCtx(utx) +} + +func (b *DynamicFeesBuilder) NewAddSubnetValidatorTx( + vdr *txs.SubnetValidator, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.AddSubnetValidatorTx, error) { + ops := common.NewOptions(options) + + subnetAuth, err := b.authorizeSubnet(vdr.Subnet, ops) + if err != nil { + return nil, err + } + + utx := &txs.AddSubnetValidatorTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + SubnetValidator: *vdr, + SubnetAuth: subnetAuth, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // update fees to account for the auth credentials to be added upon tx signing + if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddSubnetValidatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + + return utx, b.initCtx(utx) +} + +func (b *DynamicFeesBuilder) NewRemoveSubnetValidatorTx( + nodeID ids.NodeID, + subnetID ids.ID, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.RemoveSubnetValidatorTx, error) { + ops := common.NewOptions(options) + + subnetAuth, err := b.authorizeSubnet(subnetID, ops) + if err != nil { + return nil, err + } + + utx := &txs.RemoveSubnetValidatorTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + Subnet: subnetID, + NodeID: nodeID, + SubnetAuth: subnetAuth, + } + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // update fees to account for the auth credentials to be added upon tx signing + if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.RemoveSubnetValidatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + + return utx, b.initCtx(utx) +} + +func (b *DynamicFeesBuilder) NewAddDelegatorTx( + vdr *txs.Validator, + rewardsOwner *secp256k1fx.OutputOwners, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.AddDelegatorTx, error) { + ops := common.NewOptions(options) + utils.Sort(rewardsOwner.Addrs) + utx := &txs.AddDelegatorTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + Validator: *vdr, + DelegationRewardsOwner: rewardsOwner, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{ + b.backend.AVAXAssetID(): vdr.Wght, + } + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddDelegatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + utx.StakeOuts = stakeOutputs + + return utx, b.initCtx(utx) +} + +func (b *DynamicFeesBuilder) NewCreateChainTx( + subnetID ids.ID, + genesis []byte, + vmID ids.ID, + fxIDs []ids.ID, + chainName string, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.CreateChainTx, error) { + // 1. Build core transaction without utxos + ops := common.NewOptions(options) + subnetAuth, err := b.authorizeSubnet(subnetID, ops) + if err != nil { + return nil, err + } + + utils.Sort(fxIDs) + + uTx := &txs.CreateChainTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + SubnetID: subnetID, + ChainName: chainName, + VMID: vmID, + FxIDs: fxIDs, + GenesisData: genesis, + SubnetAuth: subnetAuth, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // update fees to account for the auth credentials to be added upon tx signing + if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.CreateChainTx(uTx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + uTx.Ins = inputs + uTx.Outs = outputs + + return uTx, b.initCtx(uTx) +} + +func (b *DynamicFeesBuilder) NewCreateSubnetTx( + owner *secp256k1fx.OutputOwners, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.CreateSubnetTx, error) { + // 1. Build core transaction without utxos + ops := common.NewOptions(options) + + utx := &txs.CreateSubnetTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + Owner: owner, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.CreateSubnetTx(utx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + + return utx, b.initCtx(utx) +} + +func (b *DynamicFeesBuilder) NewImportTx( + sourceChainID ids.ID, + to *secp256k1fx.OutputOwners, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.ImportTx, error) { + ops := common.NewOptions(options) + // 1. Build core transaction + utx := &txs.ImportTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + SourceChain: sourceChainID, + } + + // 2. Add imported inputs first + utxos, err := b.backend.UTXOs(ops.Context(), sourceChainID) + if err != nil { + return nil, err + } + + var ( + addrs = ops.Addresses(b.addrs) + minIssuanceTime = ops.MinIssuanceTime() + avaxAssetID = b.backend.AVAXAssetID() + + importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) + importedSigIndices = make([][]uint32, 0) + importedAmounts = make(map[ids.ID]uint64) + ) + + for _, utxo := range utxos { + out, ok := utxo.Out.(*secp256k1fx.TransferOutput) + if !ok { + continue + } + + inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) + if !ok { + // We couldn't spend this UTXO, so we skip to the next one + continue + } + + importedInputs = append(importedInputs, &avax.TransferableInput{ + UTXOID: utxo.UTXOID, + Asset: utxo.Asset, + In: &secp256k1fx.TransferInput{ + Amt: out.Amt, + Input: secp256k1fx.Input{ + SigIndices: inputSigIndices, + }, + }, + }) + + assetID := utxo.AssetID() + newImportedAmount, err := math.Add64(importedAmounts[assetID], out.Amt) + if err != nil { + return nil, err + } + importedAmounts[assetID] = newImportedAmount + importedSigIndices = append(importedSigIndices, inputSigIndices) + } + if len(importedInputs) == 0 { + return nil, fmt.Errorf( + "%w: no UTXOs available to import", + errInsufficientFunds, + ) + } + + utils.Sort(importedInputs) // sort imported inputs + utx.ImportedInputs = importedInputs + + // 3. Add an output for all non-avax denominated inputs. + for assetID, amount := range importedAmounts { + if assetID == avaxAssetID { + // Avax-denominated inputs may be used to fully or partially pay fees, + // so we'll handle them later on. + continue + } + + utx.Outs = append(utx.Outs, &avax.TransferableOutput{ + Asset: avax.Asset{ID: assetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: amount, + OutputOwners: *to, + }, + }) // we'll sort them later on + } + + // 3. Finance fees as much as possible with imported, Avax-denominated UTXOs + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.ImportTx(utx); err != nil { + return nil, err + } + + for _, sigIndices := range importedSigIndices { + if _, err = financeCredential(feeCalc, sigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + } + + switch importedAVAX := importedAmounts[avaxAssetID]; { + case importedAVAX == feeCalc.Fee: + // imported inputs match exactly the fees to be paid + avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs + return utx, b.initCtx(utx) + + case importedAVAX < feeCalc.Fee: + // imported inputs can partially pay fees + feeCalc.Fee -= importedAmounts[avaxAssetID] + + default: + // imported inputs may be enough to pay taxes by themselves + changeOut := &avax.TransferableOutput{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + OutputOwners: *to, // we set amount after considering own fees + }, + } + + // update fees to target given the extra output added + outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) + if err != nil { + return nil, fmt.Errorf("failed calculating output size: %w", err) + } + if _, err := feeCalc.AddFeesFor(outDimensions); err != nil { + return nil, fmt.Errorf("account for output fees: %w", err) + } + + switch { + case feeCalc.Fee < importedAVAX: + changeOut.Out.(*secp256k1fx.TransferOutput).Amt = importedAVAX - feeCalc.Fee + utx.Outs = append(utx.Outs, changeOut) + avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs + return utx, b.initCtx(utx) + + case feeCalc.Fee == importedAVAX: + // imported fees pays exactly the tx cost. We don't include the outputs + avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs + return utx, b.initCtx(utx) + + default: + // imported avax are not enough to pay fees + // Drop the changeOut and finance the tx + if _, err := feeCalc.RemoveFeesFor(outDimensions); err != nil { + return nil, fmt.Errorf("failed reverting change output: %w", err) + } + feeCalc.Fee -= importedAVAX + } + } + + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} + inputs, changeOuts, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = append(utx.Outs, changeOuts...) + avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs + return utx, b.initCtx(utx) +} + +func (b *DynamicFeesBuilder) NewExportTx( + chainID ids.ID, + outputs []*avax.TransferableOutput, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.ExportTx, error) { + // 1. Build core transaction without utxos + ops := common.NewOptions(options) + avax.SortTransferableOutputs(outputs, txs.Codec) // sort exported outputs + + utx := &txs.ExportTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + DestinationChain: chainID, + ExportedOutputs: outputs, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + for _, out := range outputs { + assetID := out.AssetID() + amountToBurn, err := math.Add64(toBurn[assetID], out.Out.Amount()) + if err != nil { + return nil, err + } + toBurn[assetID] = amountToBurn + } + + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.ExportTx(utx); err != nil { + return nil, err + } + + inputs, changeOuts, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = changeOuts + + return utx, b.initCtx(utx) +} + +func (b *DynamicFeesBuilder) NewTransformSubnetTx( + subnetID ids.ID, + assetID ids.ID, + initialSupply uint64, + maxSupply uint64, + minConsumptionRate uint64, + maxConsumptionRate uint64, + minValidatorStake uint64, + maxValidatorStake uint64, + minStakeDuration time.Duration, + maxStakeDuration time.Duration, + minDelegationFee uint32, + minDelegatorStake uint64, + maxValidatorWeightFactor byte, + uptimeRequirement uint32, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.TransformSubnetTx, error) { + // 1. Build core transaction without utxos + ops := common.NewOptions(options) + + subnetAuth, err := b.authorizeSubnet(subnetID, ops) + if err != nil { + return nil, err + } + + utx := &txs.TransformSubnetTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + Subnet: subnetID, + AssetID: assetID, + InitialSupply: initialSupply, + MaximumSupply: maxSupply, + MinConsumptionRate: minConsumptionRate, + MaxConsumptionRate: maxConsumptionRate, + MinValidatorStake: minValidatorStake, + MaxValidatorStake: maxValidatorStake, + MinStakeDuration: uint32(minStakeDuration / time.Second), + MaxStakeDuration: uint32(maxStakeDuration / time.Second), + MinDelegationFee: minDelegationFee, + MinDelegatorStake: minDelegatorStake, + MaxValidatorWeightFactor: maxValidatorWeightFactor, + UptimeRequirement: uptimeRequirement, + SubnetAuth: subnetAuth, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{ + assetID: maxSupply - initialSupply, + } // fees are calculated in financeTx + + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // update fees to account for the auth credentials to be added upon tx signing + if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.TransformSubnetTx(utx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + + return utx, b.initCtx(utx) +} + +func (b *DynamicFeesBuilder) NewAddPermissionlessValidatorTx( + vdr *txs.SubnetValidator, + signer signer.Signer, + assetID ids.ID, + validationRewardsOwner *secp256k1fx.OutputOwners, + delegationRewardsOwner *secp256k1fx.OutputOwners, + shares uint32, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.AddPermissionlessValidatorTx, error) { + ops := common.NewOptions(options) + utils.Sort(validationRewardsOwner.Addrs) + utils.Sort(delegationRewardsOwner.Addrs) + + utx := &txs.AddPermissionlessValidatorTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + Validator: vdr.Validator, + Subnet: vdr.Subnet, + Signer: signer, + ValidatorRewardsOwner: validationRewardsOwner, + DelegatorRewardsOwner: delegationRewardsOwner, + DelegationShares: shares, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{ + assetID: vdr.Wght, + } + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddPermissionlessValidatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + utx.StakeOuts = stakeOutputs + + return utx, b.initCtx(utx) +} + +func (b *DynamicFeesBuilder) NewAddPermissionlessDelegatorTx( + vdr *txs.SubnetValidator, + assetID ids.ID, + rewardsOwner *secp256k1fx.OutputOwners, + unitFees, unitCaps commonfees.Dimensions, + options ...common.Option, +) (*txs.AddPermissionlessDelegatorTx, error) { + ops := common.NewOptions(options) + utils.Sort(rewardsOwner.Addrs) + + utx := &txs.AddPermissionlessDelegatorTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + Validator: vdr.Validator, + Subnet: vdr.Subnet, + DelegationRewardsOwner: rewardsOwner, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{ + assetID: vdr.Wght, + } + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + feesMan := commonfees.NewManager(unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: unitCaps, + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddPermissionlessDelegatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + utx.StakeOuts = stakeOutputs + + return utx, b.initCtx(utx) +} + +func (b *DynamicFeesBuilder) financeTx( + amountsToBurn map[ids.ID]uint64, + amountsToStake map[ids.ID]uint64, + feeCalc *fees.Calculator, + options *common.Options, +) ( + inputs []*avax.TransferableInput, + changeOutputs []*avax.TransferableOutput, + stakeOutputs []*avax.TransferableOutput, + err error, +) { + avaxAssetID := b.backend.AVAXAssetID() + utxos, err := b.backend.UTXOs(options.Context(), constants.PlatformChainID) + if err != nil { + return nil, nil, nil, err + } + + // we can only pay fees in avax, so we sort avax-denominated UTXOs last + // to maximize probability of being able to pay fees. + slices.SortFunc(utxos, func(lhs, rhs *avax.UTXO) int { + switch { + case lhs.Asset.AssetID() == avaxAssetID && rhs.Asset.AssetID() != avaxAssetID: + return 1 + case lhs.Asset.AssetID() != avaxAssetID && rhs.Asset.AssetID() == avaxAssetID: + return -1 + default: + return 0 + } + }) + + addrs := options.Addresses(b.addrs) + minIssuanceTime := options.MinIssuanceTime() + + addr, ok := addrs.Peek() + if !ok { + return nil, nil, nil, errNoChangeAddress + } + changeOwner := options.ChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }) + + amountsToBurn[avaxAssetID] += feeCalc.Fee + + // Iterate over the locked UTXOs + for _, utxo := range utxos { + assetID := utxo.AssetID() + + // If we have staked enough of the asset, then we have no need burn + // more. + if amountsToStake[assetID] == 0 { + continue + } + + outIntf := utxo.Out + lockedOut, ok := outIntf.(*stakeable.LockOut) + if !ok { + // This output isn't locked, so it will be handled during the next + // iteration of the UTXO set + continue + } + if minIssuanceTime >= lockedOut.Locktime { + // This output isn't locked, so it will be handled during the next + // iteration of the UTXO set + continue + } + + out, ok := lockedOut.TransferableOut.(*secp256k1fx.TransferOutput) + if !ok { + return nil, nil, nil, errUnknownOutputType + } + + inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) + if !ok { + // We couldn't spend this UTXO, so we skip to the next one + continue + } + + input := &avax.TransferableInput{ + UTXOID: utxo.UTXOID, + Asset: utxo.Asset, + In: &stakeable.LockIn{ + Locktime: lockedOut.Locktime, + TransferableIn: &secp256k1fx.TransferInput{ + Amt: out.Amt, + Input: secp256k1fx.Input{ + SigIndices: inputSigIndices, + }, + }, + }, + } + + addedFees, err := financeInput(feeCalc, input) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + addedFees, err = financeCredential(feeCalc, inputSigIndices) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + inputs = append(inputs, input) + + // Stake any value that should be staked + amountToStake := math.Min( + amountsToStake[assetID], // Amount we still need to stake + out.Amt, // Amount available to stake + ) + + // Add the output to the staked outputs + stakeOut := &avax.TransferableOutput{ + Asset: utxo.Asset, + Out: &stakeable.LockOut{ + Locktime: lockedOut.Locktime, + TransferableOut: &secp256k1fx.TransferOutput{ + Amt: amountToStake, + OutputOwners: out.OutputOwners, + }, + }, + } + + addedFees, err = financeOutput(feeCalc, stakeOut) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + stakeOutputs = append(stakeOutputs, stakeOut) + + amountsToStake[assetID] -= amountToStake + if remainingAmount := out.Amt - amountToStake; remainingAmount > 0 { + // This input had extra value, so some of it must be returned + changeOut := &avax.TransferableOutput{ + Asset: utxo.Asset, + Out: &stakeable.LockOut{ + Locktime: lockedOut.Locktime, + TransferableOut: &secp256k1fx.TransferOutput{ + Amt: remainingAmount, + OutputOwners: out.OutputOwners, + }, + }, + } + + // update fees to account for the change output + addedFees, err = financeOutput(feeCalc, changeOut) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + changeOutputs = append(changeOutputs, changeOut) + } + } + + // Iterate over the unlocked UTXOs + for _, utxo := range utxos { + assetID := utxo.AssetID() + + // If we have consumed enough of the asset, then we have no need burn + // more. + if amountsToStake[assetID] == 0 && amountsToBurn[assetID] == 0 { + continue + } + + outIntf := utxo.Out + if lockedOut, ok := outIntf.(*stakeable.LockOut); ok { + if lockedOut.Locktime > minIssuanceTime { + // This output is currently locked, so this output can't be + // burned. + continue + } + outIntf = lockedOut.TransferableOut + } + + out, ok := outIntf.(*secp256k1fx.TransferOutput) + if !ok { + return nil, nil, nil, errUnknownOutputType + } + + inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) + if !ok { + // We couldn't spend this UTXO, so we skip to the next one + continue + } + + input := &avax.TransferableInput{ + UTXOID: utxo.UTXOID, + Asset: utxo.Asset, + In: &secp256k1fx.TransferInput{ + Amt: out.Amt, + Input: secp256k1fx.Input{ + SigIndices: inputSigIndices, + }, + }, + } + + addedFees, err := financeInput(feeCalc, input) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + addedFees, err = financeCredential(feeCalc, inputSigIndices) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for credential fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + inputs = append(inputs, input) + + // Burn any value that should be burned + amountToBurn := math.Min( + amountsToBurn[assetID], // Amount we still need to burn + out.Amt, // Amount available to burn + ) + amountsToBurn[assetID] -= amountToBurn + + amountAvalibleToStake := out.Amt - amountToBurn + // Burn any value that should be burned + amountToStake := math.Min( + amountsToStake[assetID], // Amount we still need to stake + amountAvalibleToStake, // Amount available to stake + ) + amountsToStake[assetID] -= amountToStake + if amountToStake > 0 { + // Some of this input was put for staking + stakeOut := &avax.TransferableOutput{ + Asset: utxo.Asset, + Out: &secp256k1fx.TransferOutput{ + Amt: amountToStake, + OutputOwners: *changeOwner, + }, + } + + stakeOutputs = append(stakeOutputs, stakeOut) + + addedFees, err = financeOutput(feeCalc, stakeOut) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + } + + if remainingAmount := amountAvalibleToStake - amountToStake; remainingAmount > 0 { + // This input had extra value, so some of it must be returned, once fees are removed + changeOut := &avax.TransferableOutput{ + Asset: utxo.Asset, + Out: &secp256k1fx.TransferOutput{ + OutputOwners: *changeOwner, + }, + } + + // update fees to account for the change output + addedFees, err = financeOutput(feeCalc, changeOut) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) + } + + if assetID != avaxAssetID { + changeOut.Out.(*secp256k1fx.TransferOutput).Amt = remainingAmount + amountsToBurn[avaxAssetID] += addedFees + changeOutputs = append(changeOutputs, changeOut) + } else { + // here assetID == b.backend.AVAXAssetID() + switch { + case addedFees < remainingAmount: + changeOut.Out.(*secp256k1fx.TransferOutput).Amt = remainingAmount - addedFees + changeOutputs = append(changeOutputs, changeOut) + case addedFees >= remainingAmount: + amountsToBurn[assetID] += addedFees - remainingAmount + } + } + } + } + + for assetID, amount := range amountsToStake { + if amount != 0 { + return nil, nil, nil, fmt.Errorf( + "%w: provided UTXOs need %d more units of asset %q to stake", + errInsufficientFunds, + amount, + assetID, + ) + } + } + for assetID, amount := range amountsToBurn { + if amount != 0 { + return nil, nil, nil, fmt.Errorf( + "%w: provided UTXOs need %d more units of asset %q", + errInsufficientFunds, + amount, + assetID, + ) + } + } + + utils.Sort(inputs) // sort inputs + avax.SortTransferableOutputs(changeOutputs, txs.Codec) // sort the change outputs + avax.SortTransferableOutputs(stakeOutputs, txs.Codec) // sort stake outputs + return inputs, changeOutputs, stakeOutputs, nil +} + +// TODO ABENEGIA: remove duplication with builder method +func (b *DynamicFeesBuilder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*secp256k1fx.Input, error) { + ownerIntf, err := b.backend.GetSubnetOwner(options.Context(), subnetID) + if err != nil { + return nil, fmt.Errorf( + "failed to fetch subnet owner for %q: %w", + subnetID, + err, + ) + } + owner, ok := ownerIntf.(*secp256k1fx.OutputOwners) + if !ok { + return nil, errUnknownOwnerType + } + + addrs := options.Addresses(b.addrs) + minIssuanceTime := options.MinIssuanceTime() + inputSigIndices, ok := common.MatchOwners(owner, addrs, minIssuanceTime) + if !ok { + // We can't authorize the subnet + return nil, errInsufficientAuthorization + } + return &secp256k1fx.Input{ + SigIndices: inputSigIndices, + }, nil +} + +func (b *DynamicFeesBuilder) initCtx(tx txs.UnsignedTx) error { + ctx, err := newSnowContext(b.backend) + if err != nil { + return err + } + + tx.InitCtx(ctx) + return nil +} + +func financeInput(feeCalc *fees.Calculator, input *avax.TransferableInput) (uint64, error) { + insDimensions, err := commonfees.GetInputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) + if err != nil { + return 0, fmt.Errorf("failed calculating input size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(insDimensions) + if err != nil { + return 0, fmt.Errorf("account for input fees: %w", err) + } + return addedFees, nil +} + +func financeOutput(feeCalc *fees.Calculator, output *avax.TransferableOutput) (uint64, error) { + outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{output}) + if err != nil { + return 0, fmt.Errorf("failed calculating changeOut size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(outDimensions) + if err != nil { + return 0, fmt.Errorf("account for stakedOut fees: %w", err) + } + return addedFees, nil +} + +func financeCredential(feeCalc *fees.Calculator, inputSigIndices []uint32) (uint64, error) { + credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, inputSigIndices) + if err != nil { + return 0, fmt.Errorf("failed calculating input size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(credsDimensions) + if err != nil { + return 0, fmt.Errorf("account for input fees: %w", err) + } + return addedFees, nil +} diff --git a/wallet/chain/p/builder_dynamic_fees_test.go b/wallet/chain/p/builder_dynamic_fees_test.go new file mode 100644 index 000000000000..a1936e603efc --- /dev/null +++ b/wallet/chain/p/builder_dynamic_fees_test.go @@ -0,0 +1,1038 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package p + +import ( + stdcontext "context" + "math" + "testing" + "time" + + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + + "github.com/ava-labs/avalanchego/ids" + "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/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" + "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/txs/fees" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/mocks" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" +) + +var ( + testKeys = secp256k1.TestKeys() + testUnitFees = commonfees.Dimensions{ + 1 * units.MicroAvax, + 2 * units.MicroAvax, + 3 * units.MicroAvax, + 4 * units.MicroAvax, + } + testBlockMaxConsumedUnits = commonfees.Dimensions{ + math.MaxUint64, + math.MaxUint64, + math.MaxUint64, + math.MaxUint64, + } +) + +// These tests create and sign a tx, then verify that utxos included +// in the tx are exactly necessary to pay fees for it + +func TestBaseTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + utxosKey = testKeys[1] + utxoAddr = utxosKey.PublicKey().Address() + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) + + outputsToMove = []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: 7 * units.Avax, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{utxosKey.PublicKey().Address()}, + }, + }, + }} + ) + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr), + backend: be, + } + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + + utx, err := b.NewBaseTx( + outputsToMove, + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5930*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 2) + require.Equal(fc.Fee+outputsToMove[0].Out.Amount(), ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + require.Equal(outputsToMove[0], outs[1]) +} + +func TestAddValidatorTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + rewardKey = testKeys[0] + utxosKey = testKeys[1] + rewardAddr = rewardKey.PublicKey().Address() + utxoAddr = utxosKey.PublicKey().Address() + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) + rewardOwner = &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + rewardKey.Address(), + }, + } + ) + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, rewardAddr), + backend: be, + } + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + + utx, err := b.NewAddValidatorTx( + &txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(time.Now().Add(time.Hour).Unix()), + Wght: 2 * units.Avax, + }, + rewardOwner, + reward.PercentDenominator, + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(12184*units.MicroAvax, fc.Fee) + + ins := utx.Ins + staked := utx.StakeOuts + outs := utx.Outs + require.Len(ins, 4) + require.Len(staked, 2) + require.Len(outs, 2) + require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) + require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) +} + +func TestAddSubnetValidatorTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + subnetAuthKey = testKeys[0] + utxosKey = testKeys[1] + subnetAuthAddr = subnetAuthKey.PublicKey().Address() + utxoAddr = utxosKey.PublicKey().Address() + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) + subnetID = ids.GenerateTestID() + subnetOwner = fx.Owner( + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{subnetAuthKey.PublicKey().Address()}, + }, + ) + ) + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, subnetAuthAddr), + backend: be, + } + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + + utx, err := b.NewAddSubnetValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(time.Now().Add(time.Hour).Unix()), + }, + Subnet: subnetID, + }, + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5765*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) +} + +func TestRemoveSubnetValidatorTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + subnetAuthKey = testKeys[0] + utxosKey = testKeys[1] + subnetAuthAddr = subnetAuthKey.PublicKey().Address() + utxoAddr = utxosKey.PublicKey().Address() + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) + subnetID = ids.GenerateTestID() + + subnetOwner = fx.Owner( + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{subnetAuthKey.PublicKey().Address()}, + }, + ) + ) + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, subnetAuthAddr), + backend: be, + } + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + + utx, err := b.NewRemoveSubnetValidatorTx( + ids.GenerateTestNodeID(), + subnetID, + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5741*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) +} + +func TestAddDelegatorTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + rewardKey = testKeys[0] + utxosKey = testKeys[1] + rewardAddr = rewardKey.PublicKey().Address() + utxoAddr = utxosKey.PublicKey().Address() + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) + rewardOwner = &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + rewardKey.Address(), + }, + } + ) + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, rewardAddr), + backend: be, + } + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + + utx, err := b.NewAddDelegatorTx( + &txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(time.Now().Add(time.Hour).Unix()), + Wght: 2 * units.Avax, + }, + rewardOwner, + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(12180*units.MicroAvax, fc.Fee) + + ins := utx.Ins + staked := utx.StakeOuts + outs := utx.Outs + require.Len(ins, 4) + require.Len(staked, 2) + require.Len(outs, 2) + require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) + require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) +} + +func TestCreateChainTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + subnetAuthKey = testKeys[0] + utxosKey = testKeys[1] + subnetAuthAddr = subnetAuthKey.PublicKey().Address() + utxoAddr = utxosKey.PublicKey().Address() + subnetID = ids.GenerateTestID() + genesisBytes = []byte{'a', 'b', 'c'} + vmID = ids.GenerateTestID() + fxIDs = []ids.ID{ids.GenerateTestID()} + chainName = "dummyChain" + subnetOwner = fx.Owner( + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{subnetAuthKey.PublicKey().Address()}, + }, + ) + ) + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, subnetAuthAddr), + backend: be, + } + + be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + + utxos, avaxAssetID, _ := testUTXOsList(utxosKey) + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + + utx, err := b.NewCreateChainTx( + subnetID, + genesisBytes, + vmID, + fxIDs, + chainName, + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5808*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) +} + +func TestCreateSubnetTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + subnetAuthKey = testKeys[0] + utxosKey = testKeys[1] + utxoAddr = utxosKey.PublicKey().Address() + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) + subnetOwner = &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + subnetAuthKey.Address(), + }, + } + ) + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr), + backend: be, + } + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + + utx, err := b.NewCreateSubnetTx( + subnetOwner, + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5644*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) +} + +func TestImportTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + utxosKey = testKeys[1] + utxoAddr = utxosKey.PublicKey().Address() + sourceChainID = ids.GenerateTestID() + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) + + importKey = testKeys[0] + importTo = &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + importKey.Address(), + }, + } + ) + + importedUtxo := utxos[0] + utxos = utxos[1:] + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr), + backend: be, + } + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), sourceChainID).Return([]*avax.UTXO{importedUtxo}, nil) + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + + utx, err := b.NewImportTx( + sourceChainID, + importTo, + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), importedUtxo.InputID()).Return(importedUtxo, nil).AnyTimes() + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5640*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + importedIns := utx.ImportedInputs + require.Len(ins, 1) + require.Len(importedIns, 1) + require.Len(outs, 1) + require.Equal(fc.Fee, importedIns[0].In.Amount()+ins[0].In.Amount()-outs[0].Out.Amount()) +} + +func TestExportTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + utxosKey = testKeys[1] + utxoAddr = utxosKey.PublicKey().Address() + subnetID = ids.GenerateTestID() + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) + + exportedOutputs = []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: 7 * units.Avax, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{utxosKey.PublicKey().Address()}, + }, + }, + }} + ) + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr), + backend: be, + } + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + + utx, err := b.NewExportTx( + subnetID, + exportedOutputs, + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5966*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee+exportedOutputs[0].Out.Amount(), ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + require.Equal(utx.ExportedOutputs, exportedOutputs) +} + +func TestTransformSubnetTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + subnetAuthKey = testKeys[0] + utxosKey = testKeys[1] + subnetAuthAddr = subnetAuthKey.PublicKey().Address() + utxoAddr = utxosKey.PublicKey().Address() + subnetID = ids.GenerateTestID() + utxos, avaxAssetID, subnetAssetID = testUTXOsList(utxosKey) + subnetOwner = fx.Owner( + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{subnetAuthKey.PublicKey().Address()}, + }, + ) + ) + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, subnetAuthAddr), + backend: be, + } + be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + + var ( + initialSupply = 40 * units.MegaAvax + maxSupply = 100 * units.MegaAvax + ) + + utx, err := b.NewTransformSubnetTx( + subnetID, + subnetAssetID, + initialSupply, // initial supply + maxSupply, // max supply + reward.PercentDenominator, // min consumption rate + reward.PercentDenominator, // max consumption rate + 1, // min validator stake + 100*units.MegaAvax, // max validator stake + time.Second, // min stake duration + 365*24*time.Hour, // max stake duration + 0, // min delegation fee + 1, // min delegator stake + 5, // max validator weight factor + .80*reward.PercentDenominator, // uptime requirement + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(8763*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 3) + require.Len(outs, 2) + require.Equal(maxSupply-initialSupply, ins[0].In.Amount()-outs[0].Out.Amount()) + require.Equal(fc.Fee, ins[1].In.Amount()+ins[2].In.Amount()-outs[1].Out.Amount()) +} + +func TestAddPermissionlessValidatorTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + rewardKey = testKeys[0] + utxosKey = testKeys[1] + rewardAddr = rewardKey.PublicKey().Address() + utxoAddr = utxosKey.PublicKey().Address() + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) + validationRewardsOwner = &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + rewardKey.Address(), + }, + } + delegationRewardsOwner = &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + rewardKey.Address(), + }, + } + ) + + sk, err := bls.NewSecretKey() + require.NoError(err) + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, rewardAddr), + backend: be, + } + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + + utx, err := b.NewAddPermissionlessValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(time.Now().Add(time.Hour).Unix()), + Wght: 2 * units.Avax, + }, + Subnet: constants.PrimaryNetworkID, + }, + signer.NewProofOfPossession(sk), + avaxAssetID, + validationRewardsOwner, + delegationRewardsOwner, + reward.PercentDenominator, + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(12404*units.MicroAvax, fc.Fee) + + ins := utx.Ins + staked := utx.StakeOuts + outs := utx.Outs + require.Len(ins, 4) + require.Len(staked, 2) + require.Len(outs, 2) + require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) + require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) +} + +func TestAddPermissionlessDelegatorTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) + + var ( + rewardKey = testKeys[0] + utxosKey = testKeys[1] + rewardAddr = rewardKey.PublicKey().Address() + utxoAddr = utxosKey.PublicKey().Address() + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) + rewardsOwner = &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + rewardKey.Address(), + }, + } + ) + + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, rewardAddr), + backend: be, + } + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + + utx, err := b.NewAddPermissionlessDelegatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(time.Now().Add(time.Hour).Unix()), + Wght: 2 * units.Avax, + }, + Subnet: constants.PrimaryNetworkID, + }, + avaxAssetID, + rewardsOwner, + testUnitFees, + testBlockMaxConsumedUnits, + ) + require.NoError(err) + + var ( + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + ) + + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(12212*units.MicroAvax, fc.Fee) + + ins := utx.Ins + staked := utx.StakeOuts + outs := utx.Outs + require.Len(ins, 4) + require.Len(staked, 2) + require.Len(outs, 2) + require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) + require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) +} + +func testUTXOsList(utxosKey *secp256k1.PrivateKey) ( + []*avax.UTXO, + ids.ID, // avaxAssetID, + ids.ID, // subnetAssetID +) { + // Note: we avoid ids.GenerateTestNodeID here to make sure that UTXO IDs won't change + // run by run. This simplifies checking what utxos are included in the built txs. + utxosOffset := uint64(2024) + + var ( + avaxAssetID = ids.Empty.Prefix(utxosOffset) + subnetAssetID = ids.Empty.Prefix(utxosOffset + 1) + ) + + return []*avax.UTXO{ // currently, the wallet scans UTXOs in the order provided here + { // a small UTXO first, which should not be enough to pay fees + UTXOID: avax.UTXOID{ + TxID: ids.Empty.Prefix(utxosOffset), + OutputIndex: uint32(utxosOffset), + }, + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: 2 * units.MilliAvax, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Addrs: []ids.ShortID{utxosKey.PublicKey().Address()}, + Threshold: 1, + }, + }, + }, + { // a locked, small UTXO + UTXOID: avax.UTXOID{ + TxID: ids.Empty.Prefix(utxosOffset + 1), + OutputIndex: uint32(utxosOffset + 1), + }, + Asset: avax.Asset{ID: avaxAssetID}, + Out: &stakeable.LockOut{ + Locktime: uint64(time.Now().Add(time.Hour).Unix()), + TransferableOut: &secp256k1fx.TransferOutput{ + Amt: 3 * units.MilliAvax, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{utxosKey.PublicKey().Address()}, + }, + }, + }, + }, + { // a subnetAssetID denominated UTXO + UTXOID: avax.UTXOID{ + TxID: ids.Empty.Prefix(utxosOffset + 2), + OutputIndex: uint32(utxosOffset + 2), + }, + Asset: avax.Asset{ID: subnetAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: 99 * units.MegaAvax, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Addrs: []ids.ShortID{utxosKey.PublicKey().Address()}, + Threshold: 1, + }, + }, + }, + { // a locked, large UTXO + UTXOID: avax.UTXOID{ + TxID: ids.Empty.Prefix(utxosOffset + 3), + OutputIndex: uint32(utxosOffset + 3), + }, + Asset: avax.Asset{ID: avaxAssetID}, + Out: &stakeable.LockOut{ + Locktime: uint64(time.Now().Add(time.Hour).Unix()), + TransferableOut: &secp256k1fx.TransferOutput{ + Amt: 88 * units.Avax, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{utxosKey.PublicKey().Address()}, + }, + }, + }, + }, + { // a large UTXO last, which should be enough to pay any fee by itself + UTXOID: avax.UTXOID{ + TxID: ids.Empty.Prefix(utxosOffset + 4), + OutputIndex: uint32(utxosOffset + 4), + }, + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: 9 * units.Avax, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Addrs: []ids.ShortID{utxosKey.PublicKey().Address()}, + Threshold: 1, + }, + }, + }, + }, + avaxAssetID, + subnetAssetID +} diff --git a/wallet/chain/p/mocks/mock_builder_backend.go b/wallet/chain/p/mocks/mock_builder_backend.go new file mode 100644 index 000000000000..e3f8cdeb5523 --- /dev/null +++ b/wallet/chain/p/mocks/mock_builder_backend.go @@ -0,0 +1,213 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ava-labs/avalanchego/wallet/chain/p (interfaces: BuilderBackend) +// +// Generated by this command: +// +// mockgen -package=mocks -destination=wallet/chain/p/mocks/mock_builder_backend.go github.com/ava-labs/avalanchego/wallet/chain/p BuilderBackend +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + ids "github.com/ava-labs/avalanchego/ids" + avax "github.com/ava-labs/avalanchego/vms/components/avax" + fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" + gomock "go.uber.org/mock/gomock" +) + +// MockBuilderBackend is a mock of BuilderBackend interface. +type MockBuilderBackend struct { + ctrl *gomock.Controller + recorder *MockBuilderBackendMockRecorder +} + +// MockBuilderBackendMockRecorder is the mock recorder for MockBuilderBackend. +type MockBuilderBackendMockRecorder struct { + mock *MockBuilderBackend +} + +// NewMockBuilderBackend creates a new mock instance. +func NewMockBuilderBackend(ctrl *gomock.Controller) *MockBuilderBackend { + mock := &MockBuilderBackend{ctrl: ctrl} + mock.recorder = &MockBuilderBackendMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBuilderBackend) EXPECT() *MockBuilderBackendMockRecorder { + return m.recorder +} + +// AVAXAssetID mocks base method. +func (m *MockBuilderBackend) AVAXAssetID() ids.ID { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AVAXAssetID") + ret0, _ := ret[0].(ids.ID) + return ret0 +} + +// AVAXAssetID indicates an expected call of AVAXAssetID. +func (mr *MockBuilderBackendMockRecorder) AVAXAssetID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AVAXAssetID", reflect.TypeOf((*MockBuilderBackend)(nil).AVAXAssetID)) +} + +// AddPrimaryNetworkDelegatorFee mocks base method. +func (m *MockBuilderBackend) AddPrimaryNetworkDelegatorFee() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddPrimaryNetworkDelegatorFee") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// AddPrimaryNetworkDelegatorFee indicates an expected call of AddPrimaryNetworkDelegatorFee. +func (mr *MockBuilderBackendMockRecorder) AddPrimaryNetworkDelegatorFee() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPrimaryNetworkDelegatorFee", reflect.TypeOf((*MockBuilderBackend)(nil).AddPrimaryNetworkDelegatorFee)) +} + +// AddPrimaryNetworkValidatorFee mocks base method. +func (m *MockBuilderBackend) AddPrimaryNetworkValidatorFee() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddPrimaryNetworkValidatorFee") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// AddPrimaryNetworkValidatorFee indicates an expected call of AddPrimaryNetworkValidatorFee. +func (mr *MockBuilderBackendMockRecorder) AddPrimaryNetworkValidatorFee() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPrimaryNetworkValidatorFee", reflect.TypeOf((*MockBuilderBackend)(nil).AddPrimaryNetworkValidatorFee)) +} + +// AddSubnetDelegatorFee mocks base method. +func (m *MockBuilderBackend) AddSubnetDelegatorFee() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddSubnetDelegatorFee") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// AddSubnetDelegatorFee indicates an expected call of AddSubnetDelegatorFee. +func (mr *MockBuilderBackendMockRecorder) AddSubnetDelegatorFee() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetDelegatorFee", reflect.TypeOf((*MockBuilderBackend)(nil).AddSubnetDelegatorFee)) +} + +// AddSubnetValidatorFee mocks base method. +func (m *MockBuilderBackend) AddSubnetValidatorFee() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddSubnetValidatorFee") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// AddSubnetValidatorFee indicates an expected call of AddSubnetValidatorFee. +func (mr *MockBuilderBackendMockRecorder) AddSubnetValidatorFee() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetValidatorFee", reflect.TypeOf((*MockBuilderBackend)(nil).AddSubnetValidatorFee)) +} + +// BaseTxFee mocks base method. +func (m *MockBuilderBackend) BaseTxFee() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BaseTxFee") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// BaseTxFee indicates an expected call of BaseTxFee. +func (mr *MockBuilderBackendMockRecorder) BaseTxFee() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BaseTxFee", reflect.TypeOf((*MockBuilderBackend)(nil).BaseTxFee)) +} + +// CreateBlockchainTxFee mocks base method. +func (m *MockBuilderBackend) CreateBlockchainTxFee() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateBlockchainTxFee") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// CreateBlockchainTxFee indicates an expected call of CreateBlockchainTxFee. +func (mr *MockBuilderBackendMockRecorder) CreateBlockchainTxFee() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateBlockchainTxFee", reflect.TypeOf((*MockBuilderBackend)(nil).CreateBlockchainTxFee)) +} + +// CreateSubnetTxFee mocks base method. +func (m *MockBuilderBackend) CreateSubnetTxFee() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateSubnetTxFee") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// CreateSubnetTxFee indicates an expected call of CreateSubnetTxFee. +func (mr *MockBuilderBackendMockRecorder) CreateSubnetTxFee() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSubnetTxFee", reflect.TypeOf((*MockBuilderBackend)(nil).CreateSubnetTxFee)) +} + +// GetSubnetOwner mocks base method. +func (m *MockBuilderBackend) GetSubnetOwner(arg0 context.Context, arg1 ids.ID) (fx.Owner, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSubnetOwner", arg0, arg1) + ret0, _ := ret[0].(fx.Owner) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSubnetOwner indicates an expected call of GetSubnetOwner. +func (mr *MockBuilderBackendMockRecorder) GetSubnetOwner(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockBuilderBackend)(nil).GetSubnetOwner), arg0, arg1) +} + +// NetworkID mocks base method. +func (m *MockBuilderBackend) NetworkID() uint32 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkID") + ret0, _ := ret[0].(uint32) + return ret0 +} + +// NetworkID indicates an expected call of NetworkID. +func (mr *MockBuilderBackendMockRecorder) NetworkID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkID", reflect.TypeOf((*MockBuilderBackend)(nil).NetworkID)) +} + +// TransformSubnetTxFee mocks base method. +func (m *MockBuilderBackend) TransformSubnetTxFee() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TransformSubnetTxFee") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// TransformSubnetTxFee indicates an expected call of TransformSubnetTxFee. +func (mr *MockBuilderBackendMockRecorder) TransformSubnetTxFee() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransformSubnetTxFee", reflect.TypeOf((*MockBuilderBackend)(nil).TransformSubnetTxFee)) +} + +// UTXOs mocks base method. +func (m *MockBuilderBackend) UTXOs(arg0 context.Context, arg1 ids.ID) ([]*avax.UTXO, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UTXOs", arg0, arg1) + ret0, _ := ret[0].([]*avax.UTXO) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UTXOs indicates an expected call of UTXOs. +func (mr *MockBuilderBackendMockRecorder) UTXOs(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UTXOs", reflect.TypeOf((*MockBuilderBackend)(nil).UTXOs), arg0, arg1) +} diff --git a/wallet/chain/p/mocks/mock_signer_backend.go b/wallet/chain/p/mocks/mock_signer_backend.go new file mode 100644 index 000000000000..9ad6db9e76dd --- /dev/null +++ b/wallet/chain/p/mocks/mock_signer_backend.go @@ -0,0 +1,73 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ava-labs/avalanchego/wallet/chain/p (interfaces: SignerBackend) +// +// Generated by this command: +// +// mockgen -package=mocks -destination=wallet/chain/p/mocks/mock_signer_backend.go github.com/ava-labs/avalanchego/wallet/chain/p SignerBackend +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + ids "github.com/ava-labs/avalanchego/ids" + avax "github.com/ava-labs/avalanchego/vms/components/avax" + fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" + gomock "go.uber.org/mock/gomock" +) + +// MockSignerBackend is a mock of SignerBackend interface. +type MockSignerBackend struct { + ctrl *gomock.Controller + recorder *MockSignerBackendMockRecorder +} + +// MockSignerBackendMockRecorder is the mock recorder for MockSignerBackend. +type MockSignerBackendMockRecorder struct { + mock *MockSignerBackend +} + +// NewMockSignerBackend creates a new mock instance. +func NewMockSignerBackend(ctrl *gomock.Controller) *MockSignerBackend { + mock := &MockSignerBackend{ctrl: ctrl} + mock.recorder = &MockSignerBackendMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSignerBackend) EXPECT() *MockSignerBackendMockRecorder { + return m.recorder +} + +// GetSubnetOwner mocks base method. +func (m *MockSignerBackend) GetSubnetOwner(arg0 context.Context, arg1 ids.ID) (fx.Owner, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSubnetOwner", arg0, arg1) + ret0, _ := ret[0].(fx.Owner) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSubnetOwner indicates an expected call of GetSubnetOwner. +func (mr *MockSignerBackendMockRecorder) GetSubnetOwner(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockSignerBackend)(nil).GetSubnetOwner), arg0, arg1) +} + +// GetUTXO mocks base method. +func (m *MockSignerBackend) GetUTXO(arg0 context.Context, arg1, arg2 ids.ID) (*avax.UTXO, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUTXO", arg0, arg1, arg2) + ret0, _ := ret[0].(*avax.UTXO) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUTXO indicates an expected call of GetUTXO. +func (mr *MockSignerBackendMockRecorder) GetUTXO(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockSignerBackend)(nil).GetUTXO), arg0, arg1, arg2) +} diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index c5b9ecb0604b..7edacbf24792 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -9,8 +9,11 @@ import ( "time" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -259,23 +262,31 @@ type Wallet interface { func NewWallet( builder Builder, + dynFeesBuilder *DynamicFeesBuilder, signer Signer, client platformvm.Client, backend Backend, ) Wallet { return &wallet{ - Backend: backend, - builder: builder, - signer: signer, - client: client, + Backend: backend, + builder: builder, + dynamicBuilder: dynFeesBuilder, + unitFees: config.EUpgradeDynamicFeesConfig.UnitFees, + unitCaps: config.EUpgradeDynamicFeesConfig.BlockUnitsCap, + signer: signer, + client: client, } } type wallet struct { Backend - builder Builder - signer Signer - client platformvm.Client + signer Signer + client platformvm.Client + + isEForkActive bool + builder Builder + dynamicBuilder *DynamicFeesBuilder + unitFees, unitCaps fees.Dimensions } func (w *wallet) Builder() Builder { @@ -290,7 +301,19 @@ func (w *wallet) IssueBaseTx( outputs []*avax.TransferableOutput, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewBaseTx(outputs, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error + ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewBaseTx(outputs, w.unitFees, w.unitCaps, options...) + } else { + utx, err = w.builder.NewBaseTx(outputs, options...) + } if err != nil { return nil, err } @@ -303,7 +326,19 @@ func (w *wallet) IssueAddValidatorTx( shares uint32, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewAddValidatorTx(vdr, rewardsOwner, shares, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error + ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewAddValidatorTx(vdr, rewardsOwner, shares, w.unitFees, w.unitCaps, options...) + } else { + utx, err = w.builder.NewAddValidatorTx(vdr, rewardsOwner, shares, options...) + } if err != nil { return nil, err } @@ -314,7 +349,19 @@ func (w *wallet) IssueAddSubnetValidatorTx( vdr *txs.SubnetValidator, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewAddSubnetValidatorTx(vdr, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error + ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewAddSubnetValidatorTx(vdr, w.unitFees, w.unitCaps, options...) + } else { + utx, err = w.builder.NewAddSubnetValidatorTx(vdr, options...) + } if err != nil { return nil, err } @@ -326,7 +373,19 @@ func (w *wallet) IssueRemoveSubnetValidatorTx( subnetID ids.ID, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewRemoveSubnetValidatorTx(nodeID, subnetID, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error + ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewRemoveSubnetValidatorTx(nodeID, subnetID, w.unitFees, w.unitCaps, options...) + } else { + utx, err = w.builder.NewRemoveSubnetValidatorTx(nodeID, subnetID, options...) + } if err != nil { return nil, err } @@ -338,7 +397,19 @@ func (w *wallet) IssueAddDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewAddDelegatorTx(vdr, rewardsOwner, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error + ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewAddDelegatorTx(vdr, rewardsOwner, w.unitFees, w.unitCaps, options...) + } else { + utx, err = w.builder.NewAddDelegatorTx(vdr, rewardsOwner, options...) + } if err != nil { return nil, err } @@ -353,7 +424,19 @@ func (w *wallet) IssueCreateChainTx( chainName string, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error + ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, w.unitFees, w.unitCaps, options...) + } else { + utx, err = w.builder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, options...) + } if err != nil { return nil, err } @@ -364,10 +447,23 @@ func (w *wallet) IssueCreateSubnetTx( owner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewCreateSubnetTx(owner, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error + ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewCreateSubnetTx(owner, w.unitFees, w.unitCaps, options...) + } else { + utx, err = w.builder.NewCreateSubnetTx(owner, options...) + } if err != nil { return nil, err } + return w.IssueUnsignedTx(utx, options...) } @@ -388,7 +484,19 @@ func (w *wallet) IssueImportTx( to *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewImportTx(sourceChainID, to, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error + ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewImportTx(sourceChainID, to, w.unitFees, w.unitCaps, options...) + } else { + utx, err = w.builder.NewImportTx(sourceChainID, to, options...) + } if err != nil { return nil, err } @@ -400,7 +508,19 @@ func (w *wallet) IssueExportTx( outputs []*avax.TransferableOutput, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewExportTx(chainID, outputs, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error + ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewExportTx(chainID, outputs, w.unitFees, w.unitCaps, options...) + } else { + utx, err = w.builder.NewExportTx(chainID, outputs, options...) + } if err != nil { return nil, err } @@ -424,23 +544,53 @@ func (w *wallet) IssueTransformSubnetTx( uptimeRequirement uint32, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewTransformSubnetTx( - subnetID, - assetID, - initialSupply, - maxSupply, - minConsumptionRate, - maxConsumptionRate, - minValidatorStake, - maxValidatorStake, - minStakeDuration, - maxStakeDuration, - minDelegationFee, - minDelegatorStake, - maxValidatorWeightFactor, - uptimeRequirement, - options..., + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewTransformSubnetTx( + subnetID, + assetID, + initialSupply, + maxSupply, + minConsumptionRate, + maxConsumptionRate, + minValidatorStake, + maxValidatorStake, + minStakeDuration, + maxStakeDuration, + minDelegationFee, + minDelegatorStake, + maxValidatorWeightFactor, + uptimeRequirement, + w.unitFees, + w.unitCaps, + options..., + ) + } else { + utx, err = w.builder.NewTransformSubnetTx( + subnetID, + assetID, + initialSupply, + maxSupply, + minConsumptionRate, + maxConsumptionRate, + minValidatorStake, + maxValidatorStake, + minStakeDuration, + maxStakeDuration, + minDelegationFee, + minDelegatorStake, + maxValidatorWeightFactor, + uptimeRequirement, + options..., + ) + } if err != nil { return nil, err } @@ -456,15 +606,37 @@ func (w *wallet) IssueAddPermissionlessValidatorTx( shares uint32, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewAddPermissionlessValidatorTx( - vdr, - signer, - assetID, - validationRewardsOwner, - delegationRewardsOwner, - shares, - options..., + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewAddPermissionlessValidatorTx( + vdr, + signer, + assetID, + validationRewardsOwner, + delegationRewardsOwner, + shares, + w.unitFees, + w.unitCaps, + options..., + ) + } else { + utx, err = w.builder.NewAddPermissionlessValidatorTx( + vdr, + signer, + assetID, + validationRewardsOwner, + delegationRewardsOwner, + shares, + options..., + ) + } if err != nil { return nil, err } @@ -477,12 +649,31 @@ func (w *wallet) IssueAddPermissionlessDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewAddPermissionlessDelegatorTx( - vdr, - assetID, - rewardsOwner, - options..., + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + var ( + utx txs.UnsignedTx + err error ) + if w.isEForkActive { + utx, err = w.dynamicBuilder.NewAddPermissionlessDelegatorTx( + vdr, + assetID, + rewardsOwner, + w.unitFees, + w.unitCaps, + options..., + ) + } else { + utx, err = w.builder.NewAddPermissionlessDelegatorTx( + vdr, + assetID, + rewardsOwner, + options..., + ) + } if err != nil { return nil, err } @@ -536,3 +727,25 @@ func (w *wallet) IssueTx( } return nil } + +func (w *wallet) refreshFork(options ...common.Option) error { + if w.isEForkActive { + // E fork enables dinamic fees and it is active + // not need to recheck + return nil + } + + var ( + ops = common.NewOptions(options) + ctx = ops.Context() + eForkTime = version.GetEUpgradeTime(w.NetworkID()) + ) + + chainTime, err := w.client.GetTimestamp(ctx) + if err != nil { + return err + } + + w.isEForkActive = !chainTime.Before(eForkTime) + return nil +} diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 3bb3e9965684..0825ab1b370f 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -119,6 +119,7 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { pUTXOs := NewChainUTXOs(constants.PlatformChainID, avaxState.UTXOs) pBackend := p.NewBackend(avaxState.PCTX, pUTXOs, pChainTxs) pBuilder := p.NewBuilder(avaxAddrs, pBackend) + pDynamicFeesBuilder := p.NewDynamicFeesBuilder(avaxAddrs, pBackend) pSigner := p.NewSigner(config.AVAXKeychain, pBackend) xChainID := avaxState.XCTX.BlockchainID() @@ -134,7 +135,7 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( - p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), + p.NewWallet(pBuilder, pDynamicFeesBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil From 74f0c1872d5225e4cfaf9b595e152878bbaddd0d Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 5 Feb 2024 08:58:26 +0100 Subject: [PATCH 002/120] appease linter --- vms/components/fees/dimensions.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/vms/components/fees/dimensions.go b/vms/components/fees/dimensions.go index 6f6b68128ef7..e37dd451d69b 100644 --- a/vms/components/fees/dimensions.go +++ b/vms/components/fees/dimensions.go @@ -3,9 +3,7 @@ package fees -import ( - "github.com/ava-labs/avalanchego/utils/math" -) +import "github.com/ava-labs/avalanchego/utils/math" const ( Bandwidth Dimension = 0 @@ -14,8 +12,6 @@ const ( Compute Dimension = 3 // signatures checks, tx-specific FeeDimensions = 4 - - uint64Len = 8 ) var Empty = Dimensions{} // helps avoiding reading unit fees from db for some pre E fork processing From 9eda7f3ed5eeb68d41a17ce45ada64ed56b61afb Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 5 Feb 2024 09:15:55 +0100 Subject: [PATCH 003/120] nits --- vms/components/fees/dimensions.go | 2 +- vms/components/fees/manager.go | 8 ++++---- .../txs/executor/staker_tx_verification.go | 6 +++--- vms/platformvm/txs/executor/standard_tx_executor.go | 13 ++++++------- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/vms/components/fees/dimensions.go b/vms/components/fees/dimensions.go index e37dd451d69b..332f11b750f8 100644 --- a/vms/components/fees/dimensions.go +++ b/vms/components/fees/dimensions.go @@ -14,7 +14,7 @@ const ( FeeDimensions = 4 ) -var Empty = Dimensions{} // helps avoiding reading unit fees from db for some pre E fork processing +var Empty = Dimensions{} type ( Dimension int diff --git a/vms/components/fees/manager.go b/vms/components/fees/manager.go index 644cf37fa9b1..325c0a73f994 100644 --- a/vms/components/fees/manager.go +++ b/vms/components/fees/manager.go @@ -28,6 +28,10 @@ func (m *Manager) GetUnitFees() Dimensions { return m.unitFees } +func (m *Manager) GetCumulatedUnits() Dimensions { + return m.cumulatedUnits +} + // CalculateFee must be a stateless method func (m *Manager) CalculateFee(units Dimensions) (uint64, error) { fee := uint64(0) @@ -86,7 +90,3 @@ func (m *Manager) RemoveUnits(unitsToRm Dimensions) error { m.cumulatedUnits = revertedUnits return nil } - -func (m *Manager) GetCumulatedUnits() Dimensions { - return m.cumulatedUnits -} diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 2fd34ea1a28f..868bdb2231a6 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -114,7 +114,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 } @@ -198,7 +198,7 @@ func verifyAddValidatorTx( // verifyStakerStartsSoon is checked last to allow // the verifier visitor to explicitly check for this error. - return outs, verifyStakerStartsSoon(false /*=isDurangoActive*/, currentTimestamp, startTime) + return outs, verifyStakerStartsSoon(isDurangoActive, currentTimestamp, startTime) } // verifyAddSubnetValidatorTx carries out the validation for an @@ -525,7 +525,7 @@ func verifyAddDelegatorTx( // verifyStakerStartsSoon is checked last to allow // the verifier visitor to explicitly check for this error. - return outs, verifyStakerStartsSoon(false /*=isDurangoActive*/, currentTimestamp, startTime) + return outs, verifyStakerStartsSoon(isDurangoActive, currentTimestamp, startTime) } // verifyAddPermissionlessValidatorTx carries out the validation for an diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index d18930a39a72..de301c94e513 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -283,10 +283,6 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { 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 @@ -306,6 +302,9 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { 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, @@ -460,14 +459,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) @@ -499,7 +497,6 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error return err } - totalRewardAmount := tx.MaximumSupply - tx.InitialSupply feeCalculator := fees.Calculator{ IsEUpgradeActive: e.Backend.Config.IsEUpgradeActivated(currentTimestamp), Config: e.Backend.Config, @@ -511,6 +508,8 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error if err := tx.Visit(&feeCalculator); err != nil { return err } + + totalRewardAmount := tx.MaximumSupply - tx.InitialSupply if err := e.Backend.FlowChecker.VerifySpend( tx, e.State, From 71b5930334f8f32355a9851cb0f3121c5a97ac81 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 5 Feb 2024 09:49:04 +0100 Subject: [PATCH 004/120] fixed AddValidatorTx AddDelegatorTx fees post EUpgrade --- vms/platformvm/txs/builder/builder.go | 106 ++----------- .../txs/executor/proposal_tx_executor.go | 4 - .../txs/executor/staker_tx_verification.go | 8 - .../txs/executor/standard_tx_executor.go | 4 - vms/platformvm/txs/fees/calculator.go | 58 ++----- vms/platformvm/txs/fees/calculator_test.go | 62 +------- vms/platformvm/utxo/handler_test.go | 66 ++++++-- wallet/chain/p/builder_dynamic_fees.go | 98 ------------ wallet/chain/p/builder_dynamic_fees_test.go | 145 ------------------ wallet/chain/p/wallet.go | 28 +--- 10 files changed, 87 insertions(+), 492 deletions(-) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 1d7770764bef..42333adfec20 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -703,11 +703,17 @@ func (b *builder) NewAddValidatorTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - // 1. Build core transaction without utxos + ins, unstakedOuts, stakedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkValidatorFee, changeAddr) + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + // Create the tx utx := &txs.AddValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, + Ins: ins, + Outs: unstakedOuts, }}, Validator: txs.Validator{ NodeID: nodeID, @@ -715,6 +721,7 @@ func (b *builder) NewAddValidatorTx( End: endTime, Wght: stakeAmount, }, + StakeOuts: stakedOuts, RewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, @@ -722,50 +729,6 @@ func (b *builder) NewAddValidatorTx( }, DelegationShares: shares, } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - var ( - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) - ins []*avax.TransferableInput - outs []*avax.TransferableOutput - stakedOuts []*avax.TransferableOutput - signers [][]*secp256k1.PrivateKey - err error - ) - if isEForkActive { - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.AddValidatorTx(utx); err != nil { - return nil, err - } - - ins, outs, _, signers, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - } else { - ins, outs, stakedOuts, signers, err = b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkValidatorFee, changeAddr) - } - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - - utx.BaseTx.Ins = ins - utx.BaseTx.Outs = outs - utx.StakeOuts = stakedOuts - - // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -833,11 +796,17 @@ func (b *builder) NewAddDelegatorTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - // 1. Build core transaction without utxos + ins, unlockedOuts, lockedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkDelegatorFee, changeAddr) + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + // Create the tx utx := &txs.AddDelegatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, + Ins: ins, + Outs: unlockedOuts, }}, Validator: txs.Validator{ NodeID: nodeID, @@ -845,56 +814,13 @@ func (b *builder) NewAddDelegatorTx( End: endTime, Wght: stakeAmount, }, + StakeOuts: lockedOuts, DelegationRewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{rewardAddress}, }, } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - var ( - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) - ins []*avax.TransferableInput - outs []*avax.TransferableOutput - stakedOuts []*avax.TransferableOutput - signers [][]*secp256k1.PrivateKey - err error - ) - if isEForkActive { - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.AddDelegatorTx(utx); err != nil { - return nil, err - } - - ins, outs, _, signers, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - } else { - ins, outs, stakedOuts, signers, err = b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkDelegatorFee, changeAddr) - } - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - - utx.BaseTx.Ins = ins - utx.BaseTx.Outs = outs - utx.StakeOuts = stakedOuts - - // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err diff --git a/vms/platformvm/txs/executor/proposal_tx_executor.go b/vms/platformvm/txs/executor/proposal_tx_executor.go index 0aaab27c5b4b..0e3faf539013 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor.go @@ -117,8 +117,6 @@ func (e *ProposalTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error { onAbortOuts, err := verifyAddValidatorTx( e.Backend, - e.BlkFeeManager, - commonfees.Empty, e.OnCommitState, e.Tx, tx, @@ -214,8 +212,6 @@ func (e *ProposalTxExecutor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { onAbortOuts, err := verifyAddDelegatorTx( e.Backend, - e.BlkFeeManager, - commonfees.Empty, e.OnCommitState, e.Tx, tx, diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 868bdb2231a6..43f381772e26 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -92,8 +92,6 @@ func verifySubnetValidatorPrimaryNetworkRequirements( // added to the staking set. func verifyAddValidatorTx( backend *Backend, - feeManager *commonFees.Manager, - unitCaps commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddValidatorTx, @@ -175,8 +173,6 @@ func verifyAddValidatorTx( IsEUpgradeActive: false, Config: backend.Config, ChainTime: currentTimestamp, - FeeManager: feeManager, - ConsumedUnitsCap: unitCaps, Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { @@ -399,8 +395,6 @@ func verifyRemoveSubnetValidatorTx( // added to the staking set. func verifyAddDelegatorTx( backend *Backend, - feeManager *commonFees.Manager, - unitCaps commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddDelegatorTx, @@ -502,8 +496,6 @@ func verifyAddDelegatorTx( IsEUpgradeActive: false, Config: backend.Config, ChainTime: currentTimestamp, - FeeManager: feeManager, - ConsumedUnitsCap: unitCaps, Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index de301c94e513..5212310c2a67 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -369,8 +369,6 @@ func (e *StandardTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error { if _, err := verifyAddValidatorTx( e.Backend, - e.BlkFeeManager, - e.UnitCaps, e.State, e.Tx, tx, @@ -422,8 +420,6 @@ func (e *StandardTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) func (e *StandardTxExecutor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { if _, err := verifyAddDelegatorTx( e.Backend, - e.BlkFeeManager, - e.UnitCaps, e.State, e.Tx, tx, diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index 86f3e92821a3..60db001d4884 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -42,23 +42,26 @@ type Calculator struct { Fee uint64 } -func (fc *Calculator) AddValidatorTx(tx *txs.AddValidatorTx) error { - if !fc.IsEUpgradeActive { - fc.Fee = fc.Config.AddPrimaryNetworkValidatorFee - return nil - } +func (fc *Calculator) AddValidatorTx(*txs.AddValidatorTx) error { + // AddValidatorTx is banned following Durango activation, so we + // only return the pre EUpgrade fee here + fc.Fee = fc.Config.AddPrimaryNetworkValidatorFee + return nil +} - outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.StakeOuts)) - copy(outs, tx.Outs) - copy(outs[len(tx.Outs):], tx.StakeOuts) +func (fc *Calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { + // AddValidatorTx is banned following Durango activation, so we + // only return the pre EUpgrade fee here + fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee + return nil +} - consumedUnits, err := fc.commonConsumedUnits(tx, outs, tx.Ins) - if err != nil { - return err - } +func (*Calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + return nil // no fees +} - _, err = fc.AddFeesFor(consumedUnits) - return err +func (*Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { + return nil // no fees } func (fc *Calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { @@ -76,25 +79,6 @@ func (fc *Calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { return err } -func (fc *Calculator) AddDelegatorTx(tx *txs.AddDelegatorTx) error { - if !fc.IsEUpgradeActive { - fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee - return nil - } - - outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.StakeOuts)) - copy(outs, tx.Outs) - copy(outs[len(tx.Outs):], tx.StakeOuts) - - consumedUnits, err := fc.commonConsumedUnits(tx, outs, tx.Ins) - if err != nil { - return err - } - - _, err = fc.AddFeesFor(consumedUnits) - return err -} - func (fc *Calculator) CreateChainTx(tx *txs.CreateChainTx) error { if !fc.IsEUpgradeActive { fc.Fee = fc.Config.GetCreateBlockchainTxFee(fc.ChainTime) @@ -125,14 +109,6 @@ func (fc *Calculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { return err } -func (*Calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - return nil // no fees -} - -func (*Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { - return nil // no fees -} - func (fc *Calculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { if !fc.IsEUpgradeActive { fc.Fee = fc.Config.TxFee diff --git a/vms/platformvm/txs/fees/calculator_test.go b/vms/platformvm/txs/fees/calculator_test.go index 9d1d0cb3126f..537b90d6cd0f 100644 --- a/vms/platformvm/txs/fees/calculator_test.go +++ b/vms/platformvm/txs/fees/calculator_test.go @@ -239,37 +239,8 @@ func TestAddValidatorTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3719*units.MicroAvax, fc.Fee) - require.Equal(t, - fees.Dimensions{ - 741, - 1090, - 266, - 0, - }, - fc.FeeManager.GetCumulatedUnits(), - ) - }, - }, - { - description: "post E fork, bandwidth cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) - - cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime - }, - consumedUnitCapsF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits - caps[fees.Bandwidth] = 741 - 1 - return caps + require.Equal(t, fc.Config.AddPrimaryNetworkValidatorFee, fc.Fee) }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, }, } @@ -466,37 +437,8 @@ func TestAddDelegatorTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3715*units.MicroAvax, fc.Fee) - require.Equal(t, - fees.Dimensions{ - 737, - 1090, - 266, - 0, - }, - fc.FeeManager.GetCumulatedUnits(), - ) - }, - }, - { - description: "post E fork, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) - - cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime - }, - consumedUnitCapsF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 - return caps + require.Equal(t, fc.Config.AddPrimaryNetworkDelegatorFee, fc.Fee) }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, }, } diff --git a/vms/platformvm/utxo/handler_test.go b/vms/platformvm/utxo/handler_test.go index 08379e9b2f5b..fe6f249c862e 100644 --- a/vms/platformvm/utxo/handler_test.go +++ b/vms/platformvm/utxo/handler_test.go @@ -13,12 +13,15 @@ import ( "github.com/ava-labs/avalanchego/ids" "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/components/verify" "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/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -166,6 +169,9 @@ func TestVerifyFinanceTx(t *testing.T) { // even if bigUtxo would be enough finance the whole tx require.True(t, smallUtxoID.Compare(bigUtxoID) < 0) + sk, err := bls.NewSecretKey() + require.NoError(t, err) + tests := []struct { description string utxoReaderF func(ctrl *gomock.Controller) avax.UTXOReader @@ -200,7 +206,7 @@ func TestVerifyFinanceTx(t *testing.T) { amountToStake: units.MilliAvax, uTxF: func(t *testing.T) txs.UnsignedTx { - uTx := &txs.AddValidatorTx{ + uTx := &txs.AddPermissionlessValidatorTx{ BaseTx: txs.BaseTx{ BaseTx: avax.BaseTx{ NetworkID: ctx.NetworkID, @@ -216,8 +222,15 @@ func TestVerifyFinanceTx(t *testing.T) { End: uint64(time.Now().Unix()), Wght: amountToStake, }, + Subnet: constants.PrimaryNetworkID, + Signer: signer.NewProofOfPossession(sk), StakeOuts: make([]*avax.TransferableOutput, 0), - RewardsOwner: &secp256k1fx.OutputOwners{ + ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{ids.GenerateTestShortID()}, @@ -243,10 +256,10 @@ func TestVerifyFinanceTx(t *testing.T) { Credentials: []verify.Verifiable{}, } - expectedFee := 8911 * units.MicroAvax + expectedFee := 9131 * units.MicroAvax // complete uTx with the utxos - addVal, ok := uTx.(*txs.AddValidatorTx) + addVal, ok := uTx.(*txs.AddPermissionlessValidatorTx) r.True(ok) addVal.Ins = ins @@ -281,7 +294,7 @@ func TestVerifyFinanceTx(t *testing.T) { amountToStake: units.MilliAvax, uTxF: func(t *testing.T) txs.UnsignedTx { - uTx := &txs.AddValidatorTx{ + uTx := &txs.AddPermissionlessValidatorTx{ BaseTx: txs.BaseTx{ BaseTx: avax.BaseTx{ NetworkID: ctx.NetworkID, @@ -297,8 +310,15 @@ func TestVerifyFinanceTx(t *testing.T) { End: uint64(time.Now().Unix()), Wght: amountToStake, }, + Subnet: constants.PrimaryNetworkID, + Signer: signer.NewProofOfPossession(sk), StakeOuts: make([]*avax.TransferableOutput, 0), - RewardsOwner: &secp256k1fx.OutputOwners{ + ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{ids.GenerateTestShortID()}, @@ -324,10 +344,10 @@ func TestVerifyFinanceTx(t *testing.T) { Credentials: []verify.Verifiable{}, } - expectedFee := 5999 * units.MicroAvax + expectedFee := 6219 * units.MicroAvax // complete uTx with the utxos - addVal, ok := uTx.(*txs.AddValidatorTx) + addVal, ok := uTx.(*txs.AddPermissionlessValidatorTx) r.True(ok) addVal.Ins = ins @@ -364,7 +384,7 @@ func TestVerifyFinanceTx(t *testing.T) { amountToStake: units.MilliAvax, uTxF: func(t *testing.T) txs.UnsignedTx { - uTx := &txs.AddValidatorTx{ + uTx := &txs.AddPermissionlessValidatorTx{ BaseTx: txs.BaseTx{ BaseTx: avax.BaseTx{ NetworkID: ctx.NetworkID, @@ -380,8 +400,15 @@ func TestVerifyFinanceTx(t *testing.T) { End: uint64(time.Now().Unix()), Wght: amountToStake, }, + Subnet: constants.PrimaryNetworkID, + Signer: signer.NewProofOfPossession(sk), StakeOuts: make([]*avax.TransferableOutput, 0), - RewardsOwner: &secp256k1fx.OutputOwners{ + ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{ids.GenerateTestShortID()}, @@ -407,10 +434,10 @@ func TestVerifyFinanceTx(t *testing.T) { Credentials: []verify.Verifiable{}, } - expectedFee := 5879 * units.MicroAvax + expectedFee := 6099 * units.MicroAvax // complete uTx with the utxos - addVal, ok := uTx.(*txs.AddValidatorTx) + addVal, ok := uTx.(*txs.AddPermissionlessValidatorTx) r.True(ok) addVal.Ins = ins @@ -442,7 +469,7 @@ func TestVerifyFinanceTx(t *testing.T) { amountToStake: units.MilliAvax, uTxF: func(t *testing.T) txs.UnsignedTx { - uTx := &txs.AddValidatorTx{ + uTx := &txs.AddPermissionlessValidatorTx{ BaseTx: txs.BaseTx{ BaseTx: avax.BaseTx{ NetworkID: ctx.NetworkID, @@ -458,8 +485,15 @@ func TestVerifyFinanceTx(t *testing.T) { End: uint64(time.Now().Unix()), Wght: amountToStake, }, + Subnet: constants.PrimaryNetworkID, + Signer: signer.NewProofOfPossession(sk), StakeOuts: make([]*avax.TransferableOutput, 0), - RewardsOwner: &secp256k1fx.OutputOwners{ + ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{ids.GenerateTestShortID()}, @@ -485,10 +519,10 @@ func TestVerifyFinanceTx(t *testing.T) { Credentials: []verify.Verifiable{}, } - expectedFee := 3341 * units.MicroAvax + expectedFee := 3561 * units.MicroAvax // complete uTx with the utxos - addVal, ok := uTx.(*txs.AddValidatorTx) + addVal, ok := uTx.(*txs.AddPermissionlessValidatorTx) r.True(ok) addVal.Ins = ins diff --git a/wallet/chain/p/builder_dynamic_fees.go b/wallet/chain/p/builder_dynamic_fees.go index 945bdfa1510d..d2cacda1b0f2 100644 --- a/wallet/chain/p/builder_dynamic_fees.go +++ b/wallet/chain/p/builder_dynamic_fees.go @@ -91,56 +91,6 @@ func (b *DynamicFeesBuilder) NewBaseTx( return utx, b.initCtx(utx) } -func (b *DynamicFeesBuilder) NewAddValidatorTx( - vdr *txs.Validator, - rewardsOwner *secp256k1fx.OutputOwners, - shares uint32, - unitFees, unitCaps commonfees.Dimensions, - options ...common.Option, -) (*txs.AddValidatorTx, error) { - ops := common.NewOptions(options) - utils.Sort(rewardsOwner.Addrs) - utx := &txs.AddValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - Validator: *vdr, - RewardsOwner: rewardsOwner, - DelegationShares: shares, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): vdr.Wght, - } - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.AddValidatorTx(utx); err != nil { - return nil, err - } - - inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - utx.Ins = inputs - utx.Outs = outputs - utx.StakeOuts = stakeOutputs - - return utx, b.initCtx(utx) -} - func (b *DynamicFeesBuilder) NewAddSubnetValidatorTx( vdr *txs.SubnetValidator, unitFees, unitCaps commonfees.Dimensions, @@ -250,54 +200,6 @@ func (b *DynamicFeesBuilder) NewRemoveSubnetValidatorTx( return utx, b.initCtx(utx) } -func (b *DynamicFeesBuilder) NewAddDelegatorTx( - vdr *txs.Validator, - rewardsOwner *secp256k1fx.OutputOwners, - unitFees, unitCaps commonfees.Dimensions, - options ...common.Option, -) (*txs.AddDelegatorTx, error) { - ops := common.NewOptions(options) - utils.Sort(rewardsOwner.Addrs) - utx := &txs.AddDelegatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - Validator: *vdr, - DelegationRewardsOwner: rewardsOwner, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): vdr.Wght, - } - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.AddDelegatorTx(utx); err != nil { - return nil, err - } - - inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - utx.Ins = inputs - utx.Outs = outputs - utx.StakeOuts = stakeOutputs - - return utx, b.initCtx(utx) -} - func (b *DynamicFeesBuilder) NewCreateChainTx( subnetID ids.ID, genesis []byte, diff --git a/wallet/chain/p/builder_dynamic_fees_test.go b/wallet/chain/p/builder_dynamic_fees_test.go index a1936e603efc..02ea45f05149 100644 --- a/wallet/chain/p/builder_dynamic_fees_test.go +++ b/wallet/chain/p/builder_dynamic_fees_test.go @@ -118,79 +118,6 @@ func TestBaseTx(t *testing.T) { require.Equal(outputsToMove[0], outs[1]) } -func TestAddValidatorTx(t *testing.T) { - require := require.New(t) - ctrl := gomock.NewController(t) - - be := mocks.NewMockBuilderBackend(ctrl) - - var ( - rewardKey = testKeys[0] - utxosKey = testKeys[1] - rewardAddr = rewardKey.PublicKey().Address() - utxoAddr = utxosKey.PublicKey().Address() - utxos, avaxAssetID, _ = testUTXOsList(utxosKey) - rewardOwner = &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - rewardKey.Address(), - }, - } - ) - - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, rewardAddr), - backend: be, - } - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - - utx, err := b.NewAddValidatorTx( - &txs.Validator{ - NodeID: ids.GenerateTestNodeID(), - End: uint64(time.Now().Add(time.Hour).Unix()), - Wght: 2 * units.Avax, - }, - rewardOwner, - reward.PercentDenominator, - testUnitFees, - testBlockMaxConsumedUnits, - ) - require.NoError(err) - - var ( - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) - ) - - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) - - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, - } - require.NoError(utx.Visit(fc)) - require.Equal(12184*units.MicroAvax, fc.Fee) - - ins := utx.Ins - staked := utx.StakeOuts - outs := utx.Outs - require.Len(ins, 4) - require.Len(staked, 2) - require.Len(outs, 2) - require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) - require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) -} - func TestAddSubnetValidatorTx(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) @@ -333,78 +260,6 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) } -func TestAddDelegatorTx(t *testing.T) { - require := require.New(t) - ctrl := gomock.NewController(t) - - be := mocks.NewMockBuilderBackend(ctrl) - - var ( - rewardKey = testKeys[0] - utxosKey = testKeys[1] - rewardAddr = rewardKey.PublicKey().Address() - utxoAddr = utxosKey.PublicKey().Address() - utxos, avaxAssetID, _ = testUTXOsList(utxosKey) - rewardOwner = &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - rewardKey.Address(), - }, - } - ) - - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, rewardAddr), - backend: be, - } - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - - utx, err := b.NewAddDelegatorTx( - &txs.Validator{ - NodeID: ids.GenerateTestNodeID(), - End: uint64(time.Now().Add(time.Hour).Unix()), - Wght: 2 * units.Avax, - }, - rewardOwner, - testUnitFees, - testBlockMaxConsumedUnits, - ) - require.NoError(err) - - var ( - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) - ) - - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) - - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, - } - require.NoError(utx.Visit(fc)) - require.Equal(12180*units.MicroAvax, fc.Fee) - - ins := utx.Ins - staked := utx.StakeOuts - outs := utx.Outs - require.Len(ins, 4) - require.Len(staked, 2) - require.Len(outs, 2) - require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) - require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) -} - func TestCreateChainTx(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 7edacbf24792..af7bd7da13aa 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -326,19 +326,7 @@ func (w *wallet) IssueAddValidatorTx( shares uint32, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { - return nil, err - } - - var ( - utx txs.UnsignedTx - err error - ) - if w.isEForkActive { - utx, err = w.dynamicBuilder.NewAddValidatorTx(vdr, rewardsOwner, shares, w.unitFees, w.unitCaps, options...) - } else { - utx, err = w.builder.NewAddValidatorTx(vdr, rewardsOwner, shares, options...) - } + utx, err := w.builder.NewAddValidatorTx(vdr, rewardsOwner, shares, options...) if err != nil { return nil, err } @@ -397,19 +385,7 @@ func (w *wallet) IssueAddDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { - return nil, err - } - - var ( - utx txs.UnsignedTx - err error - ) - if w.isEForkActive { - utx, err = w.dynamicBuilder.NewAddDelegatorTx(vdr, rewardsOwner, w.unitFees, w.unitCaps, options...) - } else { - utx, err = w.builder.NewAddDelegatorTx(vdr, rewardsOwner, options...) - } + utx, err := w.builder.NewAddDelegatorTx(vdr, rewardsOwner, options...) if err != nil { return nil, err } From 0c0022e39bb921e58d70d6e235fa9db4ecdb3ebc Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 5 Feb 2024 10:37:57 +0100 Subject: [PATCH 005/120] fixed AddPermissionlessValidatorTx AddPermissionlessDelegatorTx fees post EUpgrade --- vms/platformvm/txs/builder/builder.go | 112 +++++++++++++++++++++----- 1 file changed, 93 insertions(+), 19 deletions(-) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 42333adfec20..04144a737cbb 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -747,17 +747,11 @@ func (b *builder) NewAddPermissionlessValidatorTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - ins, unstakedOuts, stakedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkValidatorFee, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - // Create the tx + // 1. Build core transaction without utxos utx := &txs.AddPermissionlessValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, }}, Validator: txs.Validator{ NodeID: nodeID, @@ -765,9 +759,8 @@ func (b *builder) NewAddPermissionlessValidatorTx( End: endTime, Wght: stakeAmount, }, - Subnet: constants.PrimaryNetworkID, - Signer: pop, - StakeOuts: stakedOuts, + Subnet: constants.PrimaryNetworkID, + Signer: pop, ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, @@ -780,6 +773,50 @@ func (b *builder) NewAddPermissionlessValidatorTx( }, DelegationShares: shares, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput + outs []*avax.TransferableOutput + stakeOuts []*avax.TransferableOutput + signers [][]*secp256k1.PrivateKey + err error + ) + if isEForkActive { + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.AddPermissionlessValidatorTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + } else { + ins, outs, stakeOuts, signers, err = b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkValidatorFee, changeAddr) + } + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + utx.StakeOuts = stakeOuts + + // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -837,17 +874,11 @@ func (b *builder) NewAddPermissionlessDelegatorTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - ins, unlockedOuts, lockedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkDelegatorFee, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - // Create the tx + // 1. Build core transaction without utxos utx := &txs.AddPermissionlessDelegatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: unlockedOuts, }}, Validator: txs.Validator{ NodeID: nodeID, @@ -855,14 +886,57 @@ func (b *builder) NewAddPermissionlessDelegatorTx( End: endTime, Wght: stakeAmount, }, - Subnet: constants.PrimaryNetworkID, - StakeOuts: lockedOuts, + Subnet: constants.PrimaryNetworkID, DelegationRewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{rewardAddress}, }, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput + outs []*avax.TransferableOutput + stakeOuts []*avax.TransferableOutput + signers [][]*secp256k1.PrivateKey + err error + ) + if isEForkActive { + feeCfg := config.EUpgradeDynamicFeesConfig + feeCalc := &fees.Calculator{ + IsEUpgradeActive: isEForkActive, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: txs.EmptyCredentials(signers), + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.AddPermissionlessDelegatorTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + } else { + ins, outs, stakeOuts, signers, err = b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkDelegatorFee, changeAddr) + } + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + utx.StakeOuts = stakeOuts + + // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err From f498af9df52d3d38d313d3d58d2c1ccdaf6ba364 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 5 Feb 2024 11:51:24 +0100 Subject: [PATCH 006/120] removed some code duplication --- vms/components/fees/helpers.go | 3 +- wallet/chain/p/builder.go | 51 ++++++++------- wallet/chain/p/builder_dynamic_fees.go | 71 +++++---------------- wallet/chain/p/builder_dynamic_fees_test.go | 2 +- 4 files changed, 47 insertions(+), 80 deletions(-) diff --git a/vms/components/fees/helpers.go b/vms/components/fees/helpers.go index dfdee15325eb..8db95ae9bff9 100644 --- a/vms/components/fees/helpers.go +++ b/vms/components/fees/helpers.go @@ -53,8 +53,7 @@ func GetOutputsDimensions(c codec.Manager, v uint16, outs []*avax.TransferableOu func GetCredentialsDimensions(c codec.Manager, v uint16, inputSigIndices []uint32) (Dimensions, error) { var consumedUnits Dimensions - // Workaround to ensure that codec picks interface instead of the pointer to evaluate size. - // TODO ABENEGIA: fix this + // 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, len(inputSigIndices)), diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index a2c7208ffe8a..f2adcb77c14f 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -332,7 +332,7 @@ func (b *builder) NewBaseTx( }}, Owner: &secp256k1fx.OutputOwners{}, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewAddValidatorTx( @@ -368,7 +368,7 @@ func (b *builder) NewAddValidatorTx( RewardsOwner: rewardsOwner, DelegationShares: shares, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewAddSubnetValidatorTx( @@ -385,7 +385,7 @@ func (b *builder) NewAddSubnetValidatorTx( return nil, err } - subnetAuth, err := b.authorizeSubnet(vdr.Subnet, ops) + subnetAuth, err := authorizeSubnet(b.backend, b.addrs, vdr.Subnet, ops) if err != nil { return nil, err } @@ -401,7 +401,7 @@ func (b *builder) NewAddSubnetValidatorTx( SubnetValidator: *vdr, SubnetAuth: subnetAuth, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewRemoveSubnetValidatorTx( @@ -419,7 +419,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( return nil, err } - subnetAuth, err := b.authorizeSubnet(subnetID, ops) + subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) if err != nil { return nil, err } @@ -436,7 +436,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( NodeID: nodeID, SubnetAuth: subnetAuth, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewAddDelegatorTx( @@ -470,7 +470,7 @@ func (b *builder) NewAddDelegatorTx( StakeOuts: stakeOutputs, DelegationRewardsOwner: rewardsOwner, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewCreateChainTx( @@ -491,7 +491,7 @@ func (b *builder) NewCreateChainTx( return nil, err } - subnetAuth, err := b.authorizeSubnet(subnetID, ops) + subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) if err != nil { return nil, err } @@ -512,7 +512,7 @@ func (b *builder) NewCreateChainTx( GenesisData: genesis, SubnetAuth: subnetAuth, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewCreateSubnetTx( @@ -540,7 +540,7 @@ func (b *builder) NewCreateSubnetTx( }}, Owner: owner, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewTransferSubnetOwnershipTx( @@ -558,7 +558,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( return nil, err } - subnetAuth, err := b.authorizeSubnet(subnetID, ops) + subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) if err != nil { return nil, err } @@ -576,7 +576,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( Owner: owner, SubnetAuth: subnetAuth, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewImportTx( @@ -683,7 +683,7 @@ func (b *builder) NewImportTx( SourceChain: sourceChainID, ImportedInputs: importedInputs, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewExportTx( @@ -722,7 +722,7 @@ func (b *builder) NewExportTx( DestinationChain: chainID, ExportedOutputs: outputs, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewTransformSubnetTx( @@ -753,7 +753,7 @@ func (b *builder) NewTransformSubnetTx( return nil, err } - subnetAuth, err := b.authorizeSubnet(subnetID, ops) + subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) if err != nil { return nil, err } @@ -782,7 +782,7 @@ func (b *builder) NewTransformSubnetTx( UptimeRequirement: uptimeRequirement, SubnetAuth: subnetAuth, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewAddPermissionlessValidatorTx( @@ -828,7 +828,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( DelegatorRewardsOwner: delegationRewardsOwner, DelegationShares: shares, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) NewAddPermissionlessDelegatorTx( @@ -867,7 +867,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( StakeOuts: stakeOutputs, DelegationRewardsOwner: rewardsOwner, } - return tx, b.initCtx(tx) + return tx, initCtx(b.backend, tx) } func (b *builder) getBalance( @@ -1146,8 +1146,13 @@ func (b *builder) spend( return inputs, changeOutputs, stakeOutputs, nil } -func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*secp256k1fx.Input, error) { - ownerIntf, err := b.backend.GetSubnetOwner(options.Context(), subnetID) +func authorizeSubnet( + backend BuilderBackend, + addresses set.Set[ids.ShortID], + subnetID ids.ID, + options *common.Options, +) (*secp256k1fx.Input, error) { + ownerIntf, err := backend.GetSubnetOwner(options.Context(), subnetID) if err != nil { return nil, fmt.Errorf( "failed to fetch subnet owner for %q: %w", @@ -1160,7 +1165,7 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se return nil, errUnknownOwnerType } - addrs := options.Addresses(b.addrs) + addrs := options.Addresses(addresses) minIssuanceTime := options.MinIssuanceTime() inputSigIndices, ok := common.MatchOwners(owner, addrs, minIssuanceTime) if !ok { @@ -1172,8 +1177,8 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se }, nil } -func (b *builder) initCtx(tx txs.UnsignedTx) error { - ctx, err := newSnowContext(b.backend) +func initCtx(backend BuilderBackend, tx txs.UnsignedTx) error { + ctx, err := newSnowContext(backend) if err != nil { return err } diff --git a/wallet/chain/p/builder_dynamic_fees.go b/wallet/chain/p/builder_dynamic_fees.go index d2cacda1b0f2..4e0f08e2bf3b 100644 --- a/wallet/chain/p/builder_dynamic_fees.go +++ b/wallet/chain/p/builder_dynamic_fees.go @@ -88,7 +88,7 @@ func (b *DynamicFeesBuilder) NewBaseTx( utx.Ins = inputs utx.Outs = outputs - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) } func (b *DynamicFeesBuilder) NewAddSubnetValidatorTx( @@ -98,7 +98,7 @@ func (b *DynamicFeesBuilder) NewAddSubnetValidatorTx( ) (*txs.AddSubnetValidatorTx, error) { ops := common.NewOptions(options) - subnetAuth, err := b.authorizeSubnet(vdr.Subnet, ops) + subnetAuth, err := authorizeSubnet(b.backend, b.addrs, vdr.Subnet, ops) if err != nil { return nil, err } @@ -142,7 +142,7 @@ func (b *DynamicFeesBuilder) NewAddSubnetValidatorTx( utx.Ins = inputs utx.Outs = outputs - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) } func (b *DynamicFeesBuilder) NewRemoveSubnetValidatorTx( @@ -153,7 +153,7 @@ func (b *DynamicFeesBuilder) NewRemoveSubnetValidatorTx( ) (*txs.RemoveSubnetValidatorTx, error) { ops := common.NewOptions(options) - subnetAuth, err := b.authorizeSubnet(subnetID, ops) + subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) if err != nil { return nil, err } @@ -197,7 +197,7 @@ func (b *DynamicFeesBuilder) NewRemoveSubnetValidatorTx( utx.Ins = inputs utx.Outs = outputs - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) } func (b *DynamicFeesBuilder) NewCreateChainTx( @@ -211,7 +211,7 @@ func (b *DynamicFeesBuilder) NewCreateChainTx( ) (*txs.CreateChainTx, error) { // 1. Build core transaction without utxos ops := common.NewOptions(options) - subnetAuth, err := b.authorizeSubnet(subnetID, ops) + subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) if err != nil { return nil, err } @@ -261,7 +261,7 @@ func (b *DynamicFeesBuilder) NewCreateChainTx( uTx.Ins = inputs uTx.Outs = outputs - return uTx, b.initCtx(uTx) + return uTx, initCtx(b.backend, uTx) } func (b *DynamicFeesBuilder) NewCreateSubnetTx( @@ -305,7 +305,7 @@ func (b *DynamicFeesBuilder) NewCreateSubnetTx( utx.Ins = inputs utx.Outs = outputs - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) } func (b *DynamicFeesBuilder) NewImportTx( @@ -422,7 +422,7 @@ func (b *DynamicFeesBuilder) NewImportTx( case importedAVAX == feeCalc.Fee: // imported inputs match exactly the fees to be paid avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) case importedAVAX < feeCalc.Fee: // imported inputs can partially pay fees @@ -451,12 +451,12 @@ func (b *DynamicFeesBuilder) NewImportTx( changeOut.Out.(*secp256k1fx.TransferOutput).Amt = importedAVAX - feeCalc.Fee utx.Outs = append(utx.Outs, changeOut) avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) case feeCalc.Fee == importedAVAX: // imported fees pays exactly the tx cost. We don't include the outputs avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) default: // imported avax are not enough to pay fees @@ -478,7 +478,7 @@ func (b *DynamicFeesBuilder) NewImportTx( utx.Ins = inputs utx.Outs = append(utx.Outs, changeOuts...) avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) } func (b *DynamicFeesBuilder) NewExportTx( @@ -533,7 +533,7 @@ func (b *DynamicFeesBuilder) NewExportTx( utx.Ins = inputs utx.Outs = changeOuts - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) } func (b *DynamicFeesBuilder) NewTransformSubnetTx( @@ -557,7 +557,7 @@ func (b *DynamicFeesBuilder) NewTransformSubnetTx( // 1. Build core transaction without utxos ops := common.NewOptions(options) - subnetAuth, err := b.authorizeSubnet(subnetID, ops) + subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) if err != nil { return nil, err } @@ -616,7 +616,7 @@ func (b *DynamicFeesBuilder) NewTransformSubnetTx( utx.Ins = inputs utx.Outs = outputs - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) } func (b *DynamicFeesBuilder) NewAddPermissionlessValidatorTx( @@ -674,7 +674,7 @@ func (b *DynamicFeesBuilder) NewAddPermissionlessValidatorTx( utx.Outs = outputs utx.StakeOuts = stakeOutputs - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) } func (b *DynamicFeesBuilder) NewAddPermissionlessDelegatorTx( @@ -725,7 +725,7 @@ func (b *DynamicFeesBuilder) NewAddPermissionlessDelegatorTx( utx.Outs = outputs utx.StakeOuts = stakeOutputs - return utx, b.initCtx(utx) + return utx, initCtx(b.backend, utx) } func (b *DynamicFeesBuilder) financeTx( @@ -1033,43 +1033,6 @@ func (b *DynamicFeesBuilder) financeTx( return inputs, changeOutputs, stakeOutputs, nil } -// TODO ABENEGIA: remove duplication with builder method -func (b *DynamicFeesBuilder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*secp256k1fx.Input, error) { - ownerIntf, err := b.backend.GetSubnetOwner(options.Context(), subnetID) - if err != nil { - return nil, fmt.Errorf( - "failed to fetch subnet owner for %q: %w", - subnetID, - err, - ) - } - owner, ok := ownerIntf.(*secp256k1fx.OutputOwners) - if !ok { - return nil, errUnknownOwnerType - } - - addrs := options.Addresses(b.addrs) - minIssuanceTime := options.MinIssuanceTime() - inputSigIndices, ok := common.MatchOwners(owner, addrs, minIssuanceTime) - if !ok { - // We can't authorize the subnet - return nil, errInsufficientAuthorization - } - return &secp256k1fx.Input{ - SigIndices: inputSigIndices, - }, nil -} - -func (b *DynamicFeesBuilder) initCtx(tx txs.UnsignedTx) error { - ctx, err := newSnowContext(b.backend) - if err != nil { - return err - } - - tx.InitCtx(ctx) - return nil -} - func financeInput(feeCalc *fees.Calculator, input *avax.TransferableInput) (uint64, error) { insDimensions, err := commonfees.GetInputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) if err != nil { diff --git a/wallet/chain/p/builder_dynamic_fees_test.go b/wallet/chain/p/builder_dynamic_fees_test.go index 02ea45f05149..ec5570349d74 100644 --- a/wallet/chain/p/builder_dynamic_fees_test.go +++ b/wallet/chain/p/builder_dynamic_fees_test.go @@ -807,7 +807,7 @@ func testUTXOsList(utxosKey *secp256k1.PrivateKey) ( subnetAssetID = ids.Empty.Prefix(utxosOffset + 1) ) - return []*avax.UTXO{ // currently, the wallet scans UTXOs in the order provided here + return []*avax.UTXO{ { // a small UTXO first, which should not be enough to pay fees UTXOID: avax.UTXOID{ TxID: ids.Empty.Prefix(utxosOffset), From fc8afd8e59c85bdb9152daf4357a16ec367ee8f5 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 5 Feb 2024 12:03:08 +0100 Subject: [PATCH 007/120] drop duplicated test --- vms/platformvm/txs/fees/calculator_test.go | 78 ---------------------- 1 file changed, 78 deletions(-) diff --git a/vms/platformvm/txs/fees/calculator_test.go b/vms/platformvm/txs/fees/calculator_test.go index 537b90d6cd0f..a0400e15f595 100644 --- a/vms/platformvm/txs/fees/calculator_test.go +++ b/vms/platformvm/txs/fees/calculator_test.go @@ -4,13 +4,11 @@ package fees import ( - "math/rand" "testing" "time" "github.com/stretchr/testify/require" - "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/snowtest" @@ -106,82 +104,6 @@ func TestAddAndRemoveFees(t *testing.T) { r.Zero(fc.Fee) } -func TestUTXOsAreAdditiveInSize(t *testing.T) { - // Show that including utxos of size [S] into a tx of size [T] - // result in a tx of size [S+T-CodecVersion] - // This is key to calculate fees correctly while building a tx - - uTx := &txs.AddValidatorTx{ - BaseTx: txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: rand.Uint32(), //#nosec G404 - BlockchainID: ids.GenerateTestID(), - Memo: []byte{'a', 'b', 'c'}, - Ins: make([]*avax.TransferableInput, 0), - Outs: make([]*avax.TransferableOutput, 0), - }, - }, - } - - uTxNakedSize := 105 - uTxSize, err := txs.Codec.Size(txs.CodecVersion, uTx) - require.NoError(t, err) - require.Equal(t, uTxNakedSize, uTxSize) - - // input to add - input := &avax.TransferableInput{ - UTXOID: avax.UTXOID{ - TxID: ids.ID{'t', 'x', 'I', 'D'}, - OutputIndex: 2, - }, - Asset: avax.Asset{ID: ids.GenerateTestID()}, - In: &secp256k1fx.TransferInput{ - Amt: uint64(5678), - Input: secp256k1fx.Input{SigIndices: []uint32{0}}, - }, - } - inSize, err := txs.Codec.Size(txs.CodecVersion, input) - require.NoError(t, err) - - // include input in uTx and check that sizes add - uTx.BaseTx.BaseTx.Ins = append(uTx.BaseTx.BaseTx.Ins, input) - uTxSize, err = txs.Codec.Size(txs.CodecVersion, uTx) - require.NoError(t, err) - require.Equal(t, uTxNakedSize+(inSize-codec.CodecVersionSize), uTxSize) - - // output to add - output := &avax.TransferableOutput{ - Asset: avax.Asset{ - ID: ids.GenerateTestID(), - }, - Out: &stakeable.LockOut{ - Locktime: 87654321, - TransferableOut: &secp256k1fx.TransferOutput{ - Amt: 1, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 12345678, - Threshold: 0, - Addrs: []ids.ShortID{}, - }, - }, - }, - } - outSize, err := txs.Codec.Size(txs.CodecVersion, output) - require.NoError(t, err) - - // include output in uTx and check that sizes add - uTx.BaseTx.BaseTx.Outs = append(uTx.BaseTx.BaseTx.Outs, output) - uTxSize, err = txs.Codec.Size(txs.CodecVersion, uTx) - require.NoError(t, err) - require.Equal(t, uTxNakedSize+(inSize-codec.CodecVersionSize)+(outSize-codec.CodecVersionSize), uTxSize) - - // include output in uTx as stake and check that sizes add - uTx.StakeOuts = append(uTx.StakeOuts, output) - uTxSize, err = txs.Codec.Size(txs.CodecVersion, uTx) - require.NoError(t, err) - require.Equal(t, uTxNakedSize+(inSize-codec.CodecVersionSize)+(outSize-codec.CodecVersionSize)+(outSize-codec.CodecVersionSize), uTxSize) -} - func TestAddValidatorTxFees(t *testing.T) { r := require.New(t) From 3afc8e47d855797be7f9b859f6378fccaa8c7d0a Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 5 Feb 2024 15:52:13 +0100 Subject: [PATCH 008/120] reduced fees calculator UTs code duplication --- vms/platformvm/txs/fees/calculator_test.go | 1122 ++++++++------------ 1 file changed, 434 insertions(+), 688 deletions(-) diff --git a/vms/platformvm/txs/fees/calculator_test.go b/vms/platformvm/txs/fees/calculator_test.go index a0400e15f595..8cbabc1d33dc 100644 --- a/vms/platformvm/txs/fees/calculator_test.go +++ b/vms/platformvm/txs/fees/calculator_test.go @@ -58,11 +58,12 @@ var ( ) type feeTests struct { - description string - cfgAndChainTimeF func() (*config.Config, time.Time) - consumedUnitCapsF func() fees.Dimensions - expectedError error - checksF func(*testing.T, *Calculator) + description string + cfgAndChainTimeF func() (*config.Config, time.Time) + unsignedAndSignedTx func(t *testing.T) (txs.UnsignedTx, *txs.Tx) + consumedUnitCapsF func() fees.Dimensions + expectedError error + checksF func(*testing.T, *Calculator) } func TestAddAndRemoveFees(t *testing.T) { @@ -104,34 +105,12 @@ func TestAddAndRemoveFees(t *testing.T) { r.Zero(fc.Fee) } -func TestAddValidatorTxFees(t *testing.T) { +func TestTxFees(t *testing.T) { 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) - tests := []feeTests{ { - description: "pre E fork", + description: "AddValidatorTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -142,13 +121,14 @@ func TestAddValidatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: addValidatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.AddPrimaryNetworkValidatorFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "AddValidatorTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -159,63 +139,14 @@ func TestAddValidatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + expectedError: nil, + unsignedAndSignedTx: addValidatorTx, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.AddPrimaryNetworkValidatorFee, fc.Fee) }, }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestAddSubnetValidatorTxFees(t *testing.T) { - 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) - - tests := []feeTests{ { - description: "pre E fork", + description: "AddSubnetValidatorTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -226,13 +157,14 @@ func TestAddSubnetValidatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: addSubnetValidatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.AddSubnetValidatorFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "AddSubnetValidatorTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -243,7 +175,8 @@ func TestAddSubnetValidatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + expectedError: nil, + unsignedAndSignedTx: addSubnetValidatorTx, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, 3345*units.MicroAvax, fc.Fee) require.Equal(t, @@ -258,7 +191,7 @@ func TestAddSubnetValidatorTxFees(t *testing.T) { }, }, { - description: "post E fork, utxos read cap breached", + description: "AddSubnetValidatorTx post E fork, utxos read cap breached", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -274,62 +207,12 @@ func TestAddSubnetValidatorTxFees(t *testing.T) { caps[fees.UTXORead] = 1090 - 1 return caps }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, - }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestAddDelegatorTxFees(t *testing.T) { - 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, + unsignedAndSignedTx: addSubnetValidatorTx, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, }, - 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) - - tests := []feeTests{ { - description: "pre E fork", + description: "AddDelegatorTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -340,13 +223,14 @@ func TestAddDelegatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: addDelegatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.AddPrimaryNetworkDelegatorFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "AddDelegatorTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -357,58 +241,14 @@ func TestAddDelegatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: addDelegatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.AddPrimaryNetworkDelegatorFee, fc.Fee) }, }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestCreateChainTxFees(t *testing.T) { - 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) - - tests := []feeTests{ { - description: "pre E fork", + description: "CreateChainTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -419,13 +259,14 @@ func TestCreateChainTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: createChainTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.CreateBlockchainTxFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "CreateChainTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -436,7 +277,8 @@ func TestCreateChainTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: createChainTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, 3388*units.MicroAvax, fc.Fee) require.Equal(t, @@ -451,7 +293,7 @@ func TestCreateChainTxFees(t *testing.T) { }, }, { - description: "post E fork, utxos read cap breached", + description: "CreateChainTx post E fork, utxos read cap breached", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -462,6 +304,7 @@ func TestCreateChainTxFees(t *testing.T) { return &cfg, chainTime }, + unsignedAndSignedTx: createChainTx, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 1090 - 1 @@ -470,51 +313,8 @@ func TestCreateChainTxFees(t *testing.T) { expectedError: errFailedConsumedUnitsCumulation, checksF: func(t *testing.T, fc *Calculator) {}, }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestCreateSubnetTxFees(t *testing.T) { - 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) - - tests := []feeTests{ { - description: "pre E fork", + description: "CreateSubnetTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -525,13 +325,14 @@ func TestCreateSubnetTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: createSubnetTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.CreateSubnetTxFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "CreateSubnetTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -542,7 +343,8 @@ func TestCreateSubnetTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: createSubnetTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, 3293*units.MicroAvax, fc.Fee) require.Equal(t, @@ -557,7 +359,7 @@ func TestCreateSubnetTxFees(t *testing.T) { }, }, { - description: "post E fork, utxos read cap breached", + description: "CreateSubnetTx post E fork, utxos read cap breached", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -573,53 +375,12 @@ func TestCreateSubnetTxFees(t *testing.T) { caps[fees.UTXORead] = 1090 - 1 return caps }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, + unsignedAndSignedTx: createSubnetTx, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestRemoveSubnetValidatorTxFees(t *testing.T) { - 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) - - tests := []feeTests{ { - description: "pre E fork", + description: "RemoveSubnetValidatorTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -630,13 +391,14 @@ func TestRemoveSubnetValidatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: removeSubnetValidatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.TxFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "RemoveSubnetValidatorTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -647,7 +409,8 @@ func TestRemoveSubnetValidatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: removeSubnetValidatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, 3321*units.MicroAvax, fc.Fee) require.Equal(t, @@ -662,7 +425,7 @@ func TestRemoveSubnetValidatorTxFees(t *testing.T) { }, }, { - description: "post E fork, utxos read cap breached", + description: "RemoveSubnetValidatorTx post E fork, utxos read cap breached", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -678,65 +441,12 @@ func TestRemoveSubnetValidatorTxFees(t *testing.T) { caps[fees.UTXORead] = 1090 - 1 return caps }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, + unsignedAndSignedTx: removeSubnetValidatorTx, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestTransformSubnetTxFees(t *testing.T) { - 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) - - tests := []feeTests{ { - description: "pre E fork", + description: "TransformSubnetTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -747,13 +457,14 @@ func TestTransformSubnetTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: transformSubnetTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.TransformSubnetTxFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "TransformSubnetTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -764,7 +475,8 @@ func TestTransformSubnetTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: transformSubnetTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, 3406*units.MicroAvax, fc.Fee) require.Equal(t, @@ -779,7 +491,7 @@ func TestTransformSubnetTxFees(t *testing.T) { }, }, { - description: "post E fork, utxos read cap breached", + description: "TransformSubnetTx post E fork, utxos read cap breached", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -795,61 +507,12 @@ func TestTransformSubnetTxFees(t *testing.T) { caps[fees.UTXORead] = 1090 - 1 return caps }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, - }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestTransferSubnetOwnershipTxFees(t *testing.T) { - 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(), - }, + unsignedAndSignedTx: transformSubnetTx, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, }, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - - tests := []feeTests{ { - description: "pre E fork", + description: "TransferSubnetOwnershipTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -860,13 +523,14 @@ func TestTransferSubnetOwnershipTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: transferSubnetOwnershipTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.TxFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "TransferSubnetOwnershipTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -877,7 +541,8 @@ func TestTransferSubnetOwnershipTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: transferSubnetOwnershipTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, 3337*units.MicroAvax, fc.Fee) require.Equal(t, @@ -892,7 +557,7 @@ func TestTransferSubnetOwnershipTxFees(t *testing.T) { }, }, { - description: "post E fork, utxos read cap breached", + description: "TransferSubnetOwnershipTx post E fork, utxos read cap breached", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -908,70 +573,12 @@ func TestTransferSubnetOwnershipTxFees(t *testing.T) { caps[fees.UTXORead] = 1090 - 1 return caps }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, - }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestAddPermissionlessValidatorTxFees(t *testing.T) { - 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: ids.GenerateTestID(), - 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(), - }, + unsignedAndSignedTx: transferSubnetOwnershipTx, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, }, - DelegationShares: reward.PercentDenominator, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - - tests := []feeTests{ { - description: "pre E fork", + description: "AddPermissionlessValidatorTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -982,13 +589,14 @@ func TestAddPermissionlessValidatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: addPermissionlessValidatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.AddSubnetValidatorFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "AddPermissionlessValidatorTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -999,7 +607,8 @@ func TestAddPermissionlessValidatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: addPermissionlessValidatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, 3939*units.MicroAvax, fc.Fee) require.Equal(t, @@ -1014,7 +623,7 @@ func TestAddPermissionlessValidatorTxFees(t *testing.T) { }, }, { - description: "post E fork, utxos read cap breached", + description: "AddPermissionlessValidatorTx post E fork, utxos read cap breached", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -1030,65 +639,12 @@ func TestAddPermissionlessValidatorTxFees(t *testing.T) { caps[fees.UTXORead] = 1090 - 1 return caps }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, - }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestAddPermissionlessDelegatorTxFees(t *testing.T) { - 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: ids.GenerateTestID(), - StakeOuts: stakes, - DelegationRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - ids.GenerateTestShortID(), - }, + unsignedAndSignedTx: addPermissionlessValidatorTx, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, }, - } - sTx, err := txs.NewSigned(uTx, txs.Codec, feeTestSigners) - r.NoError(err) - - tests := []feeTests{ { - description: "pre E fork", + description: "AddPermissionlessDelegatorTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -1099,13 +655,14 @@ func TestAddPermissionlessDelegatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: addPermissionlessDelegatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.AddSubnetDelegatorFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "AddPermissionlessDelegatorTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -1116,7 +673,8 @@ func TestAddPermissionlessDelegatorTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: addPermissionlessDelegatorTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, 3747*units.MicroAvax, fc.Fee) require.Equal(t, @@ -1131,7 +689,7 @@ func TestAddPermissionlessDelegatorTxFees(t *testing.T) { }, }, { - description: "post E fork, utxos read cap breached", + description: "AddPermissionlessDelegatorTx post E fork, utxos read cap breached", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -1147,48 +705,12 @@ func TestAddPermissionlessDelegatorTxFees(t *testing.T) { caps[fees.UTXORead] = 1090 - 1 return caps }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, + unsignedAndSignedTx: addPermissionlessDelegatorTx, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestBaseTxFees(t *testing.T) { - 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) - - tests := []feeTests{ { - description: "pre E fork", + description: "BaseTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -1199,13 +721,14 @@ func TestBaseTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: baseTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.TxFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "BaseTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -1216,7 +739,8 @@ func TestBaseTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: baseTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, 3253*units.MicroAvax, fc.Fee) require.Equal(t, @@ -1231,7 +755,7 @@ func TestBaseTxFees(t *testing.T) { }, }, { - description: "post E fork, utxos read cap breached", + description: "BaseTx post E fork, utxos read cap breached", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -1247,62 +771,12 @@ func TestBaseTxFees(t *testing.T) { caps[fees.UTXORead] = 1090 - 1 return caps }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, + unsignedAndSignedTx: baseTx, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestImportTxFees(t *testing.T) { - 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) - - tests := []feeTests{ { - description: "pre E fork", + description: "ImportTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -1313,13 +787,14 @@ func TestImportTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: importTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.TxFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "ImportTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -1330,7 +805,8 @@ func TestImportTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: importTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, 5827*units.MicroAvax, fc.Fee) require.Equal(t, @@ -1345,7 +821,7 @@ func TestImportTxFees(t *testing.T) { }, }, { - description: "post E fork, utxos read cap breached", + description: "ImportTx post E fork, utxos read cap breached", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -1361,52 +837,12 @@ func TestImportTxFees(t *testing.T) { caps[fees.UTXORead] = 1090 - 1 return caps }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, + unsignedAndSignedTx: importTx, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - cfg, chainTime := tt.cfgAndChainTimeF() - - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() - } - - fc := &Calculator{ - IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, - } - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) - }) - } -} - -func TestExportTxFees(t *testing.T) { - 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) - - tests := []feeTests{ { - description: "pre E fork", + description: "ExportTx pre E fork", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(-1 * time.Second) @@ -1417,13 +853,14 @@ func TestExportTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: exportTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, fc.Config.TxFee, fc.Fee) }, }, { - description: "post E fork, success", + description: "ExportTx post E fork, success", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -1434,7 +871,8 @@ func TestExportTxFees(t *testing.T) { return &cfg, chainTime }, - expectedError: nil, + unsignedAndSignedTx: exportTx, + expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { require.Equal(t, 3663*units.MicroAvax, fc.Fee) require.Equal(t, @@ -1449,7 +887,7 @@ func TestExportTxFees(t *testing.T) { }, }, { - description: "post E fork, utxos read cap breached", + description: "ExportTx post E fork, utxos read cap breached", cfgAndChainTimeF: func() (*config.Config, time.Time) { eForkTime := time.Now().Truncate(time.Second) chainTime := eForkTime.Add(time.Second) @@ -1465,8 +903,9 @@ func TestExportTxFees(t *testing.T) { caps[fees.UTXORead] = 1090 - 1 return caps }, - expectedError: errFailedConsumedUnitsCumulation, - checksF: func(t *testing.T, fc *Calculator) {}, + unsignedAndSignedTx: exportTx, + expectedError: errFailedConsumedUnitsCumulation, + checksF: func(t *testing.T, fc *Calculator) {}, }, } @@ -1479,6 +918,8 @@ func TestExportTxFees(t *testing.T) { consumedUnitCaps = tt.consumedUnitCapsF() } + uTx, sTx := tt.unsignedAndSignedTx(t) + fc := &Calculator{ IsEUpgradeActive: cfg.IsEUpgradeActivated(chainTime), Config: cfg, @@ -1494,6 +935,311 @@ func TestExportTxFees(t *testing.T) { } } +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) (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: ids.GenerateTestID(), + 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) (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: ids.GenerateTestID(), + 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, From 40031d04d6fd4c6dabcc7e41a104e83094fd8725 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 7 Feb 2024 10:36:29 +0100 Subject: [PATCH 009/120] minor dynamic fee builder refactoring in wallet --- wallet/chain/p/builder_dynamic_fees.go | 89 +++----------------- wallet/chain/p/builder_dynamic_fees_test.go | 90 ++++++++++++++++----- wallet/chain/p/wallet.go | 90 +++++++++++++++++---- 3 files changed, 155 insertions(+), 114 deletions(-) diff --git a/wallet/chain/p/builder_dynamic_fees.go b/wallet/chain/p/builder_dynamic_fees.go index 4e0f08e2bf3b..171feabc140b 100644 --- a/wallet/chain/p/builder_dynamic_fees.go +++ b/wallet/chain/p/builder_dynamic_fees.go @@ -39,7 +39,7 @@ func NewDynamicFeesBuilder(addrs set.Set[ids.ShortID], backend BuilderBackend) * func (b *DynamicFeesBuilder) NewBaseTx( outputs []*avax.TransferableOutput, - unitFees, unitCaps commonfees.Dimensions, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.BaseTx, error) { // 1. Build core transaction without utxos @@ -66,13 +66,6 @@ func (b *DynamicFeesBuilder) NewBaseTx( toBurn[assetID] = amountToBurn } - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } - // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.BaseTx(utx); err != nil { return nil, err @@ -93,7 +86,7 @@ func (b *DynamicFeesBuilder) NewBaseTx( func (b *DynamicFeesBuilder) NewAddSubnetValidatorTx( vdr *txs.SubnetValidator, - unitFees, unitCaps commonfees.Dimensions, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddSubnetValidatorTx, error) { ops := common.NewOptions(options) @@ -117,13 +110,6 @@ func (b *DynamicFeesBuilder) NewAddSubnetValidatorTx( toStake := map[ids.ID]uint64{} toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } - // update fees to account for the auth credentials to be added upon tx signing if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) @@ -148,7 +134,7 @@ func (b *DynamicFeesBuilder) NewAddSubnetValidatorTx( func (b *DynamicFeesBuilder) NewRemoveSubnetValidatorTx( nodeID ids.NodeID, subnetID ids.ID, - unitFees, unitCaps commonfees.Dimensions, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.RemoveSubnetValidatorTx, error) { ops := common.NewOptions(options) @@ -172,13 +158,6 @@ func (b *DynamicFeesBuilder) NewRemoveSubnetValidatorTx( toStake := map[ids.ID]uint64{} toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } - // update fees to account for the auth credentials to be added upon tx signing if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) @@ -206,7 +185,7 @@ func (b *DynamicFeesBuilder) NewCreateChainTx( vmID ids.ID, fxIDs []ids.ID, chainName string, - unitFees, unitCaps commonfees.Dimensions, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.CreateChainTx, error) { // 1. Build core transaction without utxos @@ -236,13 +215,6 @@ func (b *DynamicFeesBuilder) NewCreateChainTx( toStake := map[ids.ID]uint64{} toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } - // update fees to account for the auth credentials to be added upon tx signing if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) @@ -266,7 +238,7 @@ func (b *DynamicFeesBuilder) NewCreateChainTx( func (b *DynamicFeesBuilder) NewCreateSubnetTx( owner *secp256k1fx.OutputOwners, - unitFees, unitCaps commonfees.Dimensions, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.CreateSubnetTx, error) { // 1. Build core transaction without utxos @@ -285,13 +257,6 @@ func (b *DynamicFeesBuilder) NewCreateSubnetTx( toStake := map[ids.ID]uint64{} toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } - // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.CreateSubnetTx(utx); err != nil { return nil, err @@ -311,7 +276,7 @@ func (b *DynamicFeesBuilder) NewCreateSubnetTx( func (b *DynamicFeesBuilder) NewImportTx( sourceChainID ids.ID, to *secp256k1fx.OutputOwners, - unitFees, unitCaps commonfees.Dimensions, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.ImportTx, error) { ops := common.NewOptions(options) @@ -400,12 +365,6 @@ func (b *DynamicFeesBuilder) NewImportTx( } // 3. Finance fees as much as possible with imported, Avax-denominated UTXOs - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.ImportTx(utx); err != nil { @@ -484,7 +443,7 @@ func (b *DynamicFeesBuilder) NewImportTx( func (b *DynamicFeesBuilder) NewExportTx( chainID ids.ID, outputs []*avax.TransferableOutput, - unitFees, unitCaps commonfees.Dimensions, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.ExportTx, error) { // 1. Build core transaction without utxos @@ -513,13 +472,6 @@ func (b *DynamicFeesBuilder) NewExportTx( toBurn[assetID] = amountToBurn } - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } - // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.ExportTx(utx); err != nil { return nil, err @@ -551,7 +503,7 @@ func (b *DynamicFeesBuilder) NewTransformSubnetTx( minDelegatorStake uint64, maxValidatorWeightFactor byte, uptimeRequirement uint32, - unitFees, unitCaps commonfees.Dimensions, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.TransformSubnetTx, error) { // 1. Build core transaction without utxos @@ -591,13 +543,6 @@ func (b *DynamicFeesBuilder) NewTransformSubnetTx( assetID: maxSupply - initialSupply, } // fees are calculated in financeTx - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } - // update fees to account for the auth credentials to be added upon tx signing if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) @@ -626,7 +571,7 @@ func (b *DynamicFeesBuilder) NewAddPermissionlessValidatorTx( validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, shares uint32, - unitFees, unitCaps commonfees.Dimensions, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddPermissionlessValidatorTx, error) { ops := common.NewOptions(options) @@ -653,13 +598,6 @@ func (b *DynamicFeesBuilder) NewAddPermissionlessValidatorTx( } toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } - // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.AddPermissionlessValidatorTx(utx); err != nil { return nil, err @@ -681,7 +619,7 @@ func (b *DynamicFeesBuilder) NewAddPermissionlessDelegatorTx( vdr *txs.SubnetValidator, assetID ids.ID, rewardsOwner *secp256k1fx.OutputOwners, - unitFees, unitCaps commonfees.Dimensions, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddPermissionlessDelegatorTx, error) { ops := common.NewOptions(options) @@ -704,13 +642,6 @@ func (b *DynamicFeesBuilder) NewAddPermissionlessDelegatorTx( } toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - feesMan := commonfees.NewManager(unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: unitCaps, - } - // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.AddPermissionlessDelegatorTx(utx); err != nil { return nil, err diff --git a/wallet/chain/p/builder_dynamic_fees_test.go b/wallet/chain/p/builder_dynamic_fees_test.go index ec5570349d74..201aba6e7784 100644 --- a/wallet/chain/p/builder_dynamic_fees_test.go +++ b/wallet/chain/p/builder_dynamic_fees_test.go @@ -81,10 +81,15 @@ func TestBaseTx(t *testing.T) { be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + feesMan := commonfees.NewManager(testUnitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } utx, err := b.NewBaseTx( outputsToMove, - testUnitFees, - testBlockMaxConsumedUnits, + feeCalc, ) require.NoError(err) @@ -148,6 +153,12 @@ func TestAddSubnetValidatorTx(t *testing.T) { be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + feesMan := commonfees.NewManager(testUnitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } utx, err := b.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -156,8 +167,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { }, Subnet: subnetID, }, - testUnitFees, - testBlockMaxConsumedUnits, + feeCalc, ) require.NoError(err) @@ -222,11 +232,16 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + feesMan := commonfees.NewManager(testUnitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } utx, err := b.NewRemoveSubnetValidatorTx( ids.GenerateTestNodeID(), subnetID, - testUnitFees, - testBlockMaxConsumedUnits, + feeCalc, ) require.NoError(err) @@ -296,14 +311,19 @@ func TestCreateChainTx(t *testing.T) { be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + feesMan := commonfees.NewManager(testUnitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } utx, err := b.NewCreateChainTx( subnetID, genesisBytes, vmID, fxIDs, chainName, - testUnitFees, - testBlockMaxConsumedUnits, + feeCalc, ) require.NoError(err) @@ -364,10 +384,15 @@ func TestCreateSubnetTx(t *testing.T) { be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + feesMan := commonfees.NewManager(testUnitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } utx, err := b.NewCreateSubnetTx( subnetOwner, - testUnitFees, - testBlockMaxConsumedUnits, + feeCalc, ) require.NoError(err) @@ -433,11 +458,16 @@ func TestImportTx(t *testing.T) { be.EXPECT().UTXOs(gomock.Any(), sourceChainID).Return([]*avax.UTXO{importedUtxo}, nil) be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + feesMan := commonfees.NewManager(testUnitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } utx, err := b.NewImportTx( sourceChainID, importTo, - testUnitFees, - testBlockMaxConsumedUnits, + feeCalc, ) require.NoError(err) @@ -505,11 +535,16 @@ func TestExportTx(t *testing.T) { be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + feesMan := commonfees.NewManager(testUnitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } utx, err := b.NewExportTx( subnetID, exportedOutputs, - testUnitFees, - testBlockMaxConsumedUnits, + feeCalc, ) require.NoError(err) @@ -578,6 +613,12 @@ func TestTransformSubnetTx(t *testing.T) { maxSupply = 100 * units.MegaAvax ) + feesMan := commonfees.NewManager(testUnitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } utx, err := b.NewTransformSubnetTx( subnetID, subnetAssetID, @@ -593,8 +634,7 @@ func TestTransformSubnetTx(t *testing.T) { 1, // min delegator stake 5, // max validator weight factor .80*reward.PercentDenominator, // uptime requirement - testUnitFees, - testBlockMaxConsumedUnits, + feeCalc, ) require.NoError(err) @@ -666,6 +706,12 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + feesMan := commonfees.NewManager(testUnitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } utx, err := b.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -680,8 +726,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { validationRewardsOwner, delegationRewardsOwner, reward.PercentDenominator, - testUnitFees, - testBlockMaxConsumedUnits, + feeCalc, ) require.NoError(err) @@ -745,6 +790,12 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) + feesMan := commonfees.NewManager(testUnitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: feesMan, + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } utx, err := b.NewAddPermissionlessDelegatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -756,8 +807,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { }, avaxAssetID, rewardsOwner, - testUnitFees, - testBlockMaxConsumedUnits, + feeCalc, ) require.NoError(err) diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index af7bd7da13aa..07b7a8dfd695 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -11,14 +11,16 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/config" "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/fees" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var ( @@ -286,7 +288,7 @@ type wallet struct { isEForkActive bool builder Builder dynamicBuilder *DynamicFeesBuilder - unitFees, unitCaps fees.Dimensions + unitFees, unitCaps commonfees.Dimensions } func (w *wallet) Builder() Builder { @@ -310,7 +312,14 @@ func (w *wallet) IssueBaseTx( err error ) if w.isEForkActive { - utx, err = w.dynamicBuilder.NewBaseTx(outputs, w.unitFees, w.unitCaps, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + + utx, err = w.dynamicBuilder.NewBaseTx(outputs, feeCalc, options...) } else { utx, err = w.builder.NewBaseTx(outputs, options...) } @@ -346,7 +355,13 @@ func (w *wallet) IssueAddSubnetValidatorTx( err error ) if w.isEForkActive { - utx, err = w.dynamicBuilder.NewAddSubnetValidatorTx(vdr, w.unitFees, w.unitCaps, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + utx, err = w.dynamicBuilder.NewAddSubnetValidatorTx(vdr, feeCalc, options...) } else { utx, err = w.builder.NewAddSubnetValidatorTx(vdr, options...) } @@ -370,7 +385,13 @@ func (w *wallet) IssueRemoveSubnetValidatorTx( err error ) if w.isEForkActive { - utx, err = w.dynamicBuilder.NewRemoveSubnetValidatorTx(nodeID, subnetID, w.unitFees, w.unitCaps, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + utx, err = w.dynamicBuilder.NewRemoveSubnetValidatorTx(nodeID, subnetID, feeCalc, options...) } else { utx, err = w.builder.NewRemoveSubnetValidatorTx(nodeID, subnetID, options...) } @@ -409,7 +430,13 @@ func (w *wallet) IssueCreateChainTx( err error ) if w.isEForkActive { - utx, err = w.dynamicBuilder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, w.unitFees, w.unitCaps, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + utx, err = w.dynamicBuilder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, feeCalc, options...) } else { utx, err = w.builder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, options...) } @@ -432,7 +459,13 @@ func (w *wallet) IssueCreateSubnetTx( err error ) if w.isEForkActive { - utx, err = w.dynamicBuilder.NewCreateSubnetTx(owner, w.unitFees, w.unitCaps, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + utx, err = w.dynamicBuilder.NewCreateSubnetTx(owner, feeCalc, options...) } else { utx, err = w.builder.NewCreateSubnetTx(owner, options...) } @@ -469,7 +502,13 @@ func (w *wallet) IssueImportTx( err error ) if w.isEForkActive { - utx, err = w.dynamicBuilder.NewImportTx(sourceChainID, to, w.unitFees, w.unitCaps, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + utx, err = w.dynamicBuilder.NewImportTx(sourceChainID, to, feeCalc, options...) } else { utx, err = w.builder.NewImportTx(sourceChainID, to, options...) } @@ -493,7 +532,13 @@ func (w *wallet) IssueExportTx( err error ) if w.isEForkActive { - utx, err = w.dynamicBuilder.NewExportTx(chainID, outputs, w.unitFees, w.unitCaps, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + utx, err = w.dynamicBuilder.NewExportTx(chainID, outputs, feeCalc, options...) } else { utx, err = w.builder.NewExportTx(chainID, outputs, options...) } @@ -529,6 +574,12 @@ func (w *wallet) IssueTransformSubnetTx( err error ) if w.isEForkActive { + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } utx, err = w.dynamicBuilder.NewTransformSubnetTx( subnetID, assetID, @@ -544,8 +595,7 @@ func (w *wallet) IssueTransformSubnetTx( minDelegatorStake, maxValidatorWeightFactor, uptimeRequirement, - w.unitFees, - w.unitCaps, + feeCalc, options..., ) } else { @@ -591,6 +641,12 @@ func (w *wallet) IssueAddPermissionlessValidatorTx( err error ) if w.isEForkActive { + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } utx, err = w.dynamicBuilder.NewAddPermissionlessValidatorTx( vdr, signer, @@ -598,8 +654,7 @@ func (w *wallet) IssueAddPermissionlessValidatorTx( validationRewardsOwner, delegationRewardsOwner, shares, - w.unitFees, - w.unitCaps, + feeCalc, options..., ) } else { @@ -634,12 +689,17 @@ func (w *wallet) IssueAddPermissionlessDelegatorTx( err error ) if w.isEForkActive { + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } utx, err = w.dynamicBuilder.NewAddPermissionlessDelegatorTx( vdr, assetID, rewardsOwner, - w.unitFees, - w.unitCaps, + feeCalc, options..., ) } else { From 52c94dabc9a2ca7ffe390cb8304776998f7ec38b Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 7 Feb 2024 10:56:42 +0100 Subject: [PATCH 010/120] wip: consolidating dynamic fee builder code in wallet --- vms/components/fees/dimensions.go | 18 +- vms/platformvm/config/dynamic_fees_config.go | 9 +- wallet/chain/p/builder_dynamic_fees.go | 89 ++ wallet/chain/p/builder_dynamic_fees_test.go | 1399 ++++++++++++------ wallet/chain/p/wallet.go | 350 ++--- 5 files changed, 1230 insertions(+), 635 deletions(-) diff --git a/vms/components/fees/dimensions.go b/vms/components/fees/dimensions.go index 332f11b750f8..da8e4c8e31a3 100644 --- a/vms/components/fees/dimensions.go +++ b/vms/components/fees/dimensions.go @@ -3,7 +3,11 @@ package fees -import "github.com/ava-labs/avalanchego/utils/math" +import ( + "math" + + safemath "github.com/ava-labs/avalanchego/utils/math" +) const ( Bandwidth Dimension = 0 @@ -14,7 +18,15 @@ const ( FeeDimensions = 4 ) -var Empty = Dimensions{} +var ( + Empty = Dimensions{} + Max = Dimensions{ + math.MaxUint64, + math.MaxUint64, + math.MaxUint64, + math.MaxUint64, + } +) type ( Dimension int @@ -24,7 +36,7 @@ type ( func Add(lhs, rhs Dimensions) (Dimensions, error) { var res Dimensions for i := 0; i < FeeDimensions; i++ { - v, err := math.Add64(lhs[i], rhs[i]) + v, err := safemath.Add64(lhs[i], rhs[i]) if err != nil { return res, err } diff --git a/vms/platformvm/config/dynamic_fees_config.go b/vms/platformvm/config/dynamic_fees_config.go index d7994896c7da..4c4f58f97d0d 100644 --- a/vms/platformvm/config/dynamic_fees_config.go +++ b/vms/platformvm/config/dynamic_fees_config.go @@ -4,8 +4,6 @@ package config import ( - "math" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) @@ -25,12 +23,7 @@ var EUpgradeDynamicFeesConfig = DynamicFeesConfig{ 4, }, - BlockUnitsCap: commonfees.Dimensions{ - math.MaxUint64, - math.MaxUint64, - math.MaxUint64, - math.MaxUint64, - }, + BlockUnitsCap: commonfees.Max, } type DynamicFeesConfig struct { diff --git a/wallet/chain/p/builder_dynamic_fees.go b/wallet/chain/p/builder_dynamic_fees.go index 171feabc140b..093174549254 100644 --- a/wallet/chain/p/builder_dynamic_fees.go +++ b/wallet/chain/p/builder_dynamic_fees.go @@ -37,6 +37,46 @@ func NewDynamicFeesBuilder(addrs set.Set[ids.ShortID], backend BuilderBackend) * } } +func (b *DynamicFeesBuilder) newBaseTxPreEUpgrade( + outputs []*avax.TransferableOutput, + feeCalc *fees.Calculator, + options ...common.Option, +) (*txs.CreateSubnetTx, error) { + // 1. Build core transaction without utxos + ops := common.NewOptions(options) + + utx := &txs.CreateSubnetTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Outs: outputs, // not sorted yet, we'll sort later on when we have all the outputs + Memo: ops.Memo(), + }}, + Owner: &secp256k1fx.OutputOwners{}, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.CreateSubnetTx(utx); err != nil { + return nil, err + } + + inputs, changeOutputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + outputs = append(outputs, changeOutputs...) + avax.SortTransferableOutputs(outputs, txs.Codec) // sort the outputs + + utx.Ins = inputs + utx.Outs = outputs + + return utx, initCtx(b.backend, utx) +} + func (b *DynamicFeesBuilder) NewBaseTx( outputs []*avax.TransferableOutput, feeCalc *fees.Calculator, @@ -273,6 +313,55 @@ func (b *DynamicFeesBuilder) NewCreateSubnetTx( return utx, initCtx(b.backend, utx) } +func (b *DynamicFeesBuilder) NewTransferSubnetOwnershipTx( + subnetID ids.ID, + owner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, + options ...common.Option, +) (*txs.TransferSubnetOwnershipTx, error) { + // 1. Build core transaction without utxos + ops := common.NewOptions(options) + subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) + if err != nil { + return nil, err + } + + utils.Sort(owner.Addrs) + utx := &txs.TransferSubnetOwnershipTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + SubnetAuth: subnetAuth, + Owner: owner, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // update fees to account for the auth credentials to be added upon tx signing + if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.TransferSubnetOwnershipTx(utx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + + return utx, initCtx(b.backend, utx) +} + func (b *DynamicFeesBuilder) NewImportTx( sourceChainID ids.ID, to *secp256k1fx.OutputOwners, diff --git a/wallet/chain/p/builder_dynamic_fees_test.go b/wallet/chain/p/builder_dynamic_fees_test.go index 201aba6e7784..521a0670b62c 100644 --- a/wallet/chain/p/builder_dynamic_fees_test.go +++ b/wallet/chain/p/builder_dynamic_fees_test.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "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/fx" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/signer" @@ -71,56 +72,97 @@ func TestBaseTx(t *testing.T) { }, }, }} + + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) ) + // set expectations + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil).AnyTimes() + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + b := &DynamicFeesBuilder{ addrs: set.Of(utxoAddr), backend: be, } - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - feesMan := commonfees.NewManager(testUnitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - } - utx, err := b.NewBaseTx( - outputsToMove, - feeCalc, - ) - require.NoError(err) + { // Post E-Upgrade + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + utx, err := b.NewBaseTx( + outputsToMove, + feeCalc, + ) + require.NoError(err) - var ( - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) - ) + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5930*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 2) + require.Equal(fc.Fee+outputsToMove[0].Out.Amount(), ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + require.Equal(outputsToMove[0], outs[1]) } - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) + { // Pre E-Upgrade + fee := 3 * units.Avax + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + CreateSubnetTxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + utx, err := b.newBaseTxPreEUpgrade( + outputsToMove, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + CreateSubnetTxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(fee, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 2) - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, - } - require.NoError(utx.Visit(fc)) - require.Equal(5930*units.MicroAvax, fc.Fee) - - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 2) - require.Len(outs, 2) - require.Equal(fc.Fee+outputsToMove[0].Out.Amount(), ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) - require.Equal(outputsToMove[0], outs[1]) + // Note: not using outputsToMove to pay fees. + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + require.Equal(outputsToMove[0], outs[1]) + } } func TestAddSubnetValidatorTx(t *testing.T) { @@ -142,63 +184,99 @@ func TestAddSubnetValidatorTx(t *testing.T) { Addrs: []ids.ShortID{subnetAuthKey.PublicKey().Address()}, }, ) - ) - - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, subnetAuthAddr), - backend: be, - } - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) - - feesMan := commonfees.NewManager(testUnitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - } - utx, err := b.NewAddSubnetValidatorTx( - &txs.SubnetValidator{ + subnetValidator = &txs.SubnetValidator{ Validator: txs.Validator{ NodeID: ids.GenerateTestNodeID(), End: uint64(time.Now().Add(time.Hour).Unix()), }, Subnet: subnetID, - }, - feeCalc, - ) - require.NoError(err) + } - var ( kc = secp256k1fx.NewKeychain(utxosKey) sbe = mocks.NewMockSignerBackend(ctrl) s = NewSigner(kc, sbe) ) + // set expectations + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil).AnyTimes() + be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() for _, utxo := range utxos { sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() } - sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, subnetAuthAddr), + backend: be, + } + + { // Post E-Upgrade + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + utx, err := b.NewAddSubnetValidatorTx(subnetValidator, feeCalc) + require.NoError(err) - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + Config: &config.Config{ + AddSubnetValidatorFee: units.MilliAvax, + }, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5765*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) } - require.NoError(utx.Visit(fc)) - require.Equal(5765*units.MicroAvax, fc.Fee) - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 2) - require.Len(outs, 1) - require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + { // Pre E-Upgrade + fee := units.MilliAvax + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + AddSubnetValidatorFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + utx, err := b.NewAddSubnetValidatorTx(subnetValidator, feeCalc) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + AddSubnetValidatorFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(fee, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 1) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()-outs[0].Out.Amount()) + } } func TestRemoveSubnetValidatorTx(t *testing.T) { @@ -221,58 +299,97 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { Addrs: []ids.ShortID{subnetAuthKey.PublicKey().Address()}, }, ) - ) - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, subnetAuthAddr), - backend: be, - } - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) - - feesMan := commonfees.NewManager(testUnitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - } - utx, err := b.NewRemoveSubnetValidatorTx( - ids.GenerateTestNodeID(), - subnetID, - feeCalc, - ) - require.NoError(err) - - var ( kc = secp256k1fx.NewKeychain(utxosKey) sbe = mocks.NewMockSignerBackend(ctrl) s = NewSigner(kc, sbe) ) + // set expectations + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil).AnyTimes() + be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() for _, utxo := range utxos { sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() } - sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, subnetAuthAddr), + backend: be, + } + + { // Post E-Upgrade + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + utx, err := b.NewRemoveSubnetValidatorTx( + ids.GenerateTestNodeID(), + subnetID, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5741*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) } - require.NoError(utx.Visit(fc)) - require.Equal(5741*units.MicroAvax, fc.Fee) - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 2) - require.Len(outs, 1) - require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + { // Pre E-Upgrade + fee := units.MilliAvax + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + TxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + utx, err := b.NewRemoveSubnetValidatorTx( + ids.GenerateTestNodeID(), + subnetID, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + TxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(fee, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 1) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()-outs[0].Out.Amount()) + } } func TestCreateChainTx(t *testing.T) { @@ -297,64 +414,103 @@ func TestCreateChainTx(t *testing.T) { Addrs: []ids.ShortID{subnetAuthKey.PublicKey().Address()}, }, ) - ) - - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, subnetAuthAddr), - backend: be, - } - - be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) - - utxos, avaxAssetID, _ := testUTXOsList(utxosKey) - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - - feesMan := commonfees.NewManager(testUnitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - } - utx, err := b.NewCreateChainTx( - subnetID, - genesisBytes, - vmID, - fxIDs, - chainName, - feeCalc, - ) - require.NoError(err) + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) - var ( kc = secp256k1fx.NewKeychain(utxosKey) sbe = mocks.NewMockSignerBackend(ctrl) s = NewSigner(kc, sbe) ) + // set expectations + be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil).AnyTimes() for _, utxo := range utxos { sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() } - sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) + sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, subnetAuthAddr), + backend: be, + } - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + { // Post E-Upgrade + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + utx, err := b.NewCreateChainTx( + subnetID, + genesisBytes, + vmID, + fxIDs, + chainName, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5808*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) } - require.NoError(utx.Visit(fc)) - require.Equal(5808*units.MicroAvax, fc.Fee) - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 2) - require.Len(outs, 1) - require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + { // Pre E-Upgrade + fee := 1234 * units.MicroAvax + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + CreateBlockchainTxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + utx, err := b.NewCreateChainTx( + subnetID, + genesisBytes, + vmID, + fxIDs, + chainName, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + CreateBlockchainTxFee: fee, + }, + ConsumedUnitsCap: commonfees.Max, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(fee, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 1) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()-outs[0].Out.Amount()) + } } func TestCreateSubnetTx(t *testing.T) { @@ -374,55 +530,204 @@ func TestCreateSubnetTx(t *testing.T) { subnetAuthKey.Address(), }, } + + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) ) + // setup expectations + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil).AnyTimes() + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + b := &DynamicFeesBuilder{ addrs: set.Of(utxoAddr), backend: be, } - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - feesMan := commonfees.NewManager(testUnitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: testBlockMaxConsumedUnits, + { // Post E-Upgrade + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + utx, err := b.NewCreateSubnetTx( + subnetOwner, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5644*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) } - utx, err := b.NewCreateSubnetTx( - subnetOwner, - feeCalc, - ) - require.NoError(err) + + { // Pre E-Upgrade + fee := 4567 * units.MicroAvax + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + CreateSubnetTxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + utx, err := b.NewCreateSubnetTx( + subnetOwner, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + CreateSubnetTxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(fee, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + } +} + +func TestTransferSubnetOwnershipTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + be := mocks.NewMockBuilderBackend(ctrl) var ( + subnetAuthKey = testKeys[0] + utxosKey = testKeys[1] + utxoAddr = utxosKey.PublicKey().Address() + utxos, avaxAssetID, _ = testUTXOsList(utxosKey) + subnetID = ids.GenerateTestID() + subnetOwner = &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + subnetAuthKey.Address(), + }, + } + kc = secp256k1fx.NewKeychain(utxosKey) sbe = mocks.NewMockSignerBackend(ctrl) s = NewSigner(kc, sbe) ) + // setup expectations + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil).AnyTimes() for _, utxo := range utxos { sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() } + sbe.EXPECT().GetSubnetOwner(gomock.Any(), gomock.Any()).Return(subnetOwner, nil).AnyTimes() - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr, subnetAuthKey.Address()), + backend: be, + } + + { // Post E-Upgrade + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + utx, err := b.NewTransferSubnetOwnershipTx( + subnetID, + subnetOwner, + feeCalc, + ) + require.NoError(err) - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5761*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) } - require.NoError(utx.Visit(fc)) - require.Equal(5644*units.MicroAvax, fc.Fee) - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 2) - require.Len(outs, 1) - require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + { // Pre E-Upgrade + fee := 4567 * units.MicroAvax + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + TxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + utx, err := b.NewTransferSubnetOwnershipTx( + subnetID, + subnetOwner, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + TxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(fee, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + } } func TestImportTx(t *testing.T) { @@ -444,63 +749,104 @@ func TestImportTx(t *testing.T) { importKey.Address(), }, } + + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) ) importedUtxo := utxos[0] utxos = utxos[1:] + // setup expectations + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), sourceChainID).Return([]*avax.UTXO{importedUtxo}, nil).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil).AnyTimes() + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), importedUtxo.InputID()).Return(importedUtxo, nil).AnyTimes() + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + b := &DynamicFeesBuilder{ addrs: set.Of(utxoAddr), backend: be, } - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), sourceChainID).Return([]*avax.UTXO{importedUtxo}, nil) - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - - feesMan := commonfees.NewManager(testUnitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - } - utx, err := b.NewImportTx( - sourceChainID, - importTo, - feeCalc, - ) - require.NoError(err) - var ( - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) - ) + { // Post E-Upgrade + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + utx, err := b.NewImportTx( + sourceChainID, + importTo, + feeCalc, + ) + require.NoError(err) - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), importedUtxo.InputID()).Return(importedUtxo, nil).AnyTimes() - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5640*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + importedIns := utx.ImportedInputs + require.Len(ins, 1) + require.Len(importedIns, 1) + require.Len(outs, 1) + require.Equal(fc.Fee, importedIns[0].In.Amount()+ins[0].In.Amount()-outs[0].Out.Amount()) } - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) + { // Pre E-Upgrade + fee := 7890 * units.MicroAvax + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + TxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + utx, err := b.NewImportTx( + sourceChainID, + importTo, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, - } - require.NoError(utx.Visit(fc)) - require.Equal(5640*units.MicroAvax, fc.Fee) - - ins := utx.Ins - outs := utx.Outs - importedIns := utx.ImportedInputs - require.Len(ins, 1) - require.Len(importedIns, 1) - require.Len(outs, 1) - require.Equal(fc.Fee, importedIns[0].In.Amount()+ins[0].In.Amount()-outs[0].Out.Amount()) + fc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + TxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(fee, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + importedIns := utx.ImportedInputs + require.Len(ins, 1) + require.Len(importedIns, 1) + require.Len(outs, 1) + require.Equal(fc.Fee, importedIns[0].In.Amount()+ins[0].In.Amount()-outs[0].Out.Amount()) + } } func TestExportTx(t *testing.T) { @@ -525,57 +871,97 @@ func TestExportTx(t *testing.T) { }, }, }} - ) - - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr), - backend: be, - } - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - - feesMan := commonfees.NewManager(testUnitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - } - utx, err := b.NewExportTx( - subnetID, - exportedOutputs, - feeCalc, - ) - require.NoError(err) - var ( kc = secp256k1fx.NewKeychain(utxosKey) sbe = mocks.NewMockSignerBackend(ctrl) s = NewSigner(kc, sbe) ) + // setup expectation + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil).AnyTimes() for _, utxo := range utxos { sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() } - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) + b := &DynamicFeesBuilder{ + addrs: set.Of(utxoAddr), + backend: be, + } + + { // Post E-Upgrade + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + utx, err := b.NewExportTx( + subnetID, + exportedOutputs, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, - } - require.NoError(utx.Visit(fc)) - require.Equal(5966*units.MicroAvax, fc.Fee) - - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 2) - require.Len(outs, 1) - require.Equal(fc.Fee+exportedOutputs[0].Out.Amount(), ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) - require.Equal(utx.ExportedOutputs, exportedOutputs) + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(5966*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee+exportedOutputs[0].Out.Amount(), ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + require.Equal(utx.ExportedOutputs, exportedOutputs) + } + + { // Pre E-Upgrade + fee := 12 * units.MilliAvax + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + TxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + utx, err := b.NewExportTx( + subnetID, + exportedOutputs, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + TxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(fee, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 2) + require.Len(outs, 1) + require.Equal(fc.Fee+exportedOutputs[0].Out.Amount(), ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) + require.Equal(utx.ExportedOutputs, exportedOutputs) + } } func TestTransformSubnetTx(t *testing.T) { @@ -597,76 +983,125 @@ func TestTransformSubnetTx(t *testing.T) { Addrs: []ids.ShortID{subnetAuthKey.PublicKey().Address()}, }, ) + + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) + + initialSupply = 40 * units.MegaAvax + maxSupply = 100 * units.MegaAvax ) + be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil).AnyTimes() + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() + b := &DynamicFeesBuilder{ addrs: set.Of(utxoAddr, subnetAuthAddr), backend: be, } - be.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - - var ( - initialSupply = 40 * units.MegaAvax - maxSupply = 100 * units.MegaAvax - ) - feesMan := commonfees.NewManager(testUnitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - } - utx, err := b.NewTransformSubnetTx( - subnetID, - subnetAssetID, - initialSupply, // initial supply - maxSupply, // max supply - reward.PercentDenominator, // min consumption rate - reward.PercentDenominator, // max consumption rate - 1, // min validator stake - 100*units.MegaAvax, // max validator stake - time.Second, // min stake duration - 365*24*time.Hour, // max stake duration - 0, // min delegation fee - 1, // min delegator stake - 5, // max validator weight factor - .80*reward.PercentDenominator, // uptime requirement - feeCalc, - ) - require.NoError(err) + { // Post E-Upgrade + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + utx, err := b.NewTransformSubnetTx( + subnetID, + subnetAssetID, + initialSupply, // initial supply + maxSupply, // max supply + reward.PercentDenominator, // min consumption rate + reward.PercentDenominator, // max consumption rate + 1, // min validator stake + 100*units.MegaAvax, // max validator stake + time.Second, // min stake duration + 365*24*time.Hour, // max stake duration + 0, // min delegation fee + 1, // min delegator stake + 5, // max validator weight factor + .80*reward.PercentDenominator, // uptime requirement + feeCalc, + ) + require.NoError(err) - var ( - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) - ) + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(8763*units.MicroAvax, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 3) + require.Len(outs, 2) + require.Equal(maxSupply-initialSupply, ins[0].In.Amount()-outs[0].Out.Amount()) + require.Equal(fc.Fee, ins[1].In.Amount()+ins[2].In.Amount()-outs[1].Out.Amount()) } - sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil) - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) + { // Pre E-Upgrade + fee := 200 * units.MilliAvax + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + TransformSubnetTxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + utx, err := b.NewTransformSubnetTx( + subnetID, + subnetAssetID, + initialSupply, // initial supply + maxSupply, // max supply + reward.PercentDenominator, // min consumption rate + reward.PercentDenominator, // max consumption rate + 1, // min validator stake + 100*units.MegaAvax, // max validator stake + time.Second, // min stake duration + 365*24*time.Hour, // max stake duration + 0, // min delegation fee + 1, // min delegator stake + 5, // max validator weight factor + .80*reward.PercentDenominator, // uptime requirement + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, - } - require.NoError(utx.Visit(fc)) - require.Equal(8763*units.MicroAvax, fc.Fee) - - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 3) - require.Len(outs, 2) - require.Equal(maxSupply-initialSupply, ins[0].In.Amount()-outs[0].Out.Amount()) - require.Equal(fc.Fee, ins[1].In.Amount()+ins[2].In.Amount()-outs[1].Out.Amount()) + fc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + TransformSubnetTxFee: fee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(fee, fc.Fee) + + ins := utx.Ins + outs := utx.Outs + require.Len(ins, 3) + require.Len(outs, 2) + require.Equal(maxSupply-initialSupply, ins[0].In.Amount()-outs[0].Out.Amount()) + require.Equal(fc.Fee, ins[1].In.Amount()+ins[2].In.Amount()-outs[1].Out.Amount()) + } } func TestAddPermissionlessValidatorTx(t *testing.T) { @@ -693,73 +1128,129 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { rewardKey.Address(), }, } + + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) ) sk, err := bls.NewSecretKey() require.NoError(err) + // setup expectations + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil).AnyTimes() + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + b := &DynamicFeesBuilder{ addrs: set.Of(utxoAddr, rewardAddr), backend: be, } - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - feesMan := commonfees.NewManager(testUnitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - } - utx, err := b.NewAddPermissionlessValidatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: ids.GenerateTestNodeID(), - End: uint64(time.Now().Add(time.Hour).Unix()), - Wght: 2 * units.Avax, + { // Post E-Upgrade + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + utx, err := b.NewAddPermissionlessValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(time.Now().Add(time.Hour).Unix()), + Wght: 2 * units.Avax, + }, + Subnet: constants.PrimaryNetworkID, }, - Subnet: constants.PrimaryNetworkID, - }, - signer.NewProofOfPossession(sk), - avaxAssetID, - validationRewardsOwner, - delegationRewardsOwner, - reward.PercentDenominator, - feeCalc, - ) - require.NoError(err) + signer.NewProofOfPossession(sk), + avaxAssetID, + validationRewardsOwner, + delegationRewardsOwner, + reward.PercentDenominator, + feeCalc, + ) + require.NoError(err) - var ( - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) - ) + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(12404*units.MicroAvax, fc.Fee) + + ins := utx.Ins + staked := utx.StakeOuts + outs := utx.Outs + require.Len(ins, 4) + require.Len(staked, 2) + require.Len(outs, 2) + require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) + require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) } - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) + { // Pre E-Upgrade + primaryValFee := 789 * units.MilliAvax + subnetValFee := 1 * units.Avax + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + AddPrimaryNetworkValidatorFee: primaryValFee, + AddSubnetValidatorFee: subnetValFee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + utx, err := b.NewAddPermissionlessValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(time.Now().Add(time.Hour).Unix()), + Wght: 2 * units.Avax, + }, + Subnet: constants.PrimaryNetworkID, + }, + signer.NewProofOfPossession(sk), + avaxAssetID, + validationRewardsOwner, + delegationRewardsOwner, + reward.PercentDenominator, + feeCalc, + ) + require.NoError(err) - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, - } - require.NoError(utx.Visit(fc)) - require.Equal(12404*units.MicroAvax, fc.Fee) - - ins := utx.Ins - staked := utx.StakeOuts - outs := utx.Outs - require.Len(ins, 4) - require.Len(staked, 2) - require.Len(outs, 2) - require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) - require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) + + fc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + AddPrimaryNetworkValidatorFee: primaryValFee, + AddSubnetValidatorFee: subnetValFee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(primaryValFee, fc.Fee) + + ins := utx.Ins + staked := utx.StakeOuts + outs := utx.Outs + require.Len(ins, 4) + require.Len(staked, 2) + require.Len(outs, 2) + require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) + require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) + } } func TestAddPermissionlessDelegatorTx(t *testing.T) { @@ -780,67 +1271,119 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { rewardKey.Address(), }, } + + kc = secp256k1fx.NewKeychain(utxosKey) + sbe = mocks.NewMockSignerBackend(ctrl) + s = NewSigner(kc, sbe) ) + be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() + be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() + be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil).AnyTimes() + for _, utxo := range utxos { + sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + } + b := &DynamicFeesBuilder{ addrs: set.Of(utxoAddr, rewardAddr), backend: be, } - be.EXPECT().AVAXAssetID().Return(avaxAssetID).AnyTimes() - be.EXPECT().NetworkID().Return(constants.MainnetID).AnyTimes() - be.EXPECT().UTXOs(gomock.Any(), constants.PlatformChainID).Return(utxos, nil) - feesMan := commonfees.NewManager(testUnitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: feesMan, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - } - utx, err := b.NewAddPermissionlessDelegatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: ids.GenerateTestNodeID(), - End: uint64(time.Now().Add(time.Hour).Unix()), - Wght: 2 * units.Avax, + { // Post E-Upgrade + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + } + utx, err := b.NewAddPermissionlessDelegatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(time.Now().Add(time.Hour).Unix()), + Wght: 2 * units.Avax, + }, + Subnet: constants.PrimaryNetworkID, }, - Subnet: constants.PrimaryNetworkID, - }, - avaxAssetID, - rewardsOwner, - feeCalc, - ) - require.NoError(err) + avaxAssetID, + rewardsOwner, + feeCalc, + ) + require.NoError(err) - var ( - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) - ) + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() + fc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + ConsumedUnitsCap: testBlockMaxConsumedUnits, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(12212*units.MicroAvax, fc.Fee) + + ins := utx.Ins + staked := utx.StakeOuts + outs := utx.Outs + require.Len(ins, 4) + require.Len(staked, 2) + require.Len(outs, 2) + require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) + require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) } - tx, err := s.SignUnsigned(stdcontext.Background(), utx) - require.NoError(err) + { // Pre E-Upgrade + primaryDelegatorFee := 7 * units.Avax + subnetDelegatorFee := 77 * units.Avax + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + AddPrimaryNetworkDelegatorFee: primaryDelegatorFee, + AddSubnetDelegatorFee: subnetDelegatorFee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + utx, err := b.NewAddPermissionlessDelegatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(time.Now().Add(time.Hour).Unix()), + Wght: 2 * units.Avax, + }, + Subnet: constants.PrimaryNetworkID, + }, + avaxAssetID, + rewardsOwner, + feeCalc, + ) + require.NoError(err) + + tx, err := s.SignUnsigned(stdcontext.Background(), utx) + require.NoError(err) - fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, - } - require.NoError(utx.Visit(fc)) - require.Equal(12212*units.MicroAvax, fc.Fee) - - ins := utx.Ins - staked := utx.StakeOuts - outs := utx.Outs - require.Len(ins, 4) - require.Len(staked, 2) - require.Len(outs, 2) - require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) - require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) + fc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: &config.Config{ + AddPrimaryNetworkDelegatorFee: primaryDelegatorFee, + AddSubnetDelegatorFee: subnetDelegatorFee, + }, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + Credentials: tx.Creds, + } + require.NoError(utx.Visit(fc)) + require.Equal(primaryDelegatorFee, fc.Fee) + + ins := utx.Ins + staked := utx.StakeOuts + outs := utx.Outs + require.Len(ins, 4) + require.Len(staked, 2) + require.Len(outs, 2) + require.Equal(utx.Validator.Weight(), staked[0].Out.Amount()+staked[1].Out.Amount()) + require.Equal(fc.Fee, ins[1].In.Amount()+ins[3].In.Amount()-outs[0].Out.Amount()) + } } func testUTXOsList(utxosKey *secp256k1.PrivateKey) ( diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 07b7a8dfd695..4a486d8a28ac 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -273,8 +273,6 @@ func NewWallet( Backend: backend, builder: builder, dynamicBuilder: dynFeesBuilder, - unitFees: config.EUpgradeDynamicFeesConfig.UnitFees, - unitCaps: config.EUpgradeDynamicFeesConfig.BlockUnitsCap, signer: signer, client: client, } @@ -310,18 +308,21 @@ func (w *wallet) IssueBaseTx( var ( utx txs.UnsignedTx err error - ) - if w.isEForkActive { - feesMan := commonfees.NewManager(w.unitFees) - feeCalc := &fees.Calculator{ + + feesMan = commonfees.NewManager(w.unitFees) + feeCalc = &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + CreateSubnetTxFee: w.CreateSubnetTxFee(), + }, FeeManager: feesMan, ConsumedUnitsCap: w.unitCaps, } - + ) + if w.isEForkActive { utx, err = w.dynamicBuilder.NewBaseTx(outputs, feeCalc, options...) } else { - utx, err = w.builder.NewBaseTx(outputs, options...) + utx, err = w.dynamicBuilder.newBaseTxPreEUpgrade(outputs, feeCalc, options...) } if err != nil { return nil, err @@ -350,21 +351,17 @@ func (w *wallet) IssueAddSubnetValidatorTx( return nil, err } - var ( - utx txs.UnsignedTx - err error - ) - if w.isEForkActive { - feesMan := commonfees.NewManager(w.unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, - } - utx, err = w.dynamicBuilder.NewAddSubnetValidatorTx(vdr, feeCalc, options...) - } else { - utx, err = w.builder.NewAddSubnetValidatorTx(vdr, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + TxFee: w.BaseTxFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, } + + utx, err := w.dynamicBuilder.NewAddSubnetValidatorTx(vdr, feeCalc, options...) if err != nil { return nil, err } @@ -380,21 +377,17 @@ func (w *wallet) IssueRemoveSubnetValidatorTx( return nil, err } - var ( - utx txs.UnsignedTx - err error - ) - if w.isEForkActive { - feesMan := commonfees.NewManager(w.unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, - } - utx, err = w.dynamicBuilder.NewRemoveSubnetValidatorTx(nodeID, subnetID, feeCalc, options...) - } else { - utx, err = w.builder.NewRemoveSubnetValidatorTx(nodeID, subnetID, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + TxFee: w.BaseTxFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, } + + utx, err := w.dynamicBuilder.NewRemoveSubnetValidatorTx(nodeID, subnetID, feeCalc, options...) if err != nil { return nil, err } @@ -425,21 +418,17 @@ func (w *wallet) IssueCreateChainTx( return nil, err } - var ( - utx txs.UnsignedTx - err error - ) - if w.isEForkActive { - feesMan := commonfees.NewManager(w.unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, - } - utx, err = w.dynamicBuilder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, feeCalc, options...) - } else { - utx, err = w.builder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + CreateBlockchainTxFee: w.CreateBlockchainTxFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, } + + utx, err := w.dynamicBuilder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, feeCalc, options...) if err != nil { return nil, err } @@ -454,21 +443,16 @@ func (w *wallet) IssueCreateSubnetTx( return nil, err } - var ( - utx txs.UnsignedTx - err error - ) - if w.isEForkActive { - feesMan := commonfees.NewManager(w.unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, - } - utx, err = w.dynamicBuilder.NewCreateSubnetTx(owner, feeCalc, options...) - } else { - utx, err = w.builder.NewCreateSubnetTx(owner, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + CreateSubnetTxFee: w.CreateSubnetTxFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, } + utx, err := w.dynamicBuilder.NewCreateSubnetTx(owner, feeCalc, options...) if err != nil { return nil, err } @@ -481,7 +465,21 @@ func (w *wallet) IssueTransferSubnetOwnershipTx( owner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewTransferSubnetOwnershipTx(subnetID, owner, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + TxFee: w.BaseTxFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + + utx, err := w.dynamicBuilder.NewTransferSubnetOwnershipTx(subnetID, owner, feeCalc, options...) if err != nil { return nil, err } @@ -497,21 +495,17 @@ func (w *wallet) IssueImportTx( return nil, err } - var ( - utx txs.UnsignedTx - err error - ) - if w.isEForkActive { - feesMan := commonfees.NewManager(w.unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, - } - utx, err = w.dynamicBuilder.NewImportTx(sourceChainID, to, feeCalc, options...) - } else { - utx, err = w.builder.NewImportTx(sourceChainID, to, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + TxFee: w.BaseTxFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, } + + utx, err := w.dynamicBuilder.NewImportTx(sourceChainID, to, feeCalc, options...) if err != nil { return nil, err } @@ -527,21 +521,17 @@ func (w *wallet) IssueExportTx( return nil, err } - var ( - utx txs.UnsignedTx - err error - ) - if w.isEForkActive { - feesMan := commonfees.NewManager(w.unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, - } - utx, err = w.dynamicBuilder.NewExportTx(chainID, outputs, feeCalc, options...) - } else { - utx, err = w.builder.NewExportTx(chainID, outputs, options...) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + TxFee: w.BaseTxFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, } + + utx, err := w.dynamicBuilder.NewExportTx(chainID, outputs, feeCalc, options...) if err != nil { return nil, err } @@ -569,54 +559,33 @@ func (w *wallet) IssueTransformSubnetTx( return nil, err } - var ( - utx txs.UnsignedTx - err error + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + TransformSubnetTxFee: w.TransformSubnetTxFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + utx, err := w.dynamicBuilder.NewTransformSubnetTx( + subnetID, + assetID, + initialSupply, + maxSupply, + minConsumptionRate, + maxConsumptionRate, + minValidatorStake, + maxValidatorStake, + minStakeDuration, + maxStakeDuration, + minDelegationFee, + minDelegatorStake, + maxValidatorWeightFactor, + uptimeRequirement, + feeCalc, + options..., ) - if w.isEForkActive { - feesMan := commonfees.NewManager(w.unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, - } - utx, err = w.dynamicBuilder.NewTransformSubnetTx( - subnetID, - assetID, - initialSupply, - maxSupply, - minConsumptionRate, - maxConsumptionRate, - minValidatorStake, - maxValidatorStake, - minStakeDuration, - maxStakeDuration, - minDelegationFee, - minDelegatorStake, - maxValidatorWeightFactor, - uptimeRequirement, - feeCalc, - options..., - ) - } else { - utx, err = w.builder.NewTransformSubnetTx( - subnetID, - assetID, - initialSupply, - maxSupply, - minConsumptionRate, - maxConsumptionRate, - minValidatorStake, - maxValidatorStake, - minStakeDuration, - maxStakeDuration, - minDelegationFee, - minDelegatorStake, - maxValidatorWeightFactor, - uptimeRequirement, - options..., - ) - } if err != nil { return nil, err } @@ -636,38 +605,27 @@ func (w *wallet) IssueAddPermissionlessValidatorTx( return nil, err } - var ( - utx txs.UnsignedTx - err error + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + AddPrimaryNetworkValidatorFee: w.AddPrimaryNetworkValidatorFee(), + AddSubnetValidatorFee: w.AddSubnetValidatorFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + + utx, err := w.dynamicBuilder.NewAddPermissionlessValidatorTx( + vdr, + signer, + assetID, + validationRewardsOwner, + delegationRewardsOwner, + shares, + feeCalc, + options..., ) - if w.isEForkActive { - feesMan := commonfees.NewManager(w.unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, - } - utx, err = w.dynamicBuilder.NewAddPermissionlessValidatorTx( - vdr, - signer, - assetID, - validationRewardsOwner, - delegationRewardsOwner, - shares, - feeCalc, - options..., - ) - } else { - utx, err = w.builder.NewAddPermissionlessValidatorTx( - vdr, - signer, - assetID, - validationRewardsOwner, - delegationRewardsOwner, - shares, - options..., - ) - } if err != nil { return nil, err } @@ -684,32 +642,24 @@ func (w *wallet) IssueAddPermissionlessDelegatorTx( return nil, err } - var ( - utx txs.UnsignedTx - err error - ) - if w.isEForkActive { - feesMan := commonfees.NewManager(w.unitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, - } - utx, err = w.dynamicBuilder.NewAddPermissionlessDelegatorTx( - vdr, - assetID, - rewardsOwner, - feeCalc, - options..., - ) - } else { - utx, err = w.builder.NewAddPermissionlessDelegatorTx( - vdr, - assetID, - rewardsOwner, - options..., - ) + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + AddPrimaryNetworkDelegatorFee: w.AddPrimaryNetworkDelegatorFee(), + AddSubnetDelegatorFee: w.AddSubnetDelegatorFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, } + + utx, err := w.dynamicBuilder.NewAddPermissionlessDelegatorTx( + vdr, + assetID, + rewardsOwner, + feeCalc, + options..., + ) if err != nil { return nil, err } @@ -783,5 +733,13 @@ func (w *wallet) refreshFork(options ...common.Option) error { } w.isEForkActive = !chainTime.Before(eForkTime) + if w.isEForkActive { + w.unitFees = config.EUpgradeDynamicFeesConfig.UnitFees + w.unitCaps = config.EUpgradeDynamicFeesConfig.BlockUnitsCap + } else { + w.unitFees = commonfees.Empty + w.unitCaps = commonfees.Max + } + return nil } From 8bbc897cc2af9a5e3d9b5f574444bb4712af2114 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 7 Feb 2024 21:27:49 +0100 Subject: [PATCH 011/120] merged dynamic builder into builder --- wallet/chain/p/builder.go | 871 +++++++++---- wallet/chain/p/builder_dynamic_fees.go | 1090 ----------------- ...amic_fees_test.go => builder_fees_test.go} | 55 +- wallet/chain/p/builder_with_options.go | 25 + wallet/chain/p/wallet.go | 67 +- wallet/subnet/primary/wallet.go | 3 +- 6 files changed, 705 insertions(+), 1406 deletions(-) delete mode 100644 wallet/chain/p/builder_dynamic_fees.go rename wallet/chain/p/{builder_dynamic_fees_test.go => builder_fees_test.go} (97%) diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index f2adcb77c14f..156186083766 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -10,6 +10,8 @@ import ( stdcontext "context" + "golang.org/x/exp/slices" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" @@ -20,8 +22,11 @@ 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/fees" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var ( @@ -59,6 +64,14 @@ type Builder interface { // from this transaction. NewBaseTx( outputs []*avax.TransferableOutput, + feeCalc *fees.Calculator, + options ...common.Option, + ) (*txs.BaseTx, error) + + // TODO: Drop once E upgrade is activated + newBaseTxPreEUpgrade( + outputs []*avax.TransferableOutput, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.CreateSubnetTx, error) @@ -75,6 +88,7 @@ type Builder interface { vdr *txs.Validator, rewardsOwner *secp256k1fx.OutputOwners, shares uint32, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddValidatorTx, error) @@ -84,6 +98,7 @@ type Builder interface { // startTime, endTime, sampling weight, nodeID, and subnetID. NewAddSubnetValidatorTx( vdr *txs.SubnetValidator, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddSubnetValidatorTx, error) @@ -92,6 +107,7 @@ type Builder interface { NewRemoveSubnetValidatorTx( nodeID ids.NodeID, subnetID ids.ID, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.RemoveSubnetValidatorTx, error) @@ -105,6 +121,7 @@ type Builder interface { NewAddDelegatorTx( vdr *txs.Validator, rewardsOwner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddDelegatorTx, error) @@ -122,6 +139,7 @@ type Builder interface { vmID ids.ID, fxIDs []ids.ID, chainName string, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.CreateChainTx, error) @@ -131,6 +149,7 @@ type Builder interface { // validators to the subnet. NewCreateSubnetTx( owner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.CreateSubnetTx, error) @@ -142,6 +161,7 @@ type Builder interface { NewTransferSubnetOwnershipTx( subnetID ids.ID, owner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.TransferSubnetOwnershipTx, error) @@ -153,6 +173,7 @@ type Builder interface { NewImportTx( chainID ids.ID, to *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.ImportTx, error) @@ -164,6 +185,7 @@ type Builder interface { NewExportTx( chainID ids.ID, outputs []*avax.TransferableOutput, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.ExportTx, error) @@ -212,6 +234,7 @@ type Builder interface { minDelegatorStake uint64, maxValidatorWeightFactor byte, uptimeRequirement uint32, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.TransformSubnetTx, error) @@ -237,6 +260,7 @@ type Builder interface { validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, shares uint32, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddPermissionlessValidatorTx, error) @@ -252,6 +276,7 @@ type Builder interface { vdr *txs.SubnetValidator, assetID ids.ID, rewardsOwner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddPermissionlessDelegatorTx, error) } @@ -299,11 +324,24 @@ func (b *builder) GetImportableBalance( func (b *builder) NewBaseTx( outputs []*avax.TransferableOutput, + feeCalc *fees.Calculator, options ...common.Option, -) (*txs.CreateSubnetTx, error) { - toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.CreateSubnetTxFee(), +) (*txs.BaseTx, error) { + // 1. Build core transaction without utxos + ops := common.NewOptions(options) + + utx := &txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + Outs: outputs, // not sorted yet, we'll sort later on when we have all the outputs + }, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx for _, out := range outputs { assetID := out.AssetID() amountToBurn, err := math.Add64(toBurn[assetID], out.Out.Amount()) @@ -312,165 +350,244 @@ func (b *builder) NewBaseTx( } toBurn[assetID] = amountToBurn } - toStake := map[ids.ID]uint64{} - ops := common.NewOptions(options) - inputs, changeOutputs, _, err := b.spend(toBurn, toStake, ops) + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.BaseTx(utx); err != nil { + return nil, err + } + + inputs, changeOuts, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) if err != nil { return nil, err } - outputs = append(outputs, changeOutputs...) - avax.SortTransferableOutputs(outputs, txs.Codec) // sort the outputs - tx := &txs.CreateSubnetTx{ + outputs = append(outputs, changeOuts...) + avax.SortTransferableOutputs(outputs, txs.Codec) + utx.Ins = inputs + utx.Outs = outputs + + return utx, initCtx(b.backend, utx) +} + +func (b *builder) newBaseTxPreEUpgrade( + outputs []*avax.TransferableOutput, + feeCalc *fees.Calculator, + options ...common.Option, +) (*txs.CreateSubnetTx, error) { + // 1. Build core transaction without utxos + ops := common.NewOptions(options) + + utx := &txs.CreateSubnetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: outputs, + Outs: outputs, // not sorted yet, we'll sort later on when we have all the outputs Memo: ops.Memo(), }}, Owner: &secp256k1fx.OutputOwners{}, } - return tx, initCtx(b.backend, tx) + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.CreateSubnetTx(utx); err != nil { + return nil, err + } + + inputs, changeOutputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + outputs = append(outputs, changeOutputs...) + avax.SortTransferableOutputs(outputs, txs.Codec) // sort the outputs + + utx.Ins = inputs + utx.Outs = outputs + + return utx, initCtx(b.backend, utx) } func (b *builder) NewAddValidatorTx( vdr *txs.Validator, rewardsOwner *secp256k1fx.OutputOwners, shares uint32, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddValidatorTx, error) { - avaxAssetID := b.backend.AVAXAssetID() - toBurn := map[ids.ID]uint64{ - avaxAssetID: b.backend.AddPrimaryNetworkValidatorFee(), - } - toStake := map[ids.ID]uint64{ - avaxAssetID: vdr.Wght, - } ops := common.NewOptions(options) - inputs, baseOutputs, stakeOutputs, err := b.spend(toBurn, toStake, ops) - if err != nil { - return nil, err - } - utils.Sort(rewardsOwner.Addrs) - tx := &txs.AddValidatorTx{ + + utx := &txs.AddValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: baseOutputs, Memo: ops.Memo(), }}, Validator: *vdr, - StakeOuts: stakeOutputs, RewardsOwner: rewardsOwner, DelegationShares: shares, } - return tx, initCtx(b.backend, tx) + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{ + b.backend.AVAXAssetID(): vdr.Wght, + } + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddValidatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + utx.StakeOuts = stakeOutputs + + return utx, initCtx(b.backend, utx) } func (b *builder) NewAddSubnetValidatorTx( vdr *txs.SubnetValidator, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddSubnetValidatorTx, error) { - toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.AddSubnetValidatorFee(), - } - toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) - inputs, outputs, _, err := b.spend(toBurn, toStake, ops) - if err != nil { - return nil, err - } subnetAuth, err := authorizeSubnet(b.backend, b.addrs, vdr.Subnet, ops) if err != nil { return nil, err } - tx := &txs.AddSubnetValidatorTx{ + utx := &txs.AddSubnetValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: outputs, Memo: ops.Memo(), }}, SubnetValidator: *vdr, SubnetAuth: subnetAuth, } - return tx, initCtx(b.backend, tx) + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // update fees to account for the auth credentials to be added upon tx signing + if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddSubnetValidatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + + return utx, initCtx(b.backend, utx) } func (b *builder) NewRemoveSubnetValidatorTx( nodeID ids.NodeID, subnetID ids.ID, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.RemoveSubnetValidatorTx, error) { - toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.BaseTxFee(), - } - toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) - inputs, outputs, _, err := b.spend(toBurn, toStake, ops) - if err != nil { - return nil, err - } subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) if err != nil { return nil, err } - tx := &txs.RemoveSubnetValidatorTx{ + utx := &txs.RemoveSubnetValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: outputs, Memo: ops.Memo(), }}, Subnet: subnetID, NodeID: nodeID, SubnetAuth: subnetAuth, } - return tx, initCtx(b.backend, tx) + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // update fees to account for the auth credentials to be added upon tx signing + if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.RemoveSubnetValidatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + + return utx, initCtx(b.backend, utx) } func (b *builder) NewAddDelegatorTx( vdr *txs.Validator, rewardsOwner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddDelegatorTx, error) { - avaxAssetID := b.backend.AVAXAssetID() - toBurn := map[ids.ID]uint64{ - avaxAssetID: b.backend.AddPrimaryNetworkDelegatorFee(), - } - toStake := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): vdr.Wght, - } ops := common.NewOptions(options) - inputs, baseOutputs, stakeOutputs, err := b.spend(toBurn, toStake, ops) - if err != nil { - return nil, err - } - utils.Sort(rewardsOwner.Addrs) - tx := &txs.AddDelegatorTx{ + + utx := &txs.AddDelegatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: baseOutputs, Memo: ops.Memo(), }}, Validator: *vdr, - StakeOuts: stakeOutputs, DelegationRewardsOwner: rewardsOwner, } - return tx, initCtx(b.backend, tx) + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{ + b.backend.AVAXAssetID(): vdr.Wght, + } + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddDelegatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + utx.StakeOuts = stakeOutputs + + return utx, initCtx(b.backend, utx) } func (b *builder) NewCreateChainTx( @@ -479,30 +596,22 @@ func (b *builder) NewCreateChainTx( vmID ids.ID, fxIDs []ids.ID, chainName string, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.CreateChainTx, error) { - toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.CreateBlockchainTxFee(), - } - toStake := map[ids.ID]uint64{} + // 1. Build core transaction without utxos ops := common.NewOptions(options) - inputs, outputs, _, err := b.spend(toBurn, toStake, ops) - if err != nil { - return nil, err - } - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) if err != nil { return nil, err } utils.Sort(fxIDs) - tx := &txs.CreateChainTx{ + + uTx := &txs.CreateChainTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: outputs, Memo: ops.Memo(), }}, SubnetID: subnetID, @@ -512,79 +621,136 @@ func (b *builder) NewCreateChainTx( GenesisData: genesis, SubnetAuth: subnetAuth, } - return tx, initCtx(b.backend, tx) + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // update fees to account for the auth credentials to be added upon tx signing + if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.CreateChainTx(uTx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + uTx.Ins = inputs + uTx.Outs = outputs + + return uTx, initCtx(b.backend, uTx) } func (b *builder) NewCreateSubnetTx( owner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.CreateSubnetTx, error) { - toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.CreateSubnetTxFee(), - } - toStake := map[ids.ID]uint64{} + // 1. Build core transaction without utxos ops := common.NewOptions(options) - inputs, outputs, _, err := b.spend(toBurn, toStake, ops) - if err != nil { - return nil, err - } - utils.Sort(owner.Addrs) - tx := &txs.CreateSubnetTx{ + utx := &txs.CreateSubnetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: outputs, Memo: ops.Memo(), }}, Owner: owner, } - return tx, initCtx(b.backend, tx) + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.CreateSubnetTx(utx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + + return utx, initCtx(b.backend, utx) } func (b *builder) NewTransferSubnetOwnershipTx( subnetID ids.ID, owner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.TransferSubnetOwnershipTx, error) { - toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.BaseTxFee(), - } - toStake := map[ids.ID]uint64{} + // 1. Build core transaction without utxos ops := common.NewOptions(options) - inputs, outputs, _, err := b.spend(toBurn, toStake, ops) - if err != nil { - return nil, err - } - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) if err != nil { return nil, err } utils.Sort(owner.Addrs) - tx := &txs.TransferSubnetOwnershipTx{ + utx := &txs.TransferSubnetOwnershipTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: outputs, Memo: ops.Memo(), }}, - Subnet: subnetID, - Owner: owner, SubnetAuth: subnetAuth, + Owner: owner, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // update fees to account for the auth credentials to be added upon tx signing + if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) } - return tx, initCtx(b.backend, tx) + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.TransferSubnetOwnershipTx(utx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + + return utx, initCtx(b.backend, utx) } func (b *builder) NewImportTx( sourceChainID ids.ID, to *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.ImportTx, error) { ops := common.NewOptions(options) + // 1. Build core transaction + utx := &txs.ImportTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + SourceChain: sourceChainID, + } + + // 2. Add imported inputs first utxos, err := b.backend.UTXOs(ops.Context(), sourceChainID) if err != nil { return nil, err @@ -594,12 +760,12 @@ func (b *builder) NewImportTx( addrs = ops.Addresses(b.addrs) minIssuanceTime = ops.MinIssuanceTime() avaxAssetID = b.backend.AVAXAssetID() - txFee = b.backend.BaseTxFee() - importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) - importedAmounts = make(map[ids.ID]uint64) + importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) + importedSigIndices = make([][]uint32, 0) + importedAmounts = make(map[ids.ID]uint64) ) - // Iterate over the unlocked UTXOs + for _, utxo := range utxos { out, ok := utxo.Out.(*secp256k1fx.TransferOutput) if !ok { @@ -629,9 +795,8 @@ func (b *builder) NewImportTx( return nil, err } importedAmounts[assetID] = newImportedAmount + importedSigIndices = append(importedSigIndices, inputSigIndices) } - utils.Sort(importedInputs) // sort imported inputs - if len(importedInputs) == 0 { return nil, fmt.Errorf( "%w: no UTXOs available to import", @@ -639,61 +804,125 @@ func (b *builder) NewImportTx( ) } - var ( - inputs []*avax.TransferableInput - outputs = make([]*avax.TransferableOutput, 0, len(importedAmounts)) - importedAVAX = importedAmounts[avaxAssetID] - ) - if importedAVAX > txFee { - importedAmounts[avaxAssetID] -= txFee - } else { - if importedAVAX < txFee { // imported amount goes toward paying tx fee - toBurn := map[ids.ID]uint64{ - avaxAssetID: txFee - importedAVAX, - } - toStake := map[ids.ID]uint64{} - var err error - inputs, outputs, _, err = b.spend(toBurn, toStake, ops) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - } - delete(importedAmounts, avaxAssetID) - } + utils.Sort(importedInputs) // sort imported inputs + utx.ImportedInputs = importedInputs + // 3. Add an output for all non-avax denominated inputs. for assetID, amount := range importedAmounts { - outputs = append(outputs, &avax.TransferableOutput{ + if assetID == avaxAssetID { + // Avax-denominated inputs may be used to fully or partially pay fees, + // so we'll handle them later on. + continue + } + + utx.Outs = append(utx.Outs, &avax.TransferableOutput{ Asset: avax.Asset{ID: assetID}, Out: &secp256k1fx.TransferOutput{ Amt: amount, OutputOwners: *to, }, - }) + }) // we'll sort them later on } - avax.SortTransferableOutputs(outputs, txs.Codec) // sort imported outputs - tx := &txs.ImportTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: outputs, - Memo: ops.Memo(), - }}, - SourceChain: sourceChainID, - ImportedInputs: importedInputs, + // 3. Finance fees as much as possible with imported, Avax-denominated UTXOs + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.ImportTx(utx); err != nil { + return nil, err } - return tx, initCtx(b.backend, tx) + + for _, sigIndices := range importedSigIndices { + if _, err = financeCredential(feeCalc, sigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + } + + switch importedAVAX := importedAmounts[avaxAssetID]; { + case importedAVAX == feeCalc.Fee: + // imported inputs match exactly the fees to be paid + avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs + return utx, initCtx(b.backend, utx) + + case importedAVAX < feeCalc.Fee: + // imported inputs can partially pay fees + feeCalc.Fee -= importedAmounts[avaxAssetID] + + default: + // imported inputs may be enough to pay taxes by themselves + changeOut := &avax.TransferableOutput{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + OutputOwners: *to, // we set amount after considering own fees + }, + } + + // update fees to target given the extra output added + outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) + if err != nil { + return nil, fmt.Errorf("failed calculating output size: %w", err) + } + if _, err := feeCalc.AddFeesFor(outDimensions); err != nil { + return nil, fmt.Errorf("account for output fees: %w", err) + } + + switch { + case feeCalc.Fee < importedAVAX: + changeOut.Out.(*secp256k1fx.TransferOutput).Amt = importedAVAX - feeCalc.Fee + utx.Outs = append(utx.Outs, changeOut) + avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs + return utx, initCtx(b.backend, utx) + + case feeCalc.Fee == importedAVAX: + // imported fees pays exactly the tx cost. We don't include the outputs + avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs + return utx, initCtx(b.backend, utx) + + default: + // imported avax are not enough to pay fees + // Drop the changeOut and finance the tx + if _, err := feeCalc.RemoveFeesFor(outDimensions); err != nil { + return nil, fmt.Errorf("failed reverting change output: %w", err) + } + feeCalc.Fee -= importedAVAX + } + } + + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} + inputs, changeOuts, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = append(utx.Outs, changeOuts...) + avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs + return utx, initCtx(b.backend, utx) } func (b *builder) NewExportTx( chainID ids.ID, outputs []*avax.TransferableOutput, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.ExportTx, error) { - toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.BaseTxFee(), + // 1. Build core transaction without utxos + ops := common.NewOptions(options) + avax.SortTransferableOutputs(outputs, txs.Codec) // sort exported outputs + + utx := &txs.ExportTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Memo: ops.Memo(), + }}, + DestinationChain: chainID, + ExportedOutputs: outputs, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx for _, out := range outputs { assetID := out.AssetID() amountToBurn, err := math.Add64(toBurn[assetID], out.Out.Amount()) @@ -703,26 +932,20 @@ func (b *builder) NewExportTx( toBurn[assetID] = amountToBurn } - toStake := map[ids.ID]uint64{} - ops := common.NewOptions(options) - inputs, changeOutputs, _, err := b.spend(toBurn, toStake, ops) - if err != nil { + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.ExportTx(utx); err != nil { return nil, err } - avax.SortTransferableOutputs(outputs, txs.Codec) // sort exported outputs - tx := &txs.ExportTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: changeOutputs, - Memo: ops.Memo(), - }}, - DestinationChain: chainID, - ExportedOutputs: outputs, + inputs, changeOuts, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err } - return tx, initCtx(b.backend, tx) + + utx.Ins = inputs + utx.Outs = changeOuts + + return utx, initCtx(b.backend, utx) } func (b *builder) NewTransformSubnetTx( @@ -740,30 +963,21 @@ func (b *builder) NewTransformSubnetTx( minDelegatorStake uint64, maxValidatorWeightFactor byte, uptimeRequirement uint32, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.TransformSubnetTx, error) { - toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.TransformSubnetTxFee(), - assetID: maxSupply - initialSupply, - } - toStake := map[ids.ID]uint64{} + // 1. Build core transaction without utxos ops := common.NewOptions(options) - inputs, outputs, _, err := b.spend(toBurn, toStake, ops) - if err != nil { - return nil, err - } subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) if err != nil { return nil, err } - tx := &txs.TransformSubnetTx{ + utx := &txs.TransformSubnetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: outputs, Memo: ops.Memo(), }}, Subnet: subnetID, @@ -782,7 +996,32 @@ func (b *builder) NewTransformSubnetTx( UptimeRequirement: uptimeRequirement, SubnetAuth: subnetAuth, } - return tx, initCtx(b.backend, tx) + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{} + toBurn := map[ids.ID]uint64{ + assetID: maxSupply - initialSupply, + } // fees are calculated in financeTx + + // update fees to account for the auth credentials to be added upon tx signing + if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.TransformSubnetTx(utx); err != nil { + return nil, err + } + + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + + return utx, initCtx(b.backend, utx) } func (b *builder) NewAddPermissionlessValidatorTx( @@ -792,82 +1031,92 @@ func (b *builder) NewAddPermissionlessValidatorTx( validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, shares uint32, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddPermissionlessValidatorTx, error) { - avaxAssetID := b.backend.AVAXAssetID() - toBurn := map[ids.ID]uint64{} - if vdr.Subnet == constants.PrimaryNetworkID { - toBurn[avaxAssetID] = b.backend.AddPrimaryNetworkValidatorFee() - } else { - toBurn[avaxAssetID] = b.backend.AddSubnetValidatorFee() - } - toStake := map[ids.ID]uint64{ - assetID: vdr.Wght, - } ops := common.NewOptions(options) - inputs, baseOutputs, stakeOutputs, err := b.spend(toBurn, toStake, ops) - if err != nil { - return nil, err - } - utils.Sort(validationRewardsOwner.Addrs) utils.Sort(delegationRewardsOwner.Addrs) - tx := &txs.AddPermissionlessValidatorTx{ + + utx := &txs.AddPermissionlessValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: baseOutputs, Memo: ops.Memo(), }}, Validator: vdr.Validator, Subnet: vdr.Subnet, Signer: signer, - StakeOuts: stakeOutputs, ValidatorRewardsOwner: validationRewardsOwner, DelegatorRewardsOwner: delegationRewardsOwner, DelegationShares: shares, } - return tx, initCtx(b.backend, tx) + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{ + assetID: vdr.Wght, + } + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddPermissionlessValidatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + utx.StakeOuts = stakeOutputs + + return utx, initCtx(b.backend, utx) } func (b *builder) NewAddPermissionlessDelegatorTx( vdr *txs.SubnetValidator, assetID ids.ID, rewardsOwner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddPermissionlessDelegatorTx, error) { - avaxAssetID := b.backend.AVAXAssetID() - toBurn := map[ids.ID]uint64{} - if vdr.Subnet == constants.PrimaryNetworkID { - toBurn[avaxAssetID] = b.backend.AddPrimaryNetworkDelegatorFee() - } else { - toBurn[avaxAssetID] = b.backend.AddSubnetDelegatorFee() - } - toStake := map[ids.ID]uint64{ - assetID: vdr.Wght, - } ops := common.NewOptions(options) - inputs, baseOutputs, stakeOutputs, err := b.spend(toBurn, toStake, ops) - if err != nil { - return nil, err - } - utils.Sort(rewardsOwner.Addrs) - tx := &txs.AddPermissionlessDelegatorTx{ + + utx := &txs.AddPermissionlessDelegatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, - Ins: inputs, - Outs: baseOutputs, Memo: ops.Memo(), }}, Validator: vdr.Validator, Subnet: vdr.Subnet, - StakeOuts: stakeOutputs, DelegationRewardsOwner: rewardsOwner, } - return tx, initCtx(b.backend, tx) + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + toStake := map[ids.ID]uint64{ + assetID: vdr.Wght, + } + toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddPermissionlessDelegatorTx(utx); err != nil { + return nil, err + } + + inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) + if err != nil { + return nil, err + } + + utx.Ins = inputs + utx.Outs = outputs + utx.StakeOuts = stakeOutputs + + return utx, initCtx(b.backend, utx) } func (b *builder) getBalance( @@ -929,9 +1178,10 @@ func (b *builder) getBalance( // place into the staked outputs. First locked UTXOs are attempted to be // used for these funds, and then unlocked UTXOs will be attempted to be // used. There is no preferential ordering on the unlock times. -func (b *builder) spend( +func (b *builder) financeTx( amountsToBurn map[ids.ID]uint64, amountsToStake map[ids.ID]uint64, + feeCalc *fees.Calculator, options *common.Options, ) ( inputs []*avax.TransferableInput, @@ -939,11 +1189,25 @@ func (b *builder) spend( stakeOutputs []*avax.TransferableOutput, err error, ) { + avaxAssetID := b.backend.AVAXAssetID() utxos, err := b.backend.UTXOs(options.Context(), constants.PlatformChainID) if err != nil { return nil, nil, nil, err } + // we can only pay fees in avax, so we sort avax-denominated UTXOs last + // to maximize probability of being able to pay fees. + slices.SortFunc(utxos, func(lhs, rhs *avax.UTXO) int { + switch { + case lhs.Asset.AssetID() == avaxAssetID && rhs.Asset.AssetID() != avaxAssetID: + return 1 + case lhs.Asset.AssetID() != avaxAssetID && rhs.Asset.AssetID() == avaxAssetID: + return -1 + default: + return 0 + } + }) + addrs := options.Addresses(b.addrs) minIssuanceTime := options.MinIssuanceTime() @@ -956,14 +1220,15 @@ func (b *builder) spend( Addrs: []ids.ShortID{addr}, }) + amountsToBurn[avaxAssetID] += feeCalc.Fee + // Iterate over the locked UTXOs for _, utxo := range utxos { assetID := utxo.AssetID() - remainingAmountToStake := amountsToStake[assetID] // If we have staked enough of the asset, then we have no need burn // more. - if remainingAmountToStake == 0 { + if amountsToStake[assetID] == 0 { continue } @@ -991,7 +1256,7 @@ func (b *builder) spend( continue } - inputs = append(inputs, &avax.TransferableInput{ + input := &avax.TransferableInput{ UTXOID: utxo.UTXOID, Asset: utxo.Asset, In: &stakeable.LockIn{ @@ -1003,16 +1268,30 @@ func (b *builder) spend( }, }, }, - }) + } + + addedFees, err := financeInput(feeCalc, input) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + addedFees, err = financeCredential(feeCalc, inputSigIndices) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + inputs = append(inputs, input) // Stake any value that should be staked amountToStake := math.Min( - remainingAmountToStake, // Amount we still need to stake - out.Amt, // Amount available to stake + amountsToStake[assetID], // Amount we still need to stake + out.Amt, // Amount available to stake ) // Add the output to the staked outputs - stakeOutputs = append(stakeOutputs, &avax.TransferableOutput{ + stakeOut := &avax.TransferableOutput{ Asset: utxo.Asset, Out: &stakeable.LockOut{ Locktime: lockedOut.Locktime, @@ -1021,12 +1300,20 @@ func (b *builder) spend( OutputOwners: out.OutputOwners, }, }, - }) + } + + addedFees, err = financeOutput(feeCalc, stakeOut) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + stakeOutputs = append(stakeOutputs, stakeOut) amountsToStake[assetID] -= amountToStake if remainingAmount := out.Amt - amountToStake; remainingAmount > 0 { // This input had extra value, so some of it must be returned - changeOutputs = append(changeOutputs, &avax.TransferableOutput{ + changeOut := &avax.TransferableOutput{ Asset: utxo.Asset, Out: &stakeable.LockOut{ Locktime: lockedOut.Locktime, @@ -1035,19 +1322,26 @@ func (b *builder) spend( OutputOwners: out.OutputOwners, }, }, - }) + } + + // update fees to account for the change output + addedFees, err = financeOutput(feeCalc, changeOut) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + changeOutputs = append(changeOutputs, changeOut) } } // Iterate over the unlocked UTXOs for _, utxo := range utxos { assetID := utxo.AssetID() - remainingAmountToStake := amountsToStake[assetID] - remainingAmountToBurn := amountsToBurn[assetID] // If we have consumed enough of the asset, then we have no need burn // more. - if remainingAmountToStake == 0 && remainingAmountToBurn == 0 { + if amountsToStake[assetID] == 0 && amountsToBurn[assetID] == 0 { continue } @@ -1072,7 +1366,7 @@ func (b *builder) spend( continue } - inputs = append(inputs, &avax.TransferableInput{ + input := &avax.TransferableInput{ UTXOID: utxo.UTXOID, Asset: utxo.Asset, In: &secp256k1fx.TransferInput{ @@ -1081,41 +1375,84 @@ func (b *builder) spend( SigIndices: inputSigIndices, }, }, - }) + } + + addedFees, err := financeInput(feeCalc, input) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + addedFees, err = financeCredential(feeCalc, inputSigIndices) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for credential fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees + + inputs = append(inputs, input) // Burn any value that should be burned amountToBurn := math.Min( - remainingAmountToBurn, // Amount we still need to burn - out.Amt, // Amount available to burn + amountsToBurn[assetID], // Amount we still need to burn + out.Amt, // Amount available to burn ) amountsToBurn[assetID] -= amountToBurn amountAvalibleToStake := out.Amt - amountToBurn // Burn any value that should be burned amountToStake := math.Min( - remainingAmountToStake, // Amount we still need to stake - amountAvalibleToStake, // Amount available to stake + amountsToStake[assetID], // Amount we still need to stake + amountAvalibleToStake, // Amount available to stake ) amountsToStake[assetID] -= amountToStake if amountToStake > 0 { // Some of this input was put for staking - stakeOutputs = append(stakeOutputs, &avax.TransferableOutput{ + stakeOut := &avax.TransferableOutput{ Asset: utxo.Asset, Out: &secp256k1fx.TransferOutput{ Amt: amountToStake, OutputOwners: *changeOwner, }, - }) + } + + stakeOutputs = append(stakeOutputs, stakeOut) + + addedFees, err = financeOutput(feeCalc, stakeOut) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) + } + amountsToBurn[avaxAssetID] += addedFees } + if remainingAmount := amountAvalibleToStake - amountToStake; remainingAmount > 0 { - // This input had extra value, so some of it must be returned - changeOutputs = append(changeOutputs, &avax.TransferableOutput{ + // This input had extra value, so some of it must be returned, once fees are removed + changeOut := &avax.TransferableOutput{ Asset: utxo.Asset, Out: &secp256k1fx.TransferOutput{ - Amt: remainingAmount, OutputOwners: *changeOwner, }, - }) + } + + // update fees to account for the change output + addedFees, err = financeOutput(feeCalc, changeOut) + if err != nil { + return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) + } + + if assetID != avaxAssetID { + changeOut.Out.(*secp256k1fx.TransferOutput).Amt = remainingAmount + amountsToBurn[avaxAssetID] += addedFees + changeOutputs = append(changeOutputs, changeOut) + } else { + // here assetID == b.backend.AVAXAssetID() + switch { + case addedFees < remainingAmount: + changeOut.Out.(*secp256k1fx.TransferOutput).Amt = remainingAmount - addedFees + changeOutputs = append(changeOutputs, changeOut) + case addedFees >= remainingAmount: + amountsToBurn[assetID] += addedFees - remainingAmount + } + } } } @@ -1146,6 +1483,42 @@ func (b *builder) spend( return inputs, changeOutputs, stakeOutputs, nil } +func financeInput(feeCalc *fees.Calculator, input *avax.TransferableInput) (uint64, error) { + insDimensions, err := commonfees.GetInputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) + if err != nil { + return 0, fmt.Errorf("failed calculating input size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(insDimensions) + if err != nil { + return 0, fmt.Errorf("account for input fees: %w", err) + } + return addedFees, nil +} + +func financeOutput(feeCalc *fees.Calculator, output *avax.TransferableOutput) (uint64, error) { + outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{output}) + if err != nil { + return 0, fmt.Errorf("failed calculating changeOut size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(outDimensions) + if err != nil { + return 0, fmt.Errorf("account for stakedOut fees: %w", err) + } + return addedFees, nil +} + +func financeCredential(feeCalc *fees.Calculator, inputSigIndices []uint32) (uint64, error) { + credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, inputSigIndices) + if err != nil { + return 0, fmt.Errorf("failed calculating input size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(credsDimensions) + if err != nil { + return 0, fmt.Errorf("account for input fees: %w", err) + } + return addedFees, nil +} + func authorizeSubnet( backend BuilderBackend, addresses set.Set[ids.ShortID], diff --git a/wallet/chain/p/builder_dynamic_fees.go b/wallet/chain/p/builder_dynamic_fees.go deleted file mode 100644 index 093174549254..000000000000 --- a/wallet/chain/p/builder_dynamic_fees.go +++ /dev/null @@ -1,1090 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package p - -import ( - "fmt" - "time" - - "golang.org/x/exp/slices" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "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/fees" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" -) - -type DynamicFeesBuilder struct { - addrs set.Set[ids.ShortID] - backend BuilderBackend -} - -func NewDynamicFeesBuilder(addrs set.Set[ids.ShortID], backend BuilderBackend) *DynamicFeesBuilder { - return &DynamicFeesBuilder{ - addrs: addrs, - backend: backend, - } -} - -func (b *DynamicFeesBuilder) newBaseTxPreEUpgrade( - outputs []*avax.TransferableOutput, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.CreateSubnetTx, error) { - // 1. Build core transaction without utxos - ops := common.NewOptions(options) - - utx := &txs.CreateSubnetTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Outs: outputs, // not sorted yet, we'll sort later on when we have all the outputs - Memo: ops.Memo(), - }}, - Owner: &secp256k1fx.OutputOwners{}, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{} - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.CreateSubnetTx(utx); err != nil { - return nil, err - } - - inputs, changeOutputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - outputs = append(outputs, changeOutputs...) - avax.SortTransferableOutputs(outputs, txs.Codec) // sort the outputs - - utx.Ins = inputs - utx.Outs = outputs - - return utx, initCtx(b.backend, utx) -} - -func (b *DynamicFeesBuilder) NewBaseTx( - outputs []*avax.TransferableOutput, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.BaseTx, error) { - // 1. Build core transaction without utxos - ops := common.NewOptions(options) - - utx := &txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - Outs: outputs, // not sorted yet, we'll sort later on when we have all the outputs - }, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{} - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - for _, out := range outputs { - assetID := out.AssetID() - amountToBurn, err := math.Add64(toBurn[assetID], out.Out.Amount()) - if err != nil { - return nil, err - } - toBurn[assetID] = amountToBurn - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.BaseTx(utx); err != nil { - return nil, err - } - - inputs, changeOuts, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - outputs = append(outputs, changeOuts...) - avax.SortTransferableOutputs(outputs, txs.Codec) - utx.Ins = inputs - utx.Outs = outputs - - return utx, initCtx(b.backend, utx) -} - -func (b *DynamicFeesBuilder) NewAddSubnetValidatorTx( - vdr *txs.SubnetValidator, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.AddSubnetValidatorTx, error) { - ops := common.NewOptions(options) - - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, vdr.Subnet, ops) - if err != nil { - return nil, err - } - - utx := &txs.AddSubnetValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - SubnetValidator: *vdr, - SubnetAuth: subnetAuth, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{} - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - - // update fees to account for the auth credentials to be added upon tx signing - if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { - return nil, fmt.Errorf("account for credential fees: %w", err) - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.AddSubnetValidatorTx(utx); err != nil { - return nil, err - } - - inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - utx.Ins = inputs - utx.Outs = outputs - - return utx, initCtx(b.backend, utx) -} - -func (b *DynamicFeesBuilder) NewRemoveSubnetValidatorTx( - nodeID ids.NodeID, - subnetID ids.ID, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.RemoveSubnetValidatorTx, error) { - ops := common.NewOptions(options) - - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) - if err != nil { - return nil, err - } - - utx := &txs.RemoveSubnetValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - Subnet: subnetID, - NodeID: nodeID, - SubnetAuth: subnetAuth, - } - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{} - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - - // update fees to account for the auth credentials to be added upon tx signing - if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { - return nil, fmt.Errorf("account for credential fees: %w", err) - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.RemoveSubnetValidatorTx(utx); err != nil { - return nil, err - } - - inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - utx.Ins = inputs - utx.Outs = outputs - - return utx, initCtx(b.backend, utx) -} - -func (b *DynamicFeesBuilder) NewCreateChainTx( - subnetID ids.ID, - genesis []byte, - vmID ids.ID, - fxIDs []ids.ID, - chainName string, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.CreateChainTx, error) { - // 1. Build core transaction without utxos - ops := common.NewOptions(options) - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) - if err != nil { - return nil, err - } - - utils.Sort(fxIDs) - - uTx := &txs.CreateChainTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - SubnetID: subnetID, - ChainName: chainName, - VMID: vmID, - FxIDs: fxIDs, - GenesisData: genesis, - SubnetAuth: subnetAuth, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{} - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - - // update fees to account for the auth credentials to be added upon tx signing - if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { - return nil, fmt.Errorf("account for credential fees: %w", err) - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.CreateChainTx(uTx); err != nil { - return nil, err - } - - inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - uTx.Ins = inputs - uTx.Outs = outputs - - return uTx, initCtx(b.backend, uTx) -} - -func (b *DynamicFeesBuilder) NewCreateSubnetTx( - owner *secp256k1fx.OutputOwners, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.CreateSubnetTx, error) { - // 1. Build core transaction without utxos - ops := common.NewOptions(options) - - utx := &txs.CreateSubnetTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - Owner: owner, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{} - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.CreateSubnetTx(utx); err != nil { - return nil, err - } - - inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - utx.Ins = inputs - utx.Outs = outputs - - return utx, initCtx(b.backend, utx) -} - -func (b *DynamicFeesBuilder) NewTransferSubnetOwnershipTx( - subnetID ids.ID, - owner *secp256k1fx.OutputOwners, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.TransferSubnetOwnershipTx, error) { - // 1. Build core transaction without utxos - ops := common.NewOptions(options) - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) - if err != nil { - return nil, err - } - - utils.Sort(owner.Addrs) - utx := &txs.TransferSubnetOwnershipTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - SubnetAuth: subnetAuth, - Owner: owner, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{} - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - - // update fees to account for the auth credentials to be added upon tx signing - if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { - return nil, fmt.Errorf("account for credential fees: %w", err) - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.TransferSubnetOwnershipTx(utx); err != nil { - return nil, err - } - - inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - utx.Ins = inputs - utx.Outs = outputs - - return utx, initCtx(b.backend, utx) -} - -func (b *DynamicFeesBuilder) NewImportTx( - sourceChainID ids.ID, - to *secp256k1fx.OutputOwners, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.ImportTx, error) { - ops := common.NewOptions(options) - // 1. Build core transaction - utx := &txs.ImportTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - SourceChain: sourceChainID, - } - - // 2. Add imported inputs first - utxos, err := b.backend.UTXOs(ops.Context(), sourceChainID) - if err != nil { - return nil, err - } - - var ( - addrs = ops.Addresses(b.addrs) - minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - - importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) - importedSigIndices = make([][]uint32, 0) - importedAmounts = make(map[ids.ID]uint64) - ) - - for _, utxo := range utxos { - out, ok := utxo.Out.(*secp256k1fx.TransferOutput) - if !ok { - continue - } - - inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) - if !ok { - // We couldn't spend this UTXO, so we skip to the next one - continue - } - - importedInputs = append(importedInputs, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - In: &secp256k1fx.TransferInput{ - Amt: out.Amt, - Input: secp256k1fx.Input{ - SigIndices: inputSigIndices, - }, - }, - }) - - assetID := utxo.AssetID() - newImportedAmount, err := math.Add64(importedAmounts[assetID], out.Amt) - if err != nil { - return nil, err - } - importedAmounts[assetID] = newImportedAmount - importedSigIndices = append(importedSigIndices, inputSigIndices) - } - if len(importedInputs) == 0 { - return nil, fmt.Errorf( - "%w: no UTXOs available to import", - errInsufficientFunds, - ) - } - - utils.Sort(importedInputs) // sort imported inputs - utx.ImportedInputs = importedInputs - - // 3. Add an output for all non-avax denominated inputs. - for assetID, amount := range importedAmounts { - if assetID == avaxAssetID { - // Avax-denominated inputs may be used to fully or partially pay fees, - // so we'll handle them later on. - continue - } - - utx.Outs = append(utx.Outs, &avax.TransferableOutput{ - Asset: avax.Asset{ID: assetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: amount, - OutputOwners: *to, - }, - }) // we'll sort them later on - } - - // 3. Finance fees as much as possible with imported, Avax-denominated UTXOs - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.ImportTx(utx); err != nil { - return nil, err - } - - for _, sigIndices := range importedSigIndices { - if _, err = financeCredential(feeCalc, sigIndices); err != nil { - return nil, fmt.Errorf("account for credential fees: %w", err) - } - } - - switch importedAVAX := importedAmounts[avaxAssetID]; { - case importedAVAX == feeCalc.Fee: - // imported inputs match exactly the fees to be paid - avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, initCtx(b.backend, utx) - - case importedAVAX < feeCalc.Fee: - // imported inputs can partially pay fees - feeCalc.Fee -= importedAmounts[avaxAssetID] - - default: - // imported inputs may be enough to pay taxes by themselves - changeOut := &avax.TransferableOutput{ - Asset: avax.Asset{ID: avaxAssetID}, - Out: &secp256k1fx.TransferOutput{ - OutputOwners: *to, // we set amount after considering own fees - }, - } - - // update fees to target given the extra output added - outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) - if err != nil { - return nil, fmt.Errorf("failed calculating output size: %w", err) - } - if _, err := feeCalc.AddFeesFor(outDimensions); err != nil { - return nil, fmt.Errorf("account for output fees: %w", err) - } - - switch { - case feeCalc.Fee < importedAVAX: - changeOut.Out.(*secp256k1fx.TransferOutput).Amt = importedAVAX - feeCalc.Fee - utx.Outs = append(utx.Outs, changeOut) - avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, initCtx(b.backend, utx) - - case feeCalc.Fee == importedAVAX: - // imported fees pays exactly the tx cost. We don't include the outputs - avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, initCtx(b.backend, utx) - - default: - // imported avax are not enough to pay fees - // Drop the changeOut and finance the tx - if _, err := feeCalc.RemoveFeesFor(outDimensions); err != nil { - return nil, fmt.Errorf("failed reverting change output: %w", err) - } - feeCalc.Fee -= importedAVAX - } - } - - toStake := map[ids.ID]uint64{} - toBurn := map[ids.ID]uint64{} - inputs, changeOuts, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - utx.Ins = inputs - utx.Outs = append(utx.Outs, changeOuts...) - avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, initCtx(b.backend, utx) -} - -func (b *DynamicFeesBuilder) NewExportTx( - chainID ids.ID, - outputs []*avax.TransferableOutput, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.ExportTx, error) { - // 1. Build core transaction without utxos - ops := common.NewOptions(options) - avax.SortTransferableOutputs(outputs, txs.Codec) // sort exported outputs - - utx := &txs.ExportTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - DestinationChain: chainID, - ExportedOutputs: outputs, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{} - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - for _, out := range outputs { - assetID := out.AssetID() - amountToBurn, err := math.Add64(toBurn[assetID], out.Out.Amount()) - if err != nil { - return nil, err - } - toBurn[assetID] = amountToBurn - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.ExportTx(utx); err != nil { - return nil, err - } - - inputs, changeOuts, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - utx.Ins = inputs - utx.Outs = changeOuts - - return utx, initCtx(b.backend, utx) -} - -func (b *DynamicFeesBuilder) NewTransformSubnetTx( - subnetID ids.ID, - assetID ids.ID, - initialSupply uint64, - maxSupply uint64, - minConsumptionRate uint64, - maxConsumptionRate uint64, - minValidatorStake uint64, - maxValidatorStake uint64, - minStakeDuration time.Duration, - maxStakeDuration time.Duration, - minDelegationFee uint32, - minDelegatorStake uint64, - maxValidatorWeightFactor byte, - uptimeRequirement uint32, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.TransformSubnetTx, error) { - // 1. Build core transaction without utxos - ops := common.NewOptions(options) - - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) - if err != nil { - return nil, err - } - - utx := &txs.TransformSubnetTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - Subnet: subnetID, - AssetID: assetID, - InitialSupply: initialSupply, - MaximumSupply: maxSupply, - MinConsumptionRate: minConsumptionRate, - MaxConsumptionRate: maxConsumptionRate, - MinValidatorStake: minValidatorStake, - MaxValidatorStake: maxValidatorStake, - MinStakeDuration: uint32(minStakeDuration / time.Second), - MaxStakeDuration: uint32(maxStakeDuration / time.Second), - MinDelegationFee: minDelegationFee, - MinDelegatorStake: minDelegatorStake, - MaxValidatorWeightFactor: maxValidatorWeightFactor, - UptimeRequirement: uptimeRequirement, - SubnetAuth: subnetAuth, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{} - toBurn := map[ids.ID]uint64{ - assetID: maxSupply - initialSupply, - } // fees are calculated in financeTx - - // update fees to account for the auth credentials to be added upon tx signing - if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { - return nil, fmt.Errorf("account for credential fees: %w", err) - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.TransformSubnetTx(utx); err != nil { - return nil, err - } - - inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - utx.Ins = inputs - utx.Outs = outputs - - return utx, initCtx(b.backend, utx) -} - -func (b *DynamicFeesBuilder) NewAddPermissionlessValidatorTx( - vdr *txs.SubnetValidator, - signer signer.Signer, - assetID ids.ID, - validationRewardsOwner *secp256k1fx.OutputOwners, - delegationRewardsOwner *secp256k1fx.OutputOwners, - shares uint32, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.AddPermissionlessValidatorTx, error) { - ops := common.NewOptions(options) - utils.Sort(validationRewardsOwner.Addrs) - utils.Sort(delegationRewardsOwner.Addrs) - - utx := &txs.AddPermissionlessValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - Validator: vdr.Validator, - Subnet: vdr.Subnet, - Signer: signer, - ValidatorRewardsOwner: validationRewardsOwner, - DelegatorRewardsOwner: delegationRewardsOwner, - DelegationShares: shares, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{ - assetID: vdr.Wght, - } - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.AddPermissionlessValidatorTx(utx); err != nil { - return nil, err - } - - inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - utx.Ins = inputs - utx.Outs = outputs - utx.StakeOuts = stakeOutputs - - return utx, initCtx(b.backend, utx) -} - -func (b *DynamicFeesBuilder) NewAddPermissionlessDelegatorTx( - vdr *txs.SubnetValidator, - assetID ids.ID, - rewardsOwner *secp256k1fx.OutputOwners, - feeCalc *fees.Calculator, - options ...common.Option, -) (*txs.AddPermissionlessDelegatorTx, error) { - ops := common.NewOptions(options) - utils.Sort(rewardsOwner.Addrs) - - utx := &txs.AddPermissionlessDelegatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: constants.PlatformChainID, - Memo: ops.Memo(), - }}, - Validator: vdr.Validator, - Subnet: vdr.Subnet, - DelegationRewardsOwner: rewardsOwner, - } - - // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{ - assetID: vdr.Wght, - } - toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.AddPermissionlessDelegatorTx(utx); err != nil { - return nil, err - } - - inputs, outputs, stakeOutputs, err := b.financeTx(toBurn, toStake, feeCalc, ops) - if err != nil { - return nil, err - } - - utx.Ins = inputs - utx.Outs = outputs - utx.StakeOuts = stakeOutputs - - return utx, initCtx(b.backend, utx) -} - -func (b *DynamicFeesBuilder) financeTx( - amountsToBurn map[ids.ID]uint64, - amountsToStake map[ids.ID]uint64, - feeCalc *fees.Calculator, - options *common.Options, -) ( - inputs []*avax.TransferableInput, - changeOutputs []*avax.TransferableOutput, - stakeOutputs []*avax.TransferableOutput, - err error, -) { - avaxAssetID := b.backend.AVAXAssetID() - utxos, err := b.backend.UTXOs(options.Context(), constants.PlatformChainID) - if err != nil { - return nil, nil, nil, err - } - - // we can only pay fees in avax, so we sort avax-denominated UTXOs last - // to maximize probability of being able to pay fees. - slices.SortFunc(utxos, func(lhs, rhs *avax.UTXO) int { - switch { - case lhs.Asset.AssetID() == avaxAssetID && rhs.Asset.AssetID() != avaxAssetID: - return 1 - case lhs.Asset.AssetID() != avaxAssetID && rhs.Asset.AssetID() == avaxAssetID: - return -1 - default: - return 0 - } - }) - - addrs := options.Addresses(b.addrs) - minIssuanceTime := options.MinIssuanceTime() - - addr, ok := addrs.Peek() - if !ok { - return nil, nil, nil, errNoChangeAddress - } - changeOwner := options.ChangeOwner(&secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{addr}, - }) - - amountsToBurn[avaxAssetID] += feeCalc.Fee - - // Iterate over the locked UTXOs - for _, utxo := range utxos { - assetID := utxo.AssetID() - - // If we have staked enough of the asset, then we have no need burn - // more. - if amountsToStake[assetID] == 0 { - continue - } - - outIntf := utxo.Out - lockedOut, ok := outIntf.(*stakeable.LockOut) - if !ok { - // This output isn't locked, so it will be handled during the next - // iteration of the UTXO set - continue - } - if minIssuanceTime >= lockedOut.Locktime { - // This output isn't locked, so it will be handled during the next - // iteration of the UTXO set - continue - } - - out, ok := lockedOut.TransferableOut.(*secp256k1fx.TransferOutput) - if !ok { - return nil, nil, nil, errUnknownOutputType - } - - inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) - if !ok { - // We couldn't spend this UTXO, so we skip to the next one - continue - } - - input := &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - In: &stakeable.LockIn{ - Locktime: lockedOut.Locktime, - TransferableIn: &secp256k1fx.TransferInput{ - Amt: out.Amt, - Input: secp256k1fx.Input{ - SigIndices: inputSigIndices, - }, - }, - }, - } - - addedFees, err := financeInput(feeCalc, input) - if err != nil { - return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) - } - amountsToBurn[avaxAssetID] += addedFees - - addedFees, err = financeCredential(feeCalc, inputSigIndices) - if err != nil { - return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) - } - amountsToBurn[avaxAssetID] += addedFees - - inputs = append(inputs, input) - - // Stake any value that should be staked - amountToStake := math.Min( - amountsToStake[assetID], // Amount we still need to stake - out.Amt, // Amount available to stake - ) - - // Add the output to the staked outputs - stakeOut := &avax.TransferableOutput{ - Asset: utxo.Asset, - Out: &stakeable.LockOut{ - Locktime: lockedOut.Locktime, - TransferableOut: &secp256k1fx.TransferOutput{ - Amt: amountToStake, - OutputOwners: out.OutputOwners, - }, - }, - } - - addedFees, err = financeOutput(feeCalc, stakeOut) - if err != nil { - return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) - } - amountsToBurn[avaxAssetID] += addedFees - - stakeOutputs = append(stakeOutputs, stakeOut) - - amountsToStake[assetID] -= amountToStake - if remainingAmount := out.Amt - amountToStake; remainingAmount > 0 { - // This input had extra value, so some of it must be returned - changeOut := &avax.TransferableOutput{ - Asset: utxo.Asset, - Out: &stakeable.LockOut{ - Locktime: lockedOut.Locktime, - TransferableOut: &secp256k1fx.TransferOutput{ - Amt: remainingAmount, - OutputOwners: out.OutputOwners, - }, - }, - } - - // update fees to account for the change output - addedFees, err = financeOutput(feeCalc, changeOut) - if err != nil { - return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) - } - amountsToBurn[avaxAssetID] += addedFees - - changeOutputs = append(changeOutputs, changeOut) - } - } - - // Iterate over the unlocked UTXOs - for _, utxo := range utxos { - assetID := utxo.AssetID() - - // If we have consumed enough of the asset, then we have no need burn - // more. - if amountsToStake[assetID] == 0 && amountsToBurn[assetID] == 0 { - continue - } - - outIntf := utxo.Out - if lockedOut, ok := outIntf.(*stakeable.LockOut); ok { - if lockedOut.Locktime > minIssuanceTime { - // This output is currently locked, so this output can't be - // burned. - continue - } - outIntf = lockedOut.TransferableOut - } - - out, ok := outIntf.(*secp256k1fx.TransferOutput) - if !ok { - return nil, nil, nil, errUnknownOutputType - } - - inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) - if !ok { - // We couldn't spend this UTXO, so we skip to the next one - continue - } - - input := &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - In: &secp256k1fx.TransferInput{ - Amt: out.Amt, - Input: secp256k1fx.Input{ - SigIndices: inputSigIndices, - }, - }, - } - - addedFees, err := financeInput(feeCalc, input) - if err != nil { - return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) - } - amountsToBurn[avaxAssetID] += addedFees - - addedFees, err = financeCredential(feeCalc, inputSigIndices) - if err != nil { - return nil, nil, nil, fmt.Errorf("account for credential fees: %w", err) - } - amountsToBurn[avaxAssetID] += addedFees - - inputs = append(inputs, input) - - // Burn any value that should be burned - amountToBurn := math.Min( - amountsToBurn[assetID], // Amount we still need to burn - out.Amt, // Amount available to burn - ) - amountsToBurn[assetID] -= amountToBurn - - amountAvalibleToStake := out.Amt - amountToBurn - // Burn any value that should be burned - amountToStake := math.Min( - amountsToStake[assetID], // Amount we still need to stake - amountAvalibleToStake, // Amount available to stake - ) - amountsToStake[assetID] -= amountToStake - if amountToStake > 0 { - // Some of this input was put for staking - stakeOut := &avax.TransferableOutput{ - Asset: utxo.Asset, - Out: &secp256k1fx.TransferOutput{ - Amt: amountToStake, - OutputOwners: *changeOwner, - }, - } - - stakeOutputs = append(stakeOutputs, stakeOut) - - addedFees, err = financeOutput(feeCalc, stakeOut) - if err != nil { - return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) - } - amountsToBurn[avaxAssetID] += addedFees - } - - if remainingAmount := amountAvalibleToStake - amountToStake; remainingAmount > 0 { - // This input had extra value, so some of it must be returned, once fees are removed - changeOut := &avax.TransferableOutput{ - Asset: utxo.Asset, - Out: &secp256k1fx.TransferOutput{ - OutputOwners: *changeOwner, - }, - } - - // update fees to account for the change output - addedFees, err = financeOutput(feeCalc, changeOut) - if err != nil { - return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) - } - - if assetID != avaxAssetID { - changeOut.Out.(*secp256k1fx.TransferOutput).Amt = remainingAmount - amountsToBurn[avaxAssetID] += addedFees - changeOutputs = append(changeOutputs, changeOut) - } else { - // here assetID == b.backend.AVAXAssetID() - switch { - case addedFees < remainingAmount: - changeOut.Out.(*secp256k1fx.TransferOutput).Amt = remainingAmount - addedFees - changeOutputs = append(changeOutputs, changeOut) - case addedFees >= remainingAmount: - amountsToBurn[assetID] += addedFees - remainingAmount - } - } - } - } - - for assetID, amount := range amountsToStake { - if amount != 0 { - return nil, nil, nil, fmt.Errorf( - "%w: provided UTXOs need %d more units of asset %q to stake", - errInsufficientFunds, - amount, - assetID, - ) - } - } - for assetID, amount := range amountsToBurn { - if amount != 0 { - return nil, nil, nil, fmt.Errorf( - "%w: provided UTXOs need %d more units of asset %q", - errInsufficientFunds, - amount, - assetID, - ) - } - } - - utils.Sort(inputs) // sort inputs - avax.SortTransferableOutputs(changeOutputs, txs.Codec) // sort the change outputs - avax.SortTransferableOutputs(stakeOutputs, txs.Codec) // sort stake outputs - return inputs, changeOutputs, stakeOutputs, nil -} - -func financeInput(feeCalc *fees.Calculator, input *avax.TransferableInput) (uint64, error) { - insDimensions, err := commonfees.GetInputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) - if err != nil { - return 0, fmt.Errorf("failed calculating input size: %w", err) - } - addedFees, err := feeCalc.AddFeesFor(insDimensions) - if err != nil { - return 0, fmt.Errorf("account for input fees: %w", err) - } - return addedFees, nil -} - -func financeOutput(feeCalc *fees.Calculator, output *avax.TransferableOutput) (uint64, error) { - outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{output}) - if err != nil { - return 0, fmt.Errorf("failed calculating changeOut size: %w", err) - } - addedFees, err := feeCalc.AddFeesFor(outDimensions) - if err != nil { - return 0, fmt.Errorf("account for stakedOut fees: %w", err) - } - return addedFees, nil -} - -func financeCredential(feeCalc *fees.Calculator, inputSigIndices []uint32) (uint64, error) { - credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, inputSigIndices) - if err != nil { - return 0, fmt.Errorf("failed calculating input size: %w", err) - } - addedFees, err := feeCalc.AddFeesFor(credsDimensions) - if err != nil { - return 0, fmt.Errorf("account for input fees: %w", err) - } - return addedFees, nil -} diff --git a/wallet/chain/p/builder_dynamic_fees_test.go b/wallet/chain/p/builder_fees_test.go similarity index 97% rename from wallet/chain/p/builder_dynamic_fees_test.go rename to wallet/chain/p/builder_fees_test.go index 521a0670b62c..a2c11eab249a 100644 --- a/wallet/chain/p/builder_dynamic_fees_test.go +++ b/wallet/chain/p/builder_fees_test.go @@ -86,10 +86,7 @@ func TestBaseTx(t *testing.T) { sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() } - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr), - backend: be, - } + b := NewBuilder(set.Of(utxoAddr), be) { // Post E-Upgrade feeCalc := &fees.Calculator{ @@ -207,10 +204,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { } sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, subnetAuthAddr), - backend: be, - } + b := NewBuilder(set.Of(utxoAddr, subnetAuthAddr), be) { // Post E-Upgrade feeCalc := &fees.Calculator{ @@ -315,10 +309,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { } sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, subnetAuthAddr), - backend: be, - } + b := NewBuilder(set.Of(utxoAddr, subnetAuthAddr), be) { // Post E-Upgrade feeCalc := &fees.Calculator{ @@ -431,10 +422,7 @@ func TestCreateChainTx(t *testing.T) { } sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, subnetAuthAddr), - backend: be, - } + b := NewBuilder(set.Of(utxoAddr, subnetAuthAddr), be) { // Post E-Upgrade feeCalc := &fees.Calculator{ @@ -544,10 +532,7 @@ func TestCreateSubnetTx(t *testing.T) { sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() } - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr), - backend: be, - } + b := NewBuilder(set.Of(utxoAddr), be) { // Post E-Upgrade feeCalc := &fees.Calculator{ @@ -653,10 +638,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { } sbe.EXPECT().GetSubnetOwner(gomock.Any(), gomock.Any()).Return(subnetOwner, nil).AnyTimes() - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, subnetAuthKey.Address()), - backend: be, - } + b := NewBuilder(set.Of(utxoAddr, subnetAuthKey.Address()), be) { // Post E-Upgrade feeCalc := &fees.Calculator{ @@ -768,10 +750,7 @@ func TestImportTx(t *testing.T) { sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() } - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr), - backend: be, - } + b := NewBuilder(set.Of(utxoAddr), be) { // Post E-Upgrade feeCalc := &fees.Calculator{ @@ -885,10 +864,7 @@ func TestExportTx(t *testing.T) { sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() } - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr), - backend: be, - } + b := NewBuilder(set.Of(utxoAddr), be) { // Post E-Upgrade feeCalc := &fees.Calculator{ @@ -1001,10 +977,7 @@ func TestTransformSubnetTx(t *testing.T) { } sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, subnetAuthAddr), - backend: be, - } + b := NewBuilder(set.Of(utxoAddr, subnetAuthAddr), be) { // Post E-Upgrade feeCalc := &fees.Calculator{ @@ -1145,10 +1118,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() } - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, rewardAddr), - backend: be, - } + b := NewBuilder(set.Of(utxoAddr, rewardAddr), be) { // Post E-Upgrade feeCalc := &fees.Calculator{ @@ -1284,10 +1254,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() } - b := &DynamicFeesBuilder{ - addrs: set.Of(utxoAddr, rewardAddr), - backend: be, - } + b := NewBuilder(set.Of(utxoAddr, rewardAddr), be) { // Post E-Upgrade feeCalc := &fees.Calculator{ diff --git a/wallet/chain/p/builder_with_options.go b/wallet/chain/p/builder_with_options.go index a402355b9e01..4c1e3ac21962 100644 --- a/wallet/chain/p/builder_with_options.go +++ b/wallet/chain/p/builder_with_options.go @@ -10,6 +10,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -57,22 +58,26 @@ func (b *builderWithOptions) NewAddValidatorTx( vdr *txs.Validator, rewardsOwner *secp256k1fx.OutputOwners, shares uint32, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddValidatorTx, error) { return b.Builder.NewAddValidatorTx( vdr, rewardsOwner, shares, + feeCalc, common.UnionOptions(b.options, options)..., ) } func (b *builderWithOptions) NewAddSubnetValidatorTx( vdr *txs.SubnetValidator, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddSubnetValidatorTx, error) { return b.Builder.NewAddSubnetValidatorTx( vdr, + feeCalc, common.UnionOptions(b.options, options)..., ) } @@ -80,11 +85,13 @@ func (b *builderWithOptions) NewAddSubnetValidatorTx( func (b *builderWithOptions) RemoveSubnetValidatorTx( nodeID ids.NodeID, subnetID ids.ID, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.RemoveSubnetValidatorTx, error) { return b.Builder.NewRemoveSubnetValidatorTx( nodeID, subnetID, + feeCalc, common.UnionOptions(b.options, options)..., ) } @@ -92,11 +99,13 @@ func (b *builderWithOptions) RemoveSubnetValidatorTx( func (b *builderWithOptions) NewAddDelegatorTx( vdr *txs.Validator, rewardsOwner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddDelegatorTx, error) { return b.Builder.NewAddDelegatorTx( vdr, rewardsOwner, + feeCalc, common.UnionOptions(b.options, options)..., ) } @@ -107,6 +116,7 @@ func (b *builderWithOptions) NewCreateChainTx( vmID ids.ID, fxIDs []ids.ID, chainName string, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.CreateChainTx, error) { return b.Builder.NewCreateChainTx( @@ -115,16 +125,19 @@ func (b *builderWithOptions) NewCreateChainTx( vmID, fxIDs, chainName, + feeCalc, common.UnionOptions(b.options, options)..., ) } func (b *builderWithOptions) NewCreateSubnetTx( owner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.CreateSubnetTx, error) { return b.Builder.NewCreateSubnetTx( owner, + feeCalc, common.UnionOptions(b.options, options)..., ) } @@ -132,11 +145,13 @@ func (b *builderWithOptions) NewCreateSubnetTx( func (b *builderWithOptions) NewTransferSubnetOwnershipTx( subnetID ids.ID, owner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.TransferSubnetOwnershipTx, error) { return b.Builder.NewTransferSubnetOwnershipTx( subnetID, owner, + feeCalc, common.UnionOptions(b.options, options)..., ) } @@ -144,11 +159,13 @@ func (b *builderWithOptions) NewTransferSubnetOwnershipTx( func (b *builderWithOptions) NewImportTx( sourceChainID ids.ID, to *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.ImportTx, error) { return b.Builder.NewImportTx( sourceChainID, to, + feeCalc, common.UnionOptions(b.options, options)..., ) } @@ -156,11 +173,13 @@ func (b *builderWithOptions) NewImportTx( func (b *builderWithOptions) NewExportTx( chainID ids.ID, outputs []*avax.TransferableOutput, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.ExportTx, error) { return b.Builder.NewExportTx( chainID, outputs, + feeCalc, common.UnionOptions(b.options, options)..., ) } @@ -180,6 +199,7 @@ func (b *builderWithOptions) NewTransformSubnetTx( minDelegatorStake uint64, maxValidatorWeightFactor byte, uptimeRequirement uint32, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.TransformSubnetTx, error) { return b.Builder.NewTransformSubnetTx( @@ -197,6 +217,7 @@ func (b *builderWithOptions) NewTransformSubnetTx( minDelegatorStake, maxValidatorWeightFactor, uptimeRequirement, + feeCalc, common.UnionOptions(b.options, options)..., ) } @@ -208,6 +229,7 @@ func (b *builderWithOptions) NewAddPermissionlessValidatorTx( validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, shares uint32, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddPermissionlessValidatorTx, error) { return b.Builder.NewAddPermissionlessValidatorTx( @@ -217,6 +239,7 @@ func (b *builderWithOptions) NewAddPermissionlessValidatorTx( validationRewardsOwner, delegationRewardsOwner, shares, + feeCalc, common.UnionOptions(b.options, options)..., ) } @@ -225,12 +248,14 @@ func (b *builderWithOptions) NewAddPermissionlessDelegatorTx( vdr *txs.SubnetValidator, assetID ids.ID, rewardsOwner *secp256k1fx.OutputOwners, + feeCalc *fees.Calculator, options ...common.Option, ) (*txs.AddPermissionlessDelegatorTx, error) { return b.Builder.NewAddPermissionlessDelegatorTx( vdr, assetID, rewardsOwner, + feeCalc, common.UnionOptions(b.options, options)..., ) } diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 4a486d8a28ac..0eeebc4d7732 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -264,17 +264,15 @@ type Wallet interface { func NewWallet( builder Builder, - dynFeesBuilder *DynamicFeesBuilder, signer Signer, client platformvm.Client, backend Backend, ) Wallet { return &wallet{ - Backend: backend, - builder: builder, - dynamicBuilder: dynFeesBuilder, - signer: signer, - client: client, + Backend: backend, + builder: builder, + signer: signer, + client: client, } } @@ -285,7 +283,6 @@ type wallet struct { isEForkActive bool builder Builder - dynamicBuilder *DynamicFeesBuilder unitFees, unitCaps commonfees.Dimensions } @@ -320,9 +317,9 @@ func (w *wallet) IssueBaseTx( } ) if w.isEForkActive { - utx, err = w.dynamicBuilder.NewBaseTx(outputs, feeCalc, options...) + utx, err = w.builder.NewBaseTx(outputs, feeCalc, options...) } else { - utx, err = w.dynamicBuilder.newBaseTxPreEUpgrade(outputs, feeCalc, options...) + utx, err = w.builder.newBaseTxPreEUpgrade(outputs, feeCalc, options...) } if err != nil { return nil, err @@ -336,7 +333,21 @@ func (w *wallet) IssueAddValidatorTx( shares uint32, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewAddValidatorTx(vdr, rewardsOwner, shares, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + AddPrimaryNetworkValidatorFee: w.AddPrimaryNetworkValidatorFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + + utx, err := w.builder.NewAddValidatorTx(vdr, rewardsOwner, shares, feeCalc, options...) if err != nil { return nil, err } @@ -361,7 +372,7 @@ func (w *wallet) IssueAddSubnetValidatorTx( ConsumedUnitsCap: w.unitCaps, } - utx, err := w.dynamicBuilder.NewAddSubnetValidatorTx(vdr, feeCalc, options...) + utx, err := w.builder.NewAddSubnetValidatorTx(vdr, feeCalc, options...) if err != nil { return nil, err } @@ -387,7 +398,7 @@ func (w *wallet) IssueRemoveSubnetValidatorTx( ConsumedUnitsCap: w.unitCaps, } - utx, err := w.dynamicBuilder.NewRemoveSubnetValidatorTx(nodeID, subnetID, feeCalc, options...) + utx, err := w.builder.NewRemoveSubnetValidatorTx(nodeID, subnetID, feeCalc, options...) if err != nil { return nil, err } @@ -399,7 +410,21 @@ func (w *wallet) IssueAddDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - utx, err := w.builder.NewAddDelegatorTx(vdr, rewardsOwner, options...) + if err := w.refreshFork(options...); err != nil { + return nil, err + } + + feesMan := commonfees.NewManager(w.unitFees) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: w.isEForkActive, + Config: &config.Config{ + AddPrimaryNetworkDelegatorFee: w.AddPrimaryNetworkDelegatorFee(), + }, + FeeManager: feesMan, + ConsumedUnitsCap: w.unitCaps, + } + + utx, err := w.builder.NewAddDelegatorTx(vdr, rewardsOwner, feeCalc, options...) if err != nil { return nil, err } @@ -428,7 +453,7 @@ func (w *wallet) IssueCreateChainTx( ConsumedUnitsCap: w.unitCaps, } - utx, err := w.dynamicBuilder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, feeCalc, options...) + utx, err := w.builder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, feeCalc, options...) if err != nil { return nil, err } @@ -452,7 +477,7 @@ func (w *wallet) IssueCreateSubnetTx( FeeManager: feesMan, ConsumedUnitsCap: w.unitCaps, } - utx, err := w.dynamicBuilder.NewCreateSubnetTx(owner, feeCalc, options...) + utx, err := w.builder.NewCreateSubnetTx(owner, feeCalc, options...) if err != nil { return nil, err } @@ -479,7 +504,7 @@ func (w *wallet) IssueTransferSubnetOwnershipTx( ConsumedUnitsCap: w.unitCaps, } - utx, err := w.dynamicBuilder.NewTransferSubnetOwnershipTx(subnetID, owner, feeCalc, options...) + utx, err := w.builder.NewTransferSubnetOwnershipTx(subnetID, owner, feeCalc, options...) if err != nil { return nil, err } @@ -505,7 +530,7 @@ func (w *wallet) IssueImportTx( ConsumedUnitsCap: w.unitCaps, } - utx, err := w.dynamicBuilder.NewImportTx(sourceChainID, to, feeCalc, options...) + utx, err := w.builder.NewImportTx(sourceChainID, to, feeCalc, options...) if err != nil { return nil, err } @@ -531,7 +556,7 @@ func (w *wallet) IssueExportTx( ConsumedUnitsCap: w.unitCaps, } - utx, err := w.dynamicBuilder.NewExportTx(chainID, outputs, feeCalc, options...) + utx, err := w.builder.NewExportTx(chainID, outputs, feeCalc, options...) if err != nil { return nil, err } @@ -568,7 +593,7 @@ func (w *wallet) IssueTransformSubnetTx( FeeManager: feesMan, ConsumedUnitsCap: w.unitCaps, } - utx, err := w.dynamicBuilder.NewTransformSubnetTx( + utx, err := w.builder.NewTransformSubnetTx( subnetID, assetID, initialSupply, @@ -616,7 +641,7 @@ func (w *wallet) IssueAddPermissionlessValidatorTx( ConsumedUnitsCap: w.unitCaps, } - utx, err := w.dynamicBuilder.NewAddPermissionlessValidatorTx( + utx, err := w.builder.NewAddPermissionlessValidatorTx( vdr, signer, assetID, @@ -653,7 +678,7 @@ func (w *wallet) IssueAddPermissionlessDelegatorTx( ConsumedUnitsCap: w.unitCaps, } - utx, err := w.dynamicBuilder.NewAddPermissionlessDelegatorTx( + utx, err := w.builder.NewAddPermissionlessDelegatorTx( vdr, assetID, rewardsOwner, diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 0825ab1b370f..3bb3e9965684 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -119,7 +119,6 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { pUTXOs := NewChainUTXOs(constants.PlatformChainID, avaxState.UTXOs) pBackend := p.NewBackend(avaxState.PCTX, pUTXOs, pChainTxs) pBuilder := p.NewBuilder(avaxAddrs, pBackend) - pDynamicFeesBuilder := p.NewDynamicFeesBuilder(avaxAddrs, pBackend) pSigner := p.NewSigner(config.AVAXKeychain, pBackend) xChainID := avaxState.XCTX.BlockchainID() @@ -135,7 +134,7 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( - p.NewWallet(pBuilder, pDynamicFeesBuilder, pSigner, avaxState.PClient, pBackend), + p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil From 50c2ab92207fd927858ad66e4216d16eddadf3de Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 7 Feb 2024 22:40:05 +0100 Subject: [PATCH 012/120] nit --- wallet/chain/p/builder.go | 64 +++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 156186083766..5d0d432f889d 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -366,7 +366,7 @@ func (b *builder) NewBaseTx( utx.Ins = inputs utx.Outs = outputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) newBaseTxPreEUpgrade( @@ -406,7 +406,7 @@ func (b *builder) newBaseTxPreEUpgrade( utx.Ins = inputs utx.Outs = outputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) NewAddValidatorTx( @@ -450,7 +450,7 @@ func (b *builder) NewAddValidatorTx( utx.Outs = outputs utx.StakeOuts = stakeOutputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) NewAddSubnetValidatorTx( @@ -460,7 +460,7 @@ func (b *builder) NewAddSubnetValidatorTx( ) (*txs.AddSubnetValidatorTx, error) { ops := common.NewOptions(options) - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, vdr.Subnet, ops) + subnetAuth, err := b.authorizeSubnet(vdr.Subnet, ops) if err != nil { return nil, err } @@ -497,7 +497,7 @@ func (b *builder) NewAddSubnetValidatorTx( utx.Ins = inputs utx.Outs = outputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) NewRemoveSubnetValidatorTx( @@ -508,7 +508,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( ) (*txs.RemoveSubnetValidatorTx, error) { ops := common.NewOptions(options) - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) + subnetAuth, err := b.authorizeSubnet(subnetID, ops) if err != nil { return nil, err } @@ -545,7 +545,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( utx.Ins = inputs utx.Outs = outputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) NewAddDelegatorTx( @@ -587,7 +587,7 @@ func (b *builder) NewAddDelegatorTx( utx.Outs = outputs utx.StakeOuts = stakeOutputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) NewCreateChainTx( @@ -601,14 +601,14 @@ func (b *builder) NewCreateChainTx( ) (*txs.CreateChainTx, error) { // 1. Build core transaction without utxos ops := common.NewOptions(options) - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) + subnetAuth, err := b.authorizeSubnet(subnetID, ops) if err != nil { return nil, err } utils.Sort(fxIDs) - uTx := &txs.CreateChainTx{ + utx := &txs.CreateChainTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -632,7 +632,7 @@ func (b *builder) NewCreateChainTx( } // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.CreateChainTx(uTx); err != nil { + if err = feeCalc.CreateChainTx(utx); err != nil { return nil, err } @@ -641,10 +641,10 @@ func (b *builder) NewCreateChainTx( return nil, err } - uTx.Ins = inputs - uTx.Outs = outputs + utx.Ins = inputs + utx.Outs = outputs - return uTx, initCtx(b.backend, uTx) + return utx, b.initCtx(utx) } func (b *builder) NewCreateSubnetTx( @@ -681,7 +681,7 @@ func (b *builder) NewCreateSubnetTx( utx.Ins = inputs utx.Outs = outputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) NewTransferSubnetOwnershipTx( @@ -692,7 +692,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( ) (*txs.TransferSubnetOwnershipTx, error) { // 1. Build core transaction without utxos ops := common.NewOptions(options) - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) + subnetAuth, err := b.authorizeSubnet(subnetID, ops) if err != nil { return nil, err } @@ -730,7 +730,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( utx.Ins = inputs utx.Outs = outputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) NewImportTx( @@ -841,7 +841,7 @@ func (b *builder) NewImportTx( case importedAVAX == feeCalc.Fee: // imported inputs match exactly the fees to be paid avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) case importedAVAX < feeCalc.Fee: // imported inputs can partially pay fees @@ -870,12 +870,12 @@ func (b *builder) NewImportTx( changeOut.Out.(*secp256k1fx.TransferOutput).Amt = importedAVAX - feeCalc.Fee utx.Outs = append(utx.Outs, changeOut) avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) case feeCalc.Fee == importedAVAX: // imported fees pays exactly the tx cost. We don't include the outputs avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) default: // imported avax are not enough to pay fees @@ -897,7 +897,7 @@ func (b *builder) NewImportTx( utx.Ins = inputs utx.Outs = append(utx.Outs, changeOuts...) avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) NewExportTx( @@ -945,7 +945,7 @@ func (b *builder) NewExportTx( utx.Ins = inputs utx.Outs = changeOuts - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) NewTransformSubnetTx( @@ -969,7 +969,7 @@ func (b *builder) NewTransformSubnetTx( // 1. Build core transaction without utxos ops := common.NewOptions(options) - subnetAuth, err := authorizeSubnet(b.backend, b.addrs, subnetID, ops) + subnetAuth, err := b.authorizeSubnet(subnetID, ops) if err != nil { return nil, err } @@ -1021,7 +1021,7 @@ func (b *builder) NewTransformSubnetTx( utx.Ins = inputs utx.Outs = outputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) NewAddPermissionlessValidatorTx( @@ -1072,7 +1072,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( utx.Outs = outputs utx.StakeOuts = stakeOutputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) NewAddPermissionlessDelegatorTx( @@ -1116,7 +1116,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( utx.Outs = outputs utx.StakeOuts = stakeOutputs - return utx, initCtx(b.backend, utx) + return utx, b.initCtx(utx) } func (b *builder) getBalance( @@ -1519,13 +1519,11 @@ func financeCredential(feeCalc *fees.Calculator, inputSigIndices []uint32) (uint return addedFees, nil } -func authorizeSubnet( - backend BuilderBackend, - addresses set.Set[ids.ShortID], +func (b *builder) authorizeSubnet( subnetID ids.ID, options *common.Options, ) (*secp256k1fx.Input, error) { - ownerIntf, err := backend.GetSubnetOwner(options.Context(), subnetID) + ownerIntf, err := b.backend.GetSubnetOwner(options.Context(), subnetID) if err != nil { return nil, fmt.Errorf( "failed to fetch subnet owner for %q: %w", @@ -1538,7 +1536,7 @@ func authorizeSubnet( return nil, errUnknownOwnerType } - addrs := options.Addresses(addresses) + addrs := options.Addresses(b.addrs) minIssuanceTime := options.MinIssuanceTime() inputSigIndices, ok := common.MatchOwners(owner, addrs, minIssuanceTime) if !ok { @@ -1550,8 +1548,8 @@ func authorizeSubnet( }, nil } -func initCtx(backend BuilderBackend, tx txs.UnsignedTx) error { - ctx, err := newSnowContext(backend) +func (b *builder) initCtx(tx txs.UnsignedTx) error { + ctx, err := newSnowContext(b.backend) if err != nil { return err } From 6ae1419f2f2c53eba83e165fd8af1817eac5a156 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 7 Feb 2024 23:51:11 +0100 Subject: [PATCH 013/120] wip: cleaning up p-chain tx builder --- vms/platformvm/txs/builder/builder.go | 800 +++++++++--------- .../txs/executor/create_chain_test.go | 13 +- .../txs/executor/create_subnet_test.go | 13 +- vms/platformvm/utxo/handler.go | 20 +- vms/platformvm/vm_regression_test.go | 206 +---- 5 files changed, 491 insertions(+), 561 deletions(-) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 04144a737cbb..5fa2e3aa09ae 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -339,117 +339,94 @@ func (b *builder) NewImportTx( } var ( - ins []*avax.TransferableInput + importedAVAX = importedAmounts[b.ctx.AVAXAssetID] // the only entry left in importedAmounts + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - importedAVAX = importedAmounts[b.ctx.AVAXAssetID] // the only entry left in importedAmounts - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) + ins []*avax.TransferableInput ) - if isEForkActive { - // while outs are not ordered we add them to get current fees. We'll fix ordering later on - utx.BaseTx.Outs = outs - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.ImportTx(utx); err != nil { - return nil, err + // while outs are not ordered we add them to get current fees. We'll fix ordering later on + utx.BaseTx.Outs = outs + + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, } + } - if feeCalc.Fee >= importedAVAX { - // all imported avax will be burned to pay taxes. - // Fees are scaled back accordingly. - feeCalc.Fee -= importedAVAX - } else { - // imported inputs may be enough to pay taxes by themselves - changeOut := &avax.TransferableOutput{ - Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - // Amt: importedAVAX, // SET IT AFTER CONSIDERING ITS OWN FEES - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{to}, - }, - }, - } + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.ImportTx(utx); err != nil { + return nil, err + } - // update fees to target given the extra input added - outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) - if err != nil { - return nil, fmt.Errorf("failed calculating output size: %w", err) - } - addedFees, err := feeCalc.AddFeesFor(outDimensions) - if err != nil { - return nil, fmt.Errorf("account for output fees: %w", err) - } + if feeCalc.Fee >= importedAVAX { + // all imported avax will be burned to pay taxes. + // Fees are scaled back accordingly. + feeCalc.Fee -= importedAVAX + } else { + // imported inputs may be enough to pay taxes by themselves + changeOut := &avax.TransferableOutput{ + Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ // we set amount after considering changeOut own fees + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{to}, + }, + }, + } - if addedFees >= importedAVAX { - // imported avax are not enough to pay fees - // Drop the changeOut and finance the tx - if _, err := feeCalc.RemoveFeesFor(outDimensions); err != nil { - return nil, fmt.Errorf("failed reverting change output: %w", err) - } - feeCalc.Fee -= importedAVAX - - var ( - financeOut []*avax.TransferableOutput - financeSigner [][]*secp256k1.PrivateKey - ) - ins, financeOut, _, financeSigner, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - outs = append(financeOut, outs...) - signers = append(financeSigner, signers...) - } else { - changeOut.Out.(*secp256k1fx.TransferOutput).Amt = importedAVAX - feeCalc.Fee - outs = append(outs, changeOut) - } + // update fees to target given the extra output added + outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) + if err != nil { + return nil, fmt.Errorf("failed calculating output size: %w", err) } - } else { - switch { - case importedAVAX < b.cfg.TxFee: // imported amount goes toward paying tx fee - var ( - baseOuts []*avax.TransferableOutput - baseSigners [][]*secp256k1.PrivateKey - ) - ins, baseOuts, _, baseSigners, err = b.Spend(b.state, keys, 0, b.cfg.TxFee-importedAVAX, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + if _, err := feeCalc.AddFeesFor(outDimensions); err != nil { + return nil, fmt.Errorf("account for output fees: %w", err) + } + + if feeCalc.Fee >= importedAVAX { + // imported avax are not enough to pay fees + // Drop the changeOut and finance the tx + if _, err := feeCalc.RemoveFeesFor(outDimensions); err != nil { + return nil, fmt.Errorf("failed reverting change output: %w", err) } - outs = append(baseOuts, outs...) - signers = append(baseSigners, signers...) - delete(importedAmounts, b.ctx.AVAXAssetID) - case importedAVAX == b.cfg.TxFee: - delete(importedAmounts, b.ctx.AVAXAssetID) - default: - importedAVAX -= b.cfg.TxFee - outs = append(outs, &avax.TransferableOutput{ - Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: importedAVAX, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{to}, - }, - }, - }) + feeCalc.Fee -= importedAVAX + } else { + feeCalc.Fee = 0 + changeOut.Out.(*secp256k1fx.TransferOutput).Amt = importedAVAX - feeCalc.Fee + outs = append(outs, changeOut) } } + var ( + financeOut []*avax.TransferableOutput + financeSigner [][]*secp256k1.PrivateKey + ) + ins, financeOut, _, financeSigner, err = b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + outs = append(financeOut, outs...) + signers = append(financeSigner, signers...) + avax.SortTransferableOutputs(outs, txs.Codec) // sort imported outputs utx.BaseTx.Ins = ins @@ -493,42 +470,38 @@ func (b *builder) NewExportTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) - ins []*avax.TransferableInput - outs []*avax.TransferableOutput - signers [][]*secp256k1.PrivateKey - err error + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) ) - if isEForkActive { - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.ExportTx(utx); err != nil { - return nil, err + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, } + } - ins, outs, _, signers, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - } else { - var toBurn uint64 - toBurn, err = math.Add64(amount, b.cfg.TxFee) - if err != nil { - return nil, fmt.Errorf("amount (%d) + tx fee(%d) overflows", amount, b.cfg.TxFee) - } - ins, outs, _, signers, err = b.Spend(b.state, keys, 0, toBurn, changeAddr) + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.ExportTx(utx); err != nil { + return nil, err } + feeCalc.Fee += amount // account for the transferred amount to be burned + + ins, outs, _, signers, err := b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -576,38 +549,37 @@ func (b *builder) NewCreateChainTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) - ins []*avax.TransferableInput - outs []*avax.TransferableOutput - signers [][]*secp256k1.PrivateKey + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) ) - if isEForkActive { - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.CreateChainTx(utx); err != nil { - return nil, err + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, } + } - ins, outs, _, signers, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - } else { - timestamp := b.state.GetTimestamp() - createBlockchainTxFee := b.cfg.GetCreateBlockchainTxFee(timestamp) - ins, outs, _, signers, err = b.Spend(b.state, keys, 0, createBlockchainTxFee, changeAddr) + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.CreateChainTx(utx); err != nil { + return nil, err } + + ins, outs, _, signers, err := b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -646,38 +618,37 @@ func (b *builder) NewCreateSubnetTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) - ins []*avax.TransferableInput - outs []*avax.TransferableOutput - signers [][]*secp256k1.PrivateKey - err error + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) ) - if isEForkActive { - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err := feeCalc.CreateSubnetTx(utx); err != nil { - return nil, err + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, } + } - ins, outs, _, signers, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - } else { - createSubnetTxFee := b.cfg.GetCreateSubnetTxFee(chainTime) - ins, outs, _, signers, err = b.Spend(b.state, keys, 0, createSubnetTxFee, changeAddr) + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.CreateSubnetTx(utx); err != nil { + return nil, err } + + ins, outs, _, signers, err := b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -703,17 +674,10 @@ func (b *builder) NewAddValidatorTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - ins, unstakedOuts, stakedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkValidatorFee, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - // Create the tx + // 1. Build core transaction without utxos utx := &txs.AddValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, + NetworkID: b.ctx.NetworkID, }}, Validator: txs.Validator{ NodeID: nodeID, @@ -721,7 +685,6 @@ func (b *builder) NewAddValidatorTx( End: endTime, Wght: stakeAmount, }, - StakeOuts: stakedOuts, RewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, @@ -729,6 +692,49 @@ func (b *builder) NewAddValidatorTx( }, DelegationShares: shares, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) + ) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddValidatorTx(utx); err != nil { + return nil, err + } + + ins, outs, stakeOuts, signers, err := b.FinanceTx( + b.state, + keys, + stakeAmount, + feeCalc, + changeAddr, + ) + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + utx.StakeOuts = stakeOuts + + // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -776,38 +782,37 @@ func (b *builder) NewAddPermissionlessValidatorTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) - ins []*avax.TransferableInput - outs []*avax.TransferableOutput - stakeOuts []*avax.TransferableOutput - signers [][]*secp256k1.PrivateKey - err error + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) ) - if isEForkActive { - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.AddPermissionlessValidatorTx(utx); err != nil { - return nil, err + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, } + } - ins, outs, _, signers, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - } else { - ins, outs, stakeOuts, signers, err = b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkValidatorFee, changeAddr) + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddPermissionlessValidatorTx(utx); err != nil { + return nil, err } + + ins, outs, stakeOuts, signers, err := b.FinanceTx( + b.state, + keys, + stakeAmount, + feeCalc, + changeAddr, + ) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -833,17 +838,11 @@ func (b *builder) NewAddDelegatorTx( keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, ) (*txs.Tx, error) { - ins, unlockedOuts, lockedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkDelegatorFee, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - // Create the tx + // 1. Build core transaction without utxos utx := &txs.AddDelegatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: unlockedOuts, }}, Validator: txs.Validator{ NodeID: nodeID, @@ -851,13 +850,55 @@ func (b *builder) NewAddDelegatorTx( End: endTime, Wght: stakeAmount, }, - StakeOuts: lockedOuts, DelegationRewardsOwner: &secp256k1fx.OutputOwners{ Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{rewardAddress}, }, } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) + ) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + } + } + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddDelegatorTx(utx); err != nil { + return nil, err + } + + ins, outs, stakeOuts, signers, err := b.FinanceTx( + b.state, + keys, + stakeAmount, + feeCalc, + changeAddr, + ) + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + utx.StakeOuts = stakeOuts + + // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) if err != nil { return nil, err @@ -896,38 +937,37 @@ func (b *builder) NewAddPermissionlessDelegatorTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) - ins []*avax.TransferableInput - outs []*avax.TransferableOutput - stakeOuts []*avax.TransferableOutput - signers [][]*secp256k1.PrivateKey - err error + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) ) - if isEForkActive { - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.AddPermissionlessDelegatorTx(utx); err != nil { - return nil, err + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, } + } - ins, outs, _, signers, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - } else { - ins, outs, stakeOuts, signers, err = b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkDelegatorFee, changeAddr) + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.AddPermissionlessDelegatorTx(utx); err != nil { + return nil, err } + + ins, outs, stakeOuts, signers, err := b.FinanceTx( + b.state, + keys, + stakeAmount, + feeCalc, + changeAddr, + ) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -977,36 +1017,37 @@ func (b *builder) NewAddSubnetValidatorTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) - ins []*avax.TransferableInput - outs []*avax.TransferableOutput - signers [][]*secp256k1.PrivateKey + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) ) - if isEForkActive { - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.AddSubnetValidatorTx(utx); err != nil { - return nil, err + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, } + } - ins, outs, _, signers, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - } else { - ins, outs, _, signers, err = b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.AddSubnetValidatorTx(utx); err != nil { + return nil, err } + + ins, outs, _, signers, err := b.FinanceTx( + b.state, + keys, + weight, + feeCalc, + changeAddr, + ) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -1046,36 +1087,37 @@ func (b *builder) NewRemoveSubnetValidatorTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) - ins []*avax.TransferableInput - outs []*avax.TransferableOutput - signers [][]*secp256k1.PrivateKey + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) ) - if isEForkActive { - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.RemoveSubnetValidatorTx(utx); err != nil { - return nil, err + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, } + } - ins, outs, _, signers, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - } else { - ins, outs, _, signers, err = b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.RemoveSubnetValidatorTx(utx); err != nil { + return nil, err } + + ins, outs, _, signers, err := b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -1119,36 +1161,37 @@ func (b *builder) NewTransferSubnetOwnershipTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) - ins []*avax.TransferableInput - outs []*avax.TransferableOutput - signers [][]*secp256k1.PrivateKey + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) ) - if isEForkActive { - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.TransferSubnetOwnershipTx(utx); err != nil { - return nil, err + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, } + } - ins, outs, _, signers, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - } else { - ins, outs, _, signers, err = b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err = feeCalc.TransferSubnetOwnershipTx(utx); err != nil { + return nil, err } + + ins, outs, _, signers, err := b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -1176,63 +1219,58 @@ func (b *builder) NewBaseTx( BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, + Outs: []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: amount, + OutputOwners: owner, + }, + }}, // not sorted yet, we'll sort later on when we have all the outputs }, } // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( - chainTime = b.state.GetTimestamp() - isEForkActive = b.cfg.IsEUpgradeActivated(chainTime) - ins []*avax.TransferableInput - outs []*avax.TransferableOutput - signers [][]*secp256k1.PrivateKey - err error + chainTime = b.state.GetTimestamp() + feeCfg = config.EUpgradeDynamicFeesConfig + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) ) - if isEForkActive { - feeCfg := config.EUpgradeDynamicFeesConfig - feeCalc := &fees.Calculator{ - IsEUpgradeActive: isEForkActive, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: txs.EmptyCredentials(signers), - } - // feesMan cumulates consumed units. Let's init it with utx filled so far - if err = feeCalc.BaseTx(utx); err != nil { - return nil, err + feeCalc := &fees.Calculator{ + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + if !isEUpgradeActive { + feeCalc = &fees.Calculator{ + IsEUpgradeActive: false, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, } + } - ins, outs, _, signers, err = b.FinanceTx( - b.state, - keys, - 0, - feeCalc, - changeAddr, - ) - } else { - var toBurn uint64 - toBurn, err = math.Add64(amount, b.cfg.TxFee) - if err != nil { - return nil, fmt.Errorf("amount (%d) + tx fee(%d) overflows", amount, b.cfg.TxFee) - } - ins, outs, _, signers, err = b.Spend(b.state, keys, 0, toBurn, changeAddr) + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.BaseTx(utx); err != nil { + return nil, err } + feeCalc.Fee += amount // account for the transferred amount to be burned + + ins, outs, _, signers, err := b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } - outs = append(outs, &avax.TransferableOutput{ - Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: amount, - OutputOwners: owner, - }, - }) - - avax.SortTransferableOutputs(outs, txs.Codec) - utx.BaseTx.Ins = ins - utx.BaseTx.Outs = outs + utx.Outs = append(utx.Outs, outs...) + avax.SortTransferableOutputs(utx.Outs, txs.Codec) // 3. Sign the tx tx, err := txs.NewSigned(utx, txs.Codec, signers) diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index eabf9d3f9239..f6943e66773d 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/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/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -200,7 +201,17 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.config.ApricotPhase3Time = ap3Time - ins, outs, _, signers, err := env.utxosHandler.Spend(env.state, preFundedKeys, 0, test.fee, ids.ShortEmpty) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: env.config, + ChainTime: test.time, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + + Fee: test.fee, + } + + ins, outs, _, signers, err := env.utxosHandler.FinanceTx(env.state, preFundedKeys, 0, feeCalc, ids.ShortEmpty) require.NoError(err) subnetAuth, subnetSigners, err := env.utxosHandler.Authorize(env.state, testSubnet1.ID(), preFundedKeys) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index d084fe473506..a23882f0b9ee 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -14,6 +14,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/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -56,7 +57,17 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - ins, outs, _, signers, err := env.utxosHandler.Spend(env.state, preFundedKeys, 0, test.fee, ids.ShortEmpty) + feeCalc := &fees.Calculator{ + IsEUpgradeActive: false, + Config: env.config, + ChainTime: test.time, + FeeManager: commonfees.NewManager(commonfees.Empty), + ConsumedUnitsCap: commonfees.Max, + + Fee: test.fee, + } + + ins, outs, _, signers, err := env.utxosHandler.FinanceTx(env.state, preFundedKeys, 0, feeCalc, ids.ShortEmpty) require.NoError(err) // Create the tx diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index c2179f921ad3..f716dddd0eb5 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -75,7 +75,7 @@ type Spender interface { FinanceTx( utxoReader avax.UTXOReader, keys []*secp256k1.PrivateKey, - amount uint64, + amountToStake uint64, feeCalc *fees.Calculator, changeAddr ids.ShortID, ) ( @@ -410,7 +410,7 @@ func (h *handler) Spend( func (h *handler) FinanceTx( utxoReader avax.UTXOReader, keys []*secp256k1.PrivateKey, - amount uint64, + amountToStake uint64, feeCalc *fees.Calculator, changeAddr ids.ShortID, ) ( @@ -448,7 +448,7 @@ func (h *handler) FinanceTx( for _, utxo := range utxos { // If we have consumed more AVAX than we are trying to stake, then we // have no need to consume more locked AVAX - if amountStaked >= amount { + if amountStaked >= amountToStake { break } @@ -512,8 +512,8 @@ func (h *handler) FinanceTx( // Stake any value that should be staked amountToStake := math.Min( - amount-amountStaked, // Amount we still need to stake - remainingValue, // Amount available to stake + amountToStake-amountStaked, // Amount we still need to stake + remainingValue, // Amount available to stake ) amountStaked += amountToStake remainingValue -= amountToStake @@ -585,7 +585,7 @@ func (h *handler) FinanceTx( // If we have consumed more AVAX than we are trying to stake, // and we have burned more AVAX than we need to, // then we have no need to consume more AVAX - if amountBurned >= targetFee && amountStaked >= amount { + if amountBurned >= targetFee && amountStaked >= amountToStake { break } @@ -646,8 +646,8 @@ func (h *handler) FinanceTx( // Stake any value that should be staked amountToStake := math.Min( - amount-amountStaked, // Amount we still need to stake - remainingValue, // Amount available to stake + amountToStake-amountStaked, // Amount we still need to stake + remainingValue, // Amount available to stake ) amountStaked += amountToStake remainingValue -= amountToStake @@ -731,10 +731,10 @@ func (h *handler) FinanceTx( signers = append(signers, inSigners) } - if amountBurned < targetFee || amountStaked < amount { + if amountBurned < targetFee || amountStaked < amountToStake { return nil, nil, nil, nil, fmt.Errorf( "%w (unlocked, locked) (%d, %d) but need (%d, %d)", - ErrInsufficientFunds, amountBurned, amountStaked, targetFee, amount, + ErrInsufficientFunds, amountBurned, amountStaked, targetFee, amountToStake, ) } diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 4335ae460034..f8805303d0a0 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -46,7 +46,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/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" @@ -1481,51 +1480,19 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) // build primary network validator with BLS key - utxoHandler := utxo.NewHandler(vm.ctx, &vm.clock, vm.fx) - ins, unstakedOuts, stakedOuts, signers, err := utxoHandler.Spend( - vm.state, - keys, + primaryTx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( vm.MinValidatorStake, - vm.Config.AddPrimaryNetworkValidatorFee, - addr, // change Addresss + uint64(primaryStartTime.Unix()), + uint64(primaryEndTime.Unix()), + nodeID, + signer.NewProofOfPossession(sk1), + addr, // reward address + reward.PercentDenominator, + keys, + addr, // change address ) require.NoError(err) - - uPrimaryTx := &txs.AddPermissionlessValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: vm.ctx.NetworkID, - BlockchainID: vm.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Validator: txs.Validator{ - NodeID: nodeID, - Start: uint64(primaryStartTime.Unix()), - End: uint64(primaryEndTime.Unix()), - Wght: vm.MinValidatorStake, - }, - Subnet: constants.PrimaryNetworkID, - Signer: signer.NewProofOfPossession(sk1), - StakeOuts: stakedOuts, - ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - addr, - }, - }, - DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - addr, - }, - }, - DelegationShares: reward.PercentDenominator, - } - primaryTx, err := txs.NewSigned(uPrimaryTx, txs.Codec, signers) - require.NoError(err) - require.NoError(primaryTx.SyntacticVerify(vm.ctx)) + uPrimaryTx := primaryTx.Unsigned.(*txs.AddPermissionlessValidatorTx) vm.ctx.Lock.Unlock() require.NoError(vm.issueTx(context.Background(), primaryTx)) @@ -1617,50 +1584,19 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) require.NotEqual(sk1, sk2) - ins, unstakedOuts, stakedOuts, signers, err = utxoHandler.Spend( - vm.state, - keys, + primaryRestartTx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( vm.MinValidatorStake, - vm.Config.AddPrimaryNetworkValidatorFee, - addr, // change Addresss + uint64(primaryReStartTime.Unix()), + uint64(primaryReEndTime.Unix()), + nodeID, + signer.NewProofOfPossession(sk2), + addr, // reward address + reward.PercentDenominator, + keys, + addr, // change address ) require.NoError(err) - - uPrimaryRestartTx := &txs.AddPermissionlessValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: vm.ctx.NetworkID, - BlockchainID: vm.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Validator: txs.Validator{ - NodeID: nodeID, - Start: uint64(primaryReStartTime.Unix()), - End: uint64(primaryReEndTime.Unix()), - Wght: vm.MinValidatorStake, - }, - Subnet: constants.PrimaryNetworkID, - Signer: signer.NewProofOfPossession(sk2), - StakeOuts: stakedOuts, - ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - addr, - }, - }, - DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - addr, - }, - }, - DelegationShares: reward.PercentDenominator, - } - primaryRestartTx, err := txs.NewSigned(uPrimaryRestartTx, txs.Codec, signers) - require.NoError(err) - require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) + uPrimaryRestartTx := primaryRestartTx.Unsigned.(*txs.AddPermissionlessValidatorTx) vm.ctx.Lock.Unlock() require.NoError(vm.issueTx(context.Background(), primaryRestartTx)) @@ -1816,52 +1752,19 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { sk2, err := bls.NewSecretKey() require.NoError(err) - utxoHandler := utxo.NewHandler(vm.ctx, &vm.clock, vm.fx) - ins, unstakedOuts, stakedOuts, signers, err := utxoHandler.Spend( - vm.state, - keys, + primaryRestartTx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( vm.MinValidatorStake, - vm.Config.AddPrimaryNetworkValidatorFee, - addr, // change Addresss + uint64(primaryStartTime2.Unix()), + uint64(primaryEndTime2.Unix()), + nodeID, + signer.NewProofOfPossession(sk2), + addr, // reward address + reward.PercentDenominator, + keys, + addr, // change address ) require.NoError(err) - uPrimaryRestartTx := &txs.AddPermissionlessValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: vm.ctx.NetworkID, - BlockchainID: vm.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Validator: txs.Validator{ - NodeID: nodeID, - Start: uint64(primaryStartTime2.Unix()), - End: uint64(primaryEndTime2.Unix()), - Wght: vm.MinValidatorStake, - }, - Subnet: constants.PrimaryNetworkID, - Signer: signer.NewProofOfPossession(sk2), - StakeOuts: stakedOuts, - ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - addr, - }, - }, - DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - addr, - }, - }, - DelegationShares: reward.PercentDenominator, - } - primaryRestartTx, err := txs.NewSigned(uPrimaryRestartTx, txs.Codec, signers) - require.NoError(err) - require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) - vm.ctx.Lock.Unlock() require.NoError(vm.issueTx(context.Background(), primaryRestartTx)) vm.ctx.Lock.Lock() @@ -2021,52 +1924,19 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { sk2, err := bls.NewSecretKey() require.NoError(err) - utxoHandler := utxo.NewHandler(vm.ctx, &vm.clock, vm.fx) - ins, unstakedOuts, stakedOuts, signers, err := utxoHandler.Spend( - vm.state, - keys, + primaryRestartTx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( vm.MinValidatorStake, - vm.Config.AddPrimaryNetworkValidatorFee, - addr, // change Addresss + uint64(primaryStartTime2.Unix()), + uint64(primaryEndTime2.Unix()), + nodeID, + signer.NewProofOfPossession(sk2), + addr, // reward address + reward.PercentDenominator, + keys, + addr, // change address ) require.NoError(err) - uPrimaryRestartTx := &txs.AddPermissionlessValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: vm.ctx.NetworkID, - BlockchainID: vm.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Validator: txs.Validator{ - NodeID: nodeID, - Start: uint64(primaryStartTime2.Unix()), - End: uint64(primaryEndTime2.Unix()), - Wght: vm.MinValidatorStake, - }, - Subnet: constants.PrimaryNetworkID, - Signer: signer.NewProofOfPossession(sk2), - StakeOuts: stakedOuts, - ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - addr, - }, - }, - DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - addr, - }, - }, - DelegationShares: reward.PercentDenominator, - } - primaryRestartTx, err := txs.NewSigned(uPrimaryRestartTx, txs.Codec, signers) - require.NoError(err) - require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) - vm.ctx.Lock.Unlock() require.NoError(vm.issueTx(context.Background(), primaryRestartTx)) vm.ctx.Lock.Lock() From 0be756e44fc8419613e23a9682753df9fa6cbd33 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 8 Feb 2024 13:09:19 +0100 Subject: [PATCH 014/120] refactored dynamic fees config getter + UTs fix --- vms/platformvm/block/builder/builder.go | 3 +- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/block/executor/manager.go | 3 +- vms/platformvm/block/executor/verifier.go | 3 +- vms/platformvm/config/config.go | 8 + vms/platformvm/config/dynamic_fees_config.go | 27 ++- vms/platformvm/txs/builder/builder.go | 224 ++++++------------ .../txs/executor/atomic_tx_executor.go | 6 +- .../txs/executor/create_chain_test.go | 30 ++- .../txs/executor/create_subnet_test.go | 10 +- vms/platformvm/txs/executor/helpers_test.go | 7 +- .../txs/executor/standard_tx_executor_test.go | 186 +++++++++------ wallet/chain/p/builder.go | 6 +- wallet/chain/p/wallet.go | 4 +- 15 files changed, 253 insertions(+), 268 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 85122ec7d77a..fbefedb93a0d 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -20,7 +20,6 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -351,7 +350,7 @@ func packBlockTxs( } var ( - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = backend.Config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) feeMan = fees.NewManager(feeCfg.UnitFees) blockTxs []*txs.Tx diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index c46fb1163a23..d02a02f9941a 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -254,7 +254,7 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(genesisID, env.blkManager) require.NoError(err) - feeCfg := config.EUpgradeDynamicFeesConfig + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := txexecutor.StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index a49dfe9af778..a946fdad2c81 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -275,7 +275,7 @@ func addSubnet(env *environment) { panic(err) } - feeCfg := config.EUpgradeDynamicFeesConfig + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := executor.StandardTxExecutor{ Backend: env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index cc6b72a2813e..6f249054a0cb 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -11,7 +11,6 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -144,7 +143,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - feesCfg := config.EUpgradeDynamicFeesConfig + feesCfg := m.txExecutorBackend.Config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) err = tx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: m.txExecutorBackend, BlkFeeManager: fees.NewManager(feesCfg.UnitFees), diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index e4f325912cc6..afd2a74a2a0d 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -12,7 +12,6 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -440,7 +439,7 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID error, ) { var ( - feesCfg = config.EUpgradeDynamicFeesConfig + feesCfg = v.txExecutorBackend.Config.GetDynamicFeesConfig(state.GetTimestamp()) onAcceptFunc func() inputs set.Set[ids.ID] diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 91927e0b44f4..9c7c5a0995ae 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -144,6 +144,14 @@ func (c *Config) IsEUpgradeActivated(timestamp time.Time) bool { return !timestamp.Before(c.EUpgradeTime) } +func (c *Config) GetDynamicFeesConfig(timestamp time.Time) DynamicFeesConfig { + if !c.IsEUpgradeActivated(timestamp) { + return PreEUpgradeDynamicFeesConfig + } + + return EUpgradeDynamicFeesConfig +} + func (c *Config) GetCreateBlockchainTxFee(timestamp time.Time) uint64 { if c.IsApricotPhase3Activated(timestamp) { return c.CreateBlockchainTxFee diff --git a/vms/platformvm/config/dynamic_fees_config.go b/vms/platformvm/config/dynamic_fees_config.go index 4c4f58f97d0d..b41e3b33b366 100644 --- a/vms/platformvm/config/dynamic_fees_config.go +++ b/vms/platformvm/config/dynamic_fees_config.go @@ -15,16 +15,23 @@ import ( // so to have fork control over which dynamic fees is picked // EUpgradeDynamicFeesConfig to be tuned TODO ABENEGIA -var EUpgradeDynamicFeesConfig = DynamicFeesConfig{ - UnitFees: commonfees.Dimensions{ - 1, - 2, - 3, - 4, - }, - - BlockUnitsCap: commonfees.Max, -} +var ( + EUpgradeDynamicFeesConfig = DynamicFeesConfig{ + UnitFees: commonfees.Dimensions{ + 1, + 2, + 3, + 4, + }, + + BlockUnitsCap: commonfees.Max, + } + + PreEUpgradeDynamicFeesConfig = DynamicFeesConfig{ + UnitFees: commonfees.Empty, + BlockUnitsCap: commonfees.Max, + } +) type DynamicFeesConfig struct { // UnitFees contains, per each fee dimension, the diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 5fa2e3aa09ae..5a180d06643d 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -341,30 +341,23 @@ func (b *builder) NewImportTx( var ( importedAVAX = importedAmounts[b.ctx.AVAXAssetID] // the only entry left in importedAmounts chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) + feeCalc = &fees.Calculator{ + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + ins []*avax.TransferableInput ) // while outs are not ordered we add them to get current fees. We'll fix ordering later on utx.BaseTx.Outs = outs - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { - feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, - } - } - // feesMan cumulates consumed units. Let's init it with utx filled so far if err = feeCalc.ImportTx(utx); err != nil { return nil, err @@ -404,8 +397,8 @@ func (b *builder) NewImportTx( } feeCalc.Fee -= importedAVAX } else { - feeCalc.Fee = 0 changeOut.Out.(*secp256k1fx.TransferOutput).Amt = importedAVAX - feeCalc.Fee + feeCalc.Fee = 0 outs = append(outs, changeOut) } } @@ -471,23 +464,17 @@ func (b *builder) NewExportTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - ) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { + feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEUpgradeActive: isEUpgradeActive, Config: b.cfg, ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, } - } + ) // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.ExportTx(utx); err != nil { @@ -550,23 +537,17 @@ func (b *builder) NewCreateChainTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - ) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { + feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEUpgradeActive: isEUpgradeActive, Config: b.cfg, ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, } - } + ) // feesMan cumulates consumed units. Let's init it with utx filled so far if err = feeCalc.CreateChainTx(utx); err != nil { @@ -619,23 +600,17 @@ func (b *builder) NewCreateSubnetTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - ) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { + feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEUpgradeActive: isEUpgradeActive, Config: b.cfg, ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, } - } + ) // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.CreateSubnetTx(utx); err != nil { @@ -696,23 +671,17 @@ func (b *builder) NewAddValidatorTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - ) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { + feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEUpgradeActive: isEUpgradeActive, Config: b.cfg, ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, } - } + ) // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.AddValidatorTx(utx); err != nil { @@ -783,23 +752,17 @@ func (b *builder) NewAddPermissionlessValidatorTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - ) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { + feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEUpgradeActive: isEUpgradeActive, Config: b.cfg, ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, } - } + ) // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.AddPermissionlessValidatorTx(utx); err != nil { @@ -860,23 +823,17 @@ func (b *builder) NewAddDelegatorTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - ) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { + feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEUpgradeActive: isEUpgradeActive, Config: b.cfg, ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, } - } + ) // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.AddDelegatorTx(utx); err != nil { @@ -938,23 +895,17 @@ func (b *builder) NewAddPermissionlessDelegatorTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - ) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { + feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEUpgradeActive: isEUpgradeActive, Config: b.cfg, ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, } - } + ) // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.AddPermissionlessDelegatorTx(utx); err != nil { @@ -1018,23 +969,17 @@ func (b *builder) NewAddSubnetValidatorTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - ) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { + feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEUpgradeActive: isEUpgradeActive, Config: b.cfg, ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, } - } + ) // feesMan cumulates consumed units. Let's init it with utx filled so far if err = feeCalc.AddSubnetValidatorTx(utx); err != nil { @@ -1088,23 +1033,17 @@ func (b *builder) NewRemoveSubnetValidatorTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - ) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { + feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEUpgradeActive: isEUpgradeActive, Config: b.cfg, ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, } - } + ) // feesMan cumulates consumed units. Let's init it with utx filled so far if err = feeCalc.RemoveSubnetValidatorTx(utx); err != nil { @@ -1162,23 +1101,17 @@ func (b *builder) NewTransferSubnetOwnershipTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - ) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { + feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEUpgradeActive: isEUpgradeActive, Config: b.cfg, ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, } - } + ) // feesMan cumulates consumed units. Let's init it with utx filled so far if err = feeCalc.TransferSubnetOwnershipTx(utx); err != nil { @@ -1232,24 +1165,17 @@ func (b *builder) NewBaseTx( // 2. Finance the tx by building the utxos (inputs, outputs and stakes) var ( chainTime = b.state.GetTimestamp() - feeCfg = config.EUpgradeDynamicFeesConfig + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) - ) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - } - if !isEUpgradeActive { feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEUpgradeActive: isEUpgradeActive, Config: b.cfg, ChainTime: chainTime, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, } - } + ) // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.BaseTx(utx); err != nil { diff --git a/vms/platformvm/txs/executor/atomic_tx_executor.go b/vms/platformvm/txs/executor/atomic_tx_executor.go index a00d8381d7db..3a6ddcf0662a 100644 --- a/vms/platformvm/txs/executor/atomic_tx_executor.go +++ b/vms/platformvm/txs/executor/atomic_tx_executor.go @@ -7,6 +7,7 @@ import ( "github.com/ava-labs/avalanchego/chains/atomic" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -100,10 +101,11 @@ func (e *AtomicTxExecutor) atomicTx(tx txs.UnsignedTx) error { } e.OnAccept = onAccept + feesCfg := config.PreEUpgradeDynamicFeesConfig executor := StandardTxExecutor{ Backend: e.Backend, - BlkFeeManager: commonfees.NewManager(commonfees.Empty), - UnitCaps: commonfees.Empty, + BlkFeeManager: commonfees.NewManager(feesCfg.UnitFees), + UnitCaps: feesCfg.BlockUnitsCap, State: e.OnAccept, Tx: e.Tx, } diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index f6943e66773d..30ea4b4c1b27 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -49,10 +49,11 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(commonfees.Empty), - UnitCaps: commonfees.Empty, + BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: stateDiff, Tx: tx, } @@ -90,10 +91,11 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(commonfees.Empty), - UnitCaps: commonfees.Empty, + BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: stateDiff, Tx: tx, } @@ -125,10 +127,11 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(commonfees.Empty), - UnitCaps: commonfees.Empty, + BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: stateDiff, Tx: tx, } @@ -157,10 +160,11 @@ func TestCreateChainTxValid(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(commonfees.Empty), - UnitCaps: commonfees.Empty, + BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: stateDiff, Tx: tx, } @@ -201,12 +205,13 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.config.ApricotPhase3Time = ap3Time + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) feeCalc := &fees.Calculator{ IsEUpgradeActive: false, Config: env.config, ChainTime: test.time, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, Fee: test.fee, } @@ -240,10 +245,11 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) + feeCfg = env.config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(commonfees.Empty), - UnitCaps: commonfees.Empty, + BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: stateDiff, Tx: tx, } diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index a23882f0b9ee..6f84d572f7ee 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -57,12 +57,13 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) feeCalc := &fees.Calculator{ IsEUpgradeActive: false, Config: env.config, ChainTime: test.time, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, Fee: test.fee, } @@ -88,10 +89,11 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) + feeCfg = env.config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(commonfees.Empty), - UnitCaps: commonfees.Empty, + BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: stateDiff, Tx: tx, } diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 489741cdec2a..ed00917942d1 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -35,7 +35,6 @@ 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/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" @@ -47,6 +46,8 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) const ( @@ -229,10 +230,10 @@ func addSubnet( stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := config.EUpgradeDynamicFeesConfig + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), UnitCaps: feeCfg.BlockUnitsCap, State: stateDiff, Tx: testSubnet1, diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 43d2498391ec..6a3dab926bb2 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -90,10 +90,11 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: stateDiff, Tx: tx, } @@ -348,10 +349,11 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { freshTH.config.BanffTime = onAcceptState.GetTimestamp() + feeCfg := freshTH.config.GetDynamicFeesConfig(freshTH.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &freshTH.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -388,10 +390,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -418,10 +421,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -462,10 +466,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -507,10 +512,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -535,10 +541,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -562,10 +569,12 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -592,10 +601,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -650,10 +660,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: duplicateSubnetTx, } @@ -689,10 +700,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -724,10 +736,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -757,10 +770,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -800,10 +814,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -837,10 +852,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -865,10 +881,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -906,10 +923,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutCurrentValidator(staker) onAcceptState.AddTx(tx, status.Committed) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -944,10 +962,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutPendingValidator(staker) onAcceptState.AddTx(tx, status.Committed) + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -981,10 +1000,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.DeleteUTXO(utxoID) } + feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, State: onAcceptState, Tx: tx, } @@ -1774,7 +1794,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).AnyTimes().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) @@ -1792,6 +1812,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { DurangoTime: env.latestForkTime, EUpgradeTime: mockable.MaxTime, } + feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1800,8 +1821,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -1824,6 +1845,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { DurangoTime: env.latestForkTime, EUpgradeTime: mockable.MaxTime, } + + feeCfg := cfg.GetDynamicFeesConfig(time.Time{}) // pre E upgrade e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1832,8 +1855,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -1847,7 +1870,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).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) @@ -1857,6 +1880,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { DurangoTime: env.latestForkTime, EUpgradeTime: mockable.MaxTime, } + feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1865,8 +1889,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -1884,7 +1908,7 @@ 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).AnyTimes() env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(&staker, nil).Times(1) cfg := &config.Config{ @@ -1893,6 +1917,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { DurangoTime: env.latestForkTime, EUpgradeTime: mockable.MaxTime, } + feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1901,8 +1926,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -1918,7 +1943,7 @@ 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).AnyTimes() env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) cfg := &config.Config{ @@ -1927,6 +1952,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { DurangoTime: env.latestForkTime, EUpgradeTime: mockable.MaxTime, } + feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1935,8 +1961,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -1950,7 +1976,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).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) @@ -1960,6 +1986,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { DurangoTime: env.latestForkTime, EUpgradeTime: mockable.MaxTime, } + feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1968,8 +1995,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -1983,7 +2010,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).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) @@ -1995,6 +2022,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { DurangoTime: env.latestForkTime, EUpgradeTime: mockable.MaxTime, } + feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2003,8 +2031,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -2018,7 +2046,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).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) @@ -2033,6 +2061,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { DurangoTime: env.latestForkTime, EUpgradeTime: mockable.MaxTime, } + feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2041,8 +2070,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -2195,6 +2224,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { DurangoTime: env.latestForkTime, EUpgradeTime: mockable.MaxTime, } + feeCfg := cfg.GetDynamicFeesConfig(time.Time{}) // pre E-upgrade e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2203,8 +2233,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -2226,7 +2256,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { DurangoTime: env.latestForkTime, EUpgradeTime: mockable.MaxTime, } - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() + feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2235,8 +2266,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -2260,7 +2291,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { EUpgradeTime: mockable.MaxTime, MaxStakeDuration: math.MaxInt64, } - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime) + env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() + feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2269,8 +2301,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -2285,7 +2317,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).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) @@ -2300,6 +2332,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { EUpgradeTime: mockable.MaxTime, MaxStakeDuration: math.MaxInt64, } + + feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2308,8 +2342,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } @@ -2325,7 +2359,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).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) @@ -2344,6 +2378,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { EUpgradeTime: mockable.MaxTime, MaxStakeDuration: math.MaxInt64, } + + feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2352,8 +2388,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(fees.Empty), - UnitCaps: fees.Empty, + BlkFeeManager: fees.NewManager(feeCfg.UnitFees), + UnitCaps: feeCfg.BlockUnitsCap, Tx: env.tx, State: env.state, } diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 5d0d432f889d..397428e252ce 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -751,7 +751,7 @@ func (b *builder) NewImportTx( } // 2. Add imported inputs first - utxos, err := b.backend.UTXOs(ops.Context(), sourceChainID) + importedUtxos, err := b.backend.UTXOs(ops.Context(), sourceChainID) if err != nil { return nil, err } @@ -761,12 +761,12 @@ func (b *builder) NewImportTx( minIssuanceTime = ops.MinIssuanceTime() avaxAssetID = b.backend.AVAXAssetID() - importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) + importedInputs = make([]*avax.TransferableInput, 0, len(importedUtxos)) importedSigIndices = make([][]uint32, 0) importedAmounts = make(map[ids.ID]uint64) ) - for _, utxo := range utxos { + for _, utxo := range importedUtxos { out, ok := utxo.Out.(*secp256k1fx.TransferOutput) if !ok { continue diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 0eeebc4d7732..ef8ed6b9d3cd 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -762,8 +762,8 @@ func (w *wallet) refreshFork(options ...common.Option) error { w.unitFees = config.EUpgradeDynamicFeesConfig.UnitFees w.unitCaps = config.EUpgradeDynamicFeesConfig.BlockUnitsCap } else { - w.unitFees = commonfees.Empty - w.unitCaps = commonfees.Max + w.unitFees = config.PreEUpgradeDynamicFeesConfig.UnitFees + w.unitCaps = config.PreEUpgradeDynamicFeesConfig.BlockUnitsCap } return nil From 126fdc2e5607d198bcea031ac85754c45dd798d4 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 8 Feb 2024 15:03:42 +0100 Subject: [PATCH 015/120] minor cleanup of txs.Tx credentials --- vms/platformvm/txs/tx.go | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/vms/platformvm/txs/tx.go b/vms/platformvm/txs/tx.go index c33f67c8cba3..9874f66e0468 100644 --- a/vms/platformvm/txs/tx.go +++ b/vms/platformvm/txs/tx.go @@ -138,10 +138,8 @@ func (tx *Tx) Sign(c codec.Manager, signers [][]*secp256k1.PrivateKey) error { } // Attach credentials - tx.Creds = EmptyCredentials(signers) - hash := hashing.ComputeHash256(unsignedBytes) - for i, keys := range signers { + for _, keys := range signers { cred := &secp256k1fx.Credential{ Sigs: make([][secp256k1.SignatureLen]byte, len(keys)), } @@ -152,7 +150,7 @@ func (tx *Tx) Sign(c codec.Manager, signers [][]*secp256k1.PrivateKey) error { } copy(cred.Sigs[i][:], sig) } - tx.Creds[i] = cred // Attach credential + tx.Creds = append(tx.Creds, cred) // Attach credential } signedBytes, err := c.Marshal(CodecVersion, tx) @@ -162,13 +160,3 @@ func (tx *Tx) Sign(c codec.Manager, signers [][]*secp256k1.PrivateKey) error { tx.SetBytes(unsignedBytes, signedBytes) return nil } - -func EmptyCredentials(signers [][]*secp256k1.PrivateKey) []verify.Verifiable { - creds := make([]verify.Verifiable, 0, len(signers)) - for i := 0; i < len(signers); i++ { - creds = append(creds, &secp256k1fx.Credential{ - Sigs: make([][secp256k1.SignatureLen]byte, len(signers)), - }) - } - return creds -} From 572aed5589c15a91f5832f3606d1875fe8857500 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 8 Feb 2024 17:23:17 +0100 Subject: [PATCH 016/120] txBuilder added memo field --- vms/platformvm/block/builder/builder_test.go | 9 +++ vms/platformvm/block/builder/helpers_test.go | 1 + .../block/builder/standard_block_test.go | 1 + vms/platformvm/block/executor/helpers_test.go | 2 + .../block/executor/proposal_block_test.go | 16 ++++ .../block/executor/standard_block_test.go | 5 ++ vms/platformvm/service.go | 7 ++ vms/platformvm/service_test.go | 8 ++ vms/platformvm/txs/builder/builder.go | 74 +++++++++++++++---- .../txs/executor/advance_time_test.go | 7 ++ .../txs/executor/create_chain_test.go | 4 + vms/platformvm/txs/executor/export_test.go | 1 + vms/platformvm/txs/executor/helpers_test.go | 1 + vms/platformvm/txs/executor/import_test.go | 1 + .../txs/executor/proposal_tx_executor_test.go | 21 ++++++ .../txs/executor/reward_validator_test.go | 8 ++ .../txs/executor/standard_tx_executor_test.go | 30 +++++++- vms/platformvm/validator_set_property_test.go | 3 + vms/platformvm/vm_regression_test.go | 37 ++++++++++ vms/platformvm/vm_test.go | 21 ++++++ 20 files changed, 239 insertions(+), 18 deletions(-) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 56f189cb986a..955cdb75924b 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -46,6 +46,7 @@ func TestBuildBlockBasic(t *testing.T) { "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) txID := tx.ID() @@ -119,6 +120,7 @@ func TestBuildBlockShouldReward(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, preFundedKeys[0].PublicKey().Address(), + nil, ) require.NoError(err) txID := tx.ID() @@ -239,6 +241,7 @@ func TestBuildBlockForceAdvanceTime(t *testing.T) { "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) txID := tx.ID() @@ -306,6 +309,7 @@ func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, preFundedKeys[0].PublicKey().Address(), + nil, ) require.NoError(err) require.NoError(env.mempool.Add(tx1)) @@ -326,6 +330,7 @@ func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[1]}, preFundedKeys[1].PublicKey().Address(), + nil, ) require.NoError(err) require.NoError(env.mempool.Add(tx2)) @@ -346,6 +351,7 @@ func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[2]}, preFundedKeys[2].PublicKey().Address(), + nil, ) require.NoError(err) require.NoError(env.mempool.Add(tx3)) @@ -412,6 +418,7 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, preFundedKeys[0].PublicKey().Address(), + nil, ) require.NoError(err) require.NoError(env.mempool.Add(tx1)) @@ -435,6 +442,7 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[2]}, preFundedKeys[2].PublicKey().Address(), + nil, ) require.NoError(err) require.NoError(env.mempool.Add(tx2)) @@ -480,6 +488,7 @@ func TestPreviouslyDroppedTxsCannotBeReAddedToMempool(t *testing.T) { "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) txID := tx.ID() diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index d02a02f9941a..964f43b8db3c 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -246,6 +246,7 @@ func addSubnet(t *testing.T, env *environment) { }, []*secp256k1.PrivateKey{preFundedKeys[0]}, preFundedKeys[0].PublicKey().Address(), + nil, ) require.NoError(err) diff --git a/vms/platformvm/block/builder/standard_block_test.go b/vms/platformvm/block/builder/standard_block_test.go index 6064b2153113..26d87c9ba216 100644 --- a/vms/platformvm/block/builder/standard_block_test.go +++ b/vms/platformvm/block/builder/standard_block_test.go @@ -67,6 +67,7 @@ func TestAtomicTxImports(t *testing.T) { recipientKey.PublicKey().Address(), []*secp256k1.PrivateKey{recipientKey}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index a946fdad2c81..42d1a977fb2d 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -263,6 +263,7 @@ func addSubnet(env *environment) { }, []*secp256k1.PrivateKey{preFundedKeys[0]}, preFundedKeys[0].PublicKey().Address(), + nil, ) if err != nil { panic(err) @@ -474,6 +475,7 @@ func addPendingValidator( reward.PercentDenominator, keys, ids.ShortEmpty, + nil, ) if err != nil { return nil, err diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 118cece1937f..3d2e79a2c9da 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -567,6 +567,7 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -590,6 +591,7 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -619,6 +621,7 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -719,6 +722,7 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -747,6 +751,7 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -778,6 +783,7 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -861,6 +867,7 @@ func TestBanffProposalBlockTrackedSubnet(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -890,6 +897,7 @@ func TestBanffProposalBlockTrackedSubnet(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -976,6 +984,7 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -1044,6 +1053,7 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { preFundedKeys[4], }, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -1070,6 +1080,7 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -1160,6 +1171,7 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -1227,6 +1239,7 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { preFundedKeys[4], }, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -1253,6 +1266,7 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -1338,6 +1352,7 @@ func TestAddValidatorProposalBlock(t *testing.T) { preFundedKeys[4], }, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -1413,6 +1428,7 @@ func TestAddValidatorProposalBlock(t *testing.T) { preFundedKeys[4], }, ids.ShortEmpty, + nil, ) require.NoError(err) diff --git a/vms/platformvm/block/executor/standard_block_test.go b/vms/platformvm/block/executor/standard_block_test.go index 63dc7b2646c7..e91c4b7e0703 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -522,6 +522,7 @@ func TestBanffStandardBlockUpdateStakers(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -612,6 +613,7 @@ func TestBanffStandardBlockRemoveSubnetValidator(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -640,6 +642,7 @@ func TestBanffStandardBlockRemoveSubnetValidator(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -710,6 +713,7 @@ func TestBanffStandardBlockTrackedSubnet(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -805,6 +809,7 @@ func TestBanffStandardBlockDelegatorStakerWeight(t *testing.T) { preFundedKeys[4], }, ids.ShortEmpty, + nil, ) require.NoError(err) diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index 16e5b16844c6..8eedd6c8eb6d 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -1289,6 +1289,7 @@ func (s *Service) buildAddValidatorTx(args *AddValidatorArgs) (*txs.Tx, ids.Shor uint32(10000*args.DelegationFeeRate), // Shares privKeys.Keys, // Keys providing the staked tokens changeAddr, + nil, ) if err != nil { return nil, ids.ShortEmpty, err @@ -1407,6 +1408,7 @@ func (s *Service) buildAddDelegatorTx(args *AddDelegatorArgs) (*txs.Tx, ids.Shor rewardAddress, // Reward Address privKeys.Keys, // Private keys changeAddr, // Change address + nil, // Memo ) if err != nil { return nil, ids.ShortEmpty, err @@ -1521,6 +1523,7 @@ func (s *Service) buildAddSubnetValidatorTx(args *AddSubnetValidatorArgs) (*txs. subnetID, // Subnet ID keys.Keys, changeAddr, + nil, ) if err != nil { return nil, ids.ShortEmpty, err @@ -1605,6 +1608,7 @@ func (s *Service) buildCreateSubnetTx(args *CreateSubnetArgs) (*txs.Tx, ids.Shor controlKeys.List(), // Control Addresses privKeys.Keys, // Private keys changeAddr, + nil, ) if err != nil { return nil, ids.ShortEmpty, err @@ -1709,6 +1713,7 @@ func (s *Service) buildExportAVAX(args *ExportAVAXArgs) (*txs.Tx, ids.ShortID, e to, // Address privKeys.Keys, // Private keys changeAddr, // Change address + nil, ) if err != nil { return nil, ids.ShortEmpty, err @@ -1802,6 +1807,7 @@ func (s *Service) buildImportAVAXTx(args *ImportAVAXArgs) (*txs.Tx, ids.ShortID, to, privKeys.Keys, changeAddr, + nil, ) if err != nil { return nil, ids.ShortEmpty, err @@ -1934,6 +1940,7 @@ func (s *Service) buildCreateBlockchainTx(args *CreateBlockchainArgs) (*txs.Tx, args.Name, keys.Keys, changeAddr, // Change address + nil, ) if err != nil { return nil, ids.ShortEmpty, err diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 20789d441422..9b231a871024 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -211,6 +211,7 @@ func TestGetTxStatus(t *testing.T) { ids.ShortEmpty, []*secp256k1.PrivateKey{recipientKey}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -263,6 +264,7 @@ func TestGetTx(t *testing.T) { "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, keys[0].PublicKey().Address(), // change addr + nil, ) }, }, @@ -282,6 +284,7 @@ func TestGetTx(t *testing.T) { 0, []*secp256k1.PrivateKey{keys[0]}, keys[0].PublicKey().Address(), // change addr + nil, ) }, }, @@ -294,6 +297,7 @@ func TestGetTx(t *testing.T) { ids.GenerateTestShortID(), []*secp256k1.PrivateKey{keys[0]}, keys[0].PublicKey().Address(), // change addr + nil, ) }, }, @@ -482,6 +486,7 @@ func TestGetStake(t *testing.T) { ids.GenerateTestShortID(), []*secp256k1.PrivateKey{keys[0]}, keys[0].PublicKey().Address(), // change addr + nil, ) require.NoError(err) @@ -537,6 +542,7 @@ func TestGetStake(t *testing.T) { 0, []*secp256k1.PrivateKey{keys[0]}, keys[0].PublicKey().Address(), // change addr + nil, ) require.NoError(err) @@ -615,6 +621,7 @@ func TestGetCurrentValidators(t *testing.T) { ids.GenerateTestShortID(), []*secp256k1.PrivateKey{keys[0]}, keys[0].PublicKey().Address(), // change addr + nil, ) require.NoError(err) @@ -748,6 +755,7 @@ func TestGetBlock(t *testing.T) { "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, keys[0].PublicKey().Address(), // change addr + nil, ) require.NoError(err) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 5a180d06643d..1f928a3166fc 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -52,6 +52,7 @@ type AtomicTxBuilder interface { to ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) // amount: amount of tokens to export @@ -65,6 +66,7 @@ type AtomicTxBuilder interface { to ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) } @@ -84,6 +86,7 @@ type DecisionTxBuilder interface { chainName string, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) // threshold: [threshold] of [ownerAddrs] needed to manage this subnet @@ -95,6 +98,7 @@ type DecisionTxBuilder interface { ownerAddrs []ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) // amount: amount the sender is sending @@ -106,6 +110,7 @@ type DecisionTxBuilder interface { owner secp256k1fx.OutputOwners, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) } @@ -127,6 +132,7 @@ type ProposalTxBuilder interface { shares uint32, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) // stakeAmount: amount the validator stakes @@ -148,6 +154,7 @@ type ProposalTxBuilder interface { shares uint32, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) // stakeAmount: amount the delegator stakes @@ -165,6 +172,7 @@ type ProposalTxBuilder interface { rewardAddress ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) // stakeAmount: amount the delegator stakes @@ -182,6 +190,7 @@ type ProposalTxBuilder interface { rewardAddress ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) // weight: sampling weight of the new validator @@ -199,6 +208,7 @@ type ProposalTxBuilder interface { subnetID ids.ID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) // Creates a transaction that removes [nodeID] @@ -210,6 +220,7 @@ type ProposalTxBuilder interface { subnetID ids.ID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) // Creates a transaction that transfers ownership of [subnetID] @@ -223,6 +234,7 @@ type ProposalTxBuilder interface { ownerAddrs []ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) } @@ -262,12 +274,14 @@ func (b *builder) NewImportTx( to ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos utx := &txs.ImportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, + Memo: memo, }}, SourceChain: from, } @@ -440,12 +454,14 @@ func (b *builder) NewExportTx( to ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos utx := &txs.ExportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, + Memo: memo, }}, DestinationChain: chainID, ExportedOutputs: []*avax.TransferableOutput{{ // Exported to X-Chain @@ -512,6 +528,7 @@ func (b *builder) NewCreateChainTx( chainName string, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) @@ -525,6 +542,7 @@ func (b *builder) NewCreateChainTx( BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, + Memo: memo, }}, SubnetID: subnetID, ChainName: chainName, @@ -582,6 +600,7 @@ func (b *builder) NewCreateSubnetTx( ownerAddrs []ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos utils.Sort(ownerAddrs) // sort control addresses @@ -590,6 +609,7 @@ func (b *builder) NewCreateSubnetTx( BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, + Memo: memo, }}, Owner: &secp256k1fx.OutputOwners{ Threshold: threshold, @@ -648,12 +668,16 @@ func (b *builder) NewAddValidatorTx( shares uint32, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos utx := &txs.AddValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - }}, + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: b.ctx.NetworkID, + Memo: memo, + }, + }, Validator: txs.Validator{ NodeID: nodeID, Start: startTime, @@ -721,12 +745,14 @@ func (b *builder) NewAddPermissionlessValidatorTx( shares uint32, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos utx := &txs.AddPermissionlessValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, + Memo: memo, }}, Validator: txs.Validator{ NodeID: nodeID, @@ -800,12 +826,14 @@ func (b *builder) NewAddDelegatorTx( rewardAddress ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos utx := &txs.AddDelegatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, + Memo: memo, }}, Validator: txs.Validator{ NodeID: nodeID, @@ -871,13 +899,17 @@ func (b *builder) NewAddPermissionlessDelegatorTx( rewardAddress ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos utx := &txs.AddPermissionlessDelegatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - }}, + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: b.ctx.NetworkID, + BlockchainID: b.ctx.ChainID, + Memo: memo, + }, + }, Validator: txs.Validator{ NodeID: nodeID, Start: startTime, @@ -943,6 +975,7 @@ func (b *builder) NewAddSubnetValidatorTx( subnetID ids.ID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) @@ -953,6 +986,7 @@ func (b *builder) NewAddSubnetValidatorTx( BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.ctx.NetworkID, BlockchainID: b.ctx.ChainID, + Memo: memo, }}, SubnetValidator: txs.SubnetValidator{ Validator: txs.Validator{ @@ -1014,6 +1048,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( subnetID ids.ID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) @@ -1021,10 +1056,13 @@ func (b *builder) NewRemoveSubnetValidatorTx( return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) } utx := &txs.RemoveSubnetValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - }}, + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: b.ctx.NetworkID, + BlockchainID: b.ctx.ChainID, + Memo: memo, + }, + }, Subnet: subnetID, NodeID: nodeID, SubnetAuth: subnetAuth, @@ -1079,6 +1117,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( ownerAddrs []ids.ShortID, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) @@ -1086,10 +1125,13 @@ func (b *builder) NewTransferSubnetOwnershipTx( return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) } utx := &txs.TransferSubnetOwnershipTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - }}, + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: b.ctx.NetworkID, + BlockchainID: b.ctx.ChainID, + Memo: memo, + }, + }, Subnet: subnetID, SubnetAuth: subnetAuth, Owner: &secp256k1fx.OutputOwners{ @@ -1146,6 +1188,7 @@ func (b *builder) NewBaseTx( owner secp256k1fx.OutputOwners, keys []*secp256k1.PrivateKey, changeAddr ids.ShortID, + memo []byte, ) (*txs.Tx, error) { // 1. Build core transaction without utxos utx := &txs.BaseTx{ @@ -1159,6 +1202,7 @@ func (b *builder) NewBaseTx( OutputOwners: owner, }, }}, // not sorted yet, we'll sort later on when we have all the outputs + Memo: memo, }, } diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index b7b636ad6dbe..167ea5cb8e26 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -383,6 +383,7 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -477,6 +478,7 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -506,6 +508,7 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, // Keys ids.ShortEmpty, // reward address + nil, ) require.NoError(err) @@ -582,6 +585,7 @@ func TestTrackedSubnet(t *testing.T) { subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -688,6 +692,7 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { preFundedKeys[4], }, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -782,6 +787,7 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { preFundedKeys[0].PublicKey().Address(), []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -895,6 +901,7 @@ func addPendingValidator( reward.PercentDenominator, keys, ids.ShortEmpty, + nil, ) if err != nil { return nil, err diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 30ea4b4c1b27..aabadfb93f6a 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -40,6 +40,7 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { "chain name", []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -76,6 +77,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -119,6 +121,7 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -154,6 +157,7 @@ func TestCreateChainTxValid(t *testing.T) { "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index d9e0ce071008..1194b3319d60 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -54,6 +54,7 @@ func TestNewExportTx(t *testing.T) { to, tt.sourceKeys, ids.ShortEmpty, // Change address + nil, ) require.NoError(err) diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index ed00917942d1..0501f13467f5 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -223,6 +223,7 @@ func addSubnet( }, []*secp256k1.PrivateKey{preFundedKeys[0]}, preFundedKeys[0].PublicKey().Address(), + nil, ) require.NoError(err) diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index d513de619d35..e61f66b11020 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -153,6 +153,7 @@ func TestNewImportTx(t *testing.T) { to, tt.sourceKeys, ids.ShortEmpty, + nil, ) require.ErrorIs(err, tt.expectedErr) if tt.expectedErr != nil { diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index e01bd267a024..3cf61c63e6bd 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -43,6 +43,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { reward.PercentDenominator, // Shares []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, + nil, ) require.NoError(t, err) @@ -73,6 +74,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { reward.PercentDenominator, // Shared []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, + nil, ) require.NoError(t, err) @@ -256,6 +258,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { tt.rewardAddress, tt.feeKeys, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -300,6 +303,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -332,6 +336,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -365,6 +370,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { reward.PercentDenominator, // shares []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -378,6 +384,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -425,6 +432,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -455,6 +463,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -485,6 +494,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -517,6 +527,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -549,6 +560,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -576,6 +588,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -609,6 +622,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[2]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -645,6 +659,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], preFundedKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -680,6 +695,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -734,6 +750,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -764,6 +781,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -796,6 +814,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -827,6 +846,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { reward.PercentDenominator, // shares []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -872,6 +892,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) diff --git a/vms/platformvm/txs/executor/reward_validator_test.go b/vms/platformvm/txs/executor/reward_validator_test.go index 18ba653a4e79..a7c3da899df6 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -248,6 +248,7 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { reward.PercentDenominator/4, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -262,6 +263,7 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { delRewardAddress, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, // Change address + nil, ) require.NoError(err) @@ -369,6 +371,7 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { reward.PercentDenominator/4, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, /*=changeAddr*/ + nil, ) require.NoError(err) @@ -383,6 +386,7 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { delRewardAddress, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, /*=changeAddr*/ + nil, ) require.NoError(err) @@ -585,6 +589,7 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * reward.PercentDenominator/4, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -599,6 +604,7 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * delRewardAddress, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, // Change address + nil, ) require.NoError(err) @@ -747,6 +753,7 @@ func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { reward.PercentDenominator/4, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -760,6 +767,7 @@ func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { delRewardAddress, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, + nil, ) require.NoError(err) diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 6a3dab926bb2..e1eeb2bfdd7e 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -84,6 +84,7 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -124,6 +125,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { reward.PercentDenominator, // Shares []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, + nil, ) require.NoError(t, err) @@ -154,6 +156,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { reward.PercentDenominator, // Shared []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, + nil, ) require.NoError(t, err) @@ -337,6 +340,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { tt.rewardAddress, tt.feeKeys, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -384,6 +388,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -415,6 +420,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -447,6 +453,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { reward.PercentDenominator, // shares []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -460,6 +467,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -506,6 +514,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -535,6 +544,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -564,6 +574,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -595,6 +606,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -626,6 +638,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -654,6 +667,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -687,6 +701,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1], testSubnet1ControlKeys[2]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -723,6 +738,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[2]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -759,6 +775,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], preFundedKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -794,6 +811,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -846,6 +864,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -875,6 +894,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -904,7 +924,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { ids.ShortEmpty, reward.PercentDenominator, // shares []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // change addr // key + ids.ShortEmpty, // change addr + nil, // key ) require.NoError(err) @@ -945,8 +966,9 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { nodeID, ids.ShortEmpty, reward.PercentDenominator, // shares - []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // change addr // key + []*secp256k1.PrivateKey{preFundedKeys[0]}, // key + ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -986,6 +1008,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -1391,6 +1414,7 @@ func TestDurangoMemoField(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, + nil, ) require.NoError(t, err) diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 1cc68bcc1553..d838eb730205 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -260,6 +260,7 @@ func addSubnetValidator(vm *VM, data *validatorInputData, subnetID ids.ID) (*sta subnetID, []*secp256k1.PrivateKey{keys[0], keys[1]}, addr, + nil, ) if err != nil { return nil, fmt.Errorf("could not create AddSubnetValidatorTx: %w", err) @@ -285,6 +286,7 @@ func addPrimaryValidatorWithBLSKey(vm *VM, data *validatorInputData) (*state.Sta reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, addr, + nil, ) if err != nil { return nil, fmt.Errorf("could not create AddPermissionlessValidatorTx: %w", err) @@ -681,6 +683,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { []ids.ShortID{keys[0].PublicKey().Address()}, []*secp256k1.PrivateKey{keys[len(keys)-1]}, // pays tx fee keys[0].PublicKey().Address(), // change addr + nil, ) if err != nil { return nil, ids.Empty, err diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index f8805303d0a0..b84315c3c9ee 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -73,6 +73,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, changeAddr, + nil, ) require.NoError(err) @@ -107,6 +108,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { changeAddr, []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -143,6 +145,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { changeAddr, []*secp256k1.PrivateKey{keys[0], keys[1], keys[3]}, changeAddr, + nil, ) require.NoError(err) @@ -169,6 +172,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { changeAddr, []*secp256k1.PrivateKey{keys[0], keys[1], keys[4]}, changeAddr, + nil, ) require.NoError(err) @@ -241,6 +245,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -265,6 +270,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -289,6 +295,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -313,6 +320,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -337,6 +345,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -415,6 +424,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { []ids.ShortID{addr0}, []*secp256k1.PrivateKey{key0}, addr0, + nil, ) require.NoError(err) @@ -423,6 +433,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { []ids.ShortID{addr1}, []*secp256k1.PrivateKey{key1}, addr1, + nil, ) require.NoError(err) @@ -431,6 +442,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { []ids.ShortID{addr1}, []*secp256k1.PrivateKey{key1}, addr0, + nil, ) require.NoError(err) @@ -504,6 +516,7 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -712,6 +725,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -884,6 +898,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) @@ -1039,6 +1054,7 @@ func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, ids.GenerateTestShortID(), + nil, ) require.NoError(err) @@ -1160,6 +1176,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -1184,6 +1201,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -1208,6 +1226,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -1245,6 +1264,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -1264,6 +1284,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t []ids.ShortID{changeAddr}, []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -1286,6 +1307,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -1313,6 +1335,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -1366,6 +1389,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -1385,6 +1409,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t []ids.ShortID{changeAddr}, []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -1407,6 +1432,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -1426,6 +1452,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, + nil, ) require.NoError(err) @@ -1490,6 +1517,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { reward.PercentDenominator, keys, addr, // change address + nil, ) require.NoError(err) uPrimaryTx := primaryTx.Unsigned.(*txs.AddPermissionlessValidatorTx) @@ -1520,6 +1548,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { subnetID, []*secp256k1.PrivateKey{keys[0], keys[1]}, addr, + nil, ) require.NoError(err) @@ -1594,6 +1623,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { reward.PercentDenominator, keys, addr, // change address + nil, ) require.NoError(err) uPrimaryRestartTx := primaryRestartTx.Unsigned.(*txs.AddPermissionlessValidatorTx) @@ -1701,6 +1731,7 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, addr, + nil, ) require.NoError(err) @@ -1762,6 +1793,7 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { reward.PercentDenominator, keys, addr, // change address + nil, ) require.NoError(err) @@ -1832,6 +1864,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, addr, + nil, ) require.NoError(err) @@ -1861,6 +1894,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { subnetID, []*secp256k1.PrivateKey{keys[0], keys[1]}, addr, + nil, ) require.NoError(err) @@ -1934,6 +1968,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { reward.PercentDenominator, keys, addr, // change address + nil, ) require.NoError(err) @@ -2011,6 +2046,7 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, addr, + nil, ) require.NoError(err) @@ -2037,6 +2073,7 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { subnetID, []*secp256k1.PrivateKey{keys[0], keys[1]}, addr, + nil, ) require.NoError(err) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 94e158582cce..89ae84ce82d8 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -308,6 +308,7 @@ func defaultVM(t *testing.T, fork activeFork) (*VM, database.Database, *mutableS []ids.ShortID{keys[0].PublicKey().Address(), keys[1].PublicKey().Address(), keys[2].PublicKey().Address()}, []*secp256k1.PrivateKey{keys[0]}, // pays tx fee keys[0].PublicKey().Address(), // change addr + nil, ) require.NoError(err) vm.ctx.Lock.Unlock() @@ -410,6 +411,7 @@ func TestAddValidatorCommit(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -454,6 +456,7 @@ func TestInvalidAddValidatorCommit(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -507,6 +510,7 @@ func TestAddValidatorReject(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -555,6 +559,7 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -589,6 +594,7 @@ func TestAddSubnetValidatorAccept(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -636,6 +642,7 @@ func TestAddSubnetValidatorReject(t *testing.T) { testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[1], testSubnet1ControlKeys[2]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -822,6 +829,7 @@ func TestCreateChain(t *testing.T) { "name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -872,6 +880,7 @@ func TestCreateSubnet(t *testing.T) { }, []*secp256k1.PrivateKey{keys[0]}, // payer keys[0].PublicKey().Address(), // change addr + nil, ) require.NoError(err) @@ -915,6 +924,7 @@ func TestCreateSubnet(t *testing.T) { createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -978,6 +988,7 @@ func TestAtomicImport(t *testing.T) { recipientKey.PublicKey().Address(), []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, // change addr + nil, ) require.ErrorIs(err, txbuilder.ErrNoFunds) @@ -1017,6 +1028,7 @@ func TestAtomicImport(t *testing.T) { recipientKey.PublicKey().Address(), []*secp256k1.PrivateKey{recipientKey}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -2022,6 +2034,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, keys[0].Address(), + nil, ) require.NoError(err) @@ -2041,6 +2054,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { []ids.ShortID{id}, []*secp256k1.PrivateKey{keys[0]}, keys[0].Address(), + nil, ) require.NoError(err) @@ -2063,6 +2077,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { createSubnetTx.ID(), []*secp256k1.PrivateKey{key, keys[1]}, keys[1].Address(), + nil, ) require.NoError(err) @@ -2071,6 +2086,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { createSubnetTx.ID(), []*secp256k1.PrivateKey{key, keys[2]}, keys[2].Address(), + nil, ) require.NoError(err) @@ -2108,6 +2124,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { []ids.ShortID{keys[0].PublicKey().Address()}, []*secp256k1.PrivateKey{keys[0]}, keys[0].Address(), + nil, ) require.NoError(err) subnetID := createSubnetTx.ID() @@ -2143,6 +2160,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { []ids.ShortID{keys[1].PublicKey().Address()}, []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, // change addr + nil, ) require.NoError(err) @@ -2191,6 +2209,7 @@ func TestBaseTx(t *testing.T) { }, []*secp256k1.PrivateKey{keys[0]}, changeAddr, + nil, ) require.NoError(err) @@ -2266,6 +2285,7 @@ func TestPruneMempool(t *testing.T) { }, []*secp256k1.PrivateKey{keys[0]}, changeAddr, + nil, ) require.NoError(err) @@ -2297,6 +2317,7 @@ func TestPruneMempool(t *testing.T) { 20000, []*secp256k1.PrivateKey{keys[1]}, ids.ShortEmpty, + nil, ) require.NoError(err) From 78176ad7929f035cf7a44188bcd297aacf3f1496 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 8 Feb 2024 18:13:25 +0100 Subject: [PATCH 017/120] removed calls to utxos.Spend --- vms/platformvm/txs/builder/builder.go | 114 ++++ vms/platformvm/txs/executor/import_test.go | 112 ++-- .../txs/executor/standard_tx_executor_test.go | 552 ++++++------------ 3 files changed, 350 insertions(+), 428 deletions(-) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 1f928a3166fc..3cfb1599789f 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -6,6 +6,7 @@ package builder import ( "errors" "fmt" + "time" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" @@ -101,6 +102,26 @@ type DecisionTxBuilder interface { memo []byte, ) (*txs.Tx, error) + NewTransformSubnetTx( + subnetID ids.ID, + assetID ids.ID, + initialSupply uint64, + maxSupply uint64, + minConsumptionRate uint64, + maxConsumptionRate uint64, + minValidatorStake uint64, + maxValidatorStake uint64, + minStakeDuration time.Duration, + maxStakeDuration time.Duration, + minDelegationFee uint32, + minDelegatorStake uint64, + maxValidatorWeightFactor byte, + uptimeRequirement uint32, + keys []*secp256k1.PrivateKey, + changeAddr ids.ShortID, + memo []byte, + ) (*txs.Tx, error) + // amount: amount the sender is sending // owner: recipient of the funds // keys: keys to sign the tx and pay the amount @@ -659,6 +680,99 @@ func (b *builder) NewCreateSubnetTx( return tx, tx.SyntacticVerify(b.ctx) } +func (b *builder) NewTransformSubnetTx( + subnetID ids.ID, + assetID ids.ID, + initialSupply uint64, + maxSupply uint64, + minConsumptionRate uint64, + maxConsumptionRate uint64, + minValidatorStake uint64, + maxValidatorStake uint64, + minStakeDuration time.Duration, + maxStakeDuration time.Duration, + minDelegationFee uint32, + minDelegatorStake uint64, + maxValidatorWeightFactor byte, + uptimeRequirement uint32, + keys []*secp256k1.PrivateKey, + changeAddr ids.ShortID, + memo []byte, +) (*txs.Tx, error) { + // 1. Build core transaction without utxos + subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) + if err != nil { + return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) + } + + utx := &txs.TransformSubnetTx{ + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: b.ctx.NetworkID, + BlockchainID: b.ctx.ChainID, + Memo: memo, + }, + }, + Subnet: subnetID, + AssetID: assetID, + InitialSupply: initialSupply, + MaximumSupply: maxSupply, + MinConsumptionRate: minConsumptionRate, + MaxConsumptionRate: maxConsumptionRate, + MinValidatorStake: minValidatorStake, + MaxValidatorStake: maxValidatorStake, + MinStakeDuration: uint32(minStakeDuration / time.Second), + MaxStakeDuration: uint32(maxStakeDuration / time.Second), + MinDelegationFee: minDelegationFee, + MinDelegatorStake: minDelegatorStake, + MaxValidatorWeightFactor: maxValidatorWeightFactor, + UptimeRequirement: uptimeRequirement, + SubnetAuth: subnetAuth, + } + + // 2. Finance the tx by building the utxos (inputs, outputs and stakes) + var ( + chainTime = b.state.GetTimestamp() + feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + isEUpgradeActive = b.cfg.IsEUpgradeActivated(chainTime) + + feeCalc = &fees.Calculator{ + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.UnitFees), + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + } + ) + + // feesMan cumulates consumed units. Let's init it with utx filled so far + if err := feeCalc.TransformSubnetTx(utx); err != nil { + return nil, err + } + + ins, outs, _, signers, err := b.FinanceTx( + b.state, + keys, + 0, + feeCalc, + changeAddr, + ) + if err != nil { + return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + } + + utx.BaseTx.Ins = ins + utx.BaseTx.Outs = outs + + // 3. Sign the tx + signers = append(signers, subnetSigners) + tx, err := txs.NewSigned(utx, txs.Codec, signers) + if err != nil { + return nil, err + } + return tx, tx.SyntacticVerify(b.ctx) +} + func (b *builder) NewAddValidatorTx( stakeAmount, startTime, diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index e61f66b11020..b56c1445b553 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -21,6 +21,8 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) +var fundedSharedMemoryCalls byte + func TestNewImportTx(t *testing.T) { env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) @@ -36,56 +38,6 @@ func TestNewImportTx(t *testing.T) { sourceKey, err := secp256k1.NewPrivateKey() require.NoError(t, err) - cnt := new(byte) - - // Returns a shared memory where GetDatabase returns a database - // where [recipientKey] has a balance of [amt] - fundedSharedMemory := func(peerChain ids.ID, assets map[ids.ID]uint64) atomic.SharedMemory { - *cnt++ - m := atomic.NewMemory(prefixdb.New([]byte{*cnt}, env.baseDB)) - - sm := m.NewSharedMemory(env.ctx.ChainID) - peerSharedMemory := m.NewSharedMemory(peerChain) - - for assetID, amt := range assets { - // #nosec G404 - utxo := &avax.UTXO{ - UTXOID: avax.UTXOID{ - TxID: ids.GenerateTestID(), - OutputIndex: rand.Uint32(), - }, - Asset: avax.Asset{ID: assetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: amt, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Addrs: []ids.ShortID{sourceKey.PublicKey().Address()}, - Threshold: 1, - }, - }, - } - utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) - require.NoError(t, err) - - inputID := utxo.InputID() - require.NoError(t, peerSharedMemory.Apply(map[ids.ID]*atomic.Requests{ - env.ctx.ChainID: { - PutRequests: []*atomic.Element{ - { - Key: inputID[:], - Value: utxoBytes, - Traits: [][]byte{ - sourceKey.PublicKey().Address().Bytes(), - }, - }, - }, - }, - })) - } - - return sm - } - customAssetID := ids.GenerateTestID() tests := []test{ @@ -93,6 +45,9 @@ func TestNewImportTx(t *testing.T) { description: "can't pay fee", sourceChainID: env.ctx.XChainID, sharedMemory: fundedSharedMemory( + t, + env, + sourceKey, env.ctx.XChainID, map[ids.ID]uint64{ env.ctx.AVAXAssetID: env.config.TxFee - 1, @@ -105,6 +60,9 @@ func TestNewImportTx(t *testing.T) { description: "can barely pay fee", sourceChainID: env.ctx.XChainID, sharedMemory: fundedSharedMemory( + t, + env, + sourceKey, env.ctx.XChainID, map[ids.ID]uint64{ env.ctx.AVAXAssetID: env.config.TxFee, @@ -117,6 +75,9 @@ func TestNewImportTx(t *testing.T) { description: "attempting to import from C-chain", sourceChainID: env.ctx.CChainID, sharedMemory: fundedSharedMemory( + t, + env, + sourceKey, env.ctx.CChainID, map[ids.ID]uint64{ env.ctx.AVAXAssetID: env.config.TxFee, @@ -130,6 +91,9 @@ func TestNewImportTx(t *testing.T) { description: "attempting to import non-avax from X-chain", sourceChainID: env.ctx.XChainID, sharedMemory: fundedSharedMemory( + t, + env, + sourceKey, env.ctx.XChainID, map[ids.ID]uint64{ env.ctx.AVAXAssetID: env.config.TxFee, @@ -194,3 +158,51 @@ func TestNewImportTx(t *testing.T) { }) } } + +// Returns a shared memory where GetDatabase returns a database +// where [recipientKey] has a balance of [amt] +func fundedSharedMemory(t *testing.T, env *environment, sourceKey *secp256k1.PrivateKey, peerChain ids.ID, assets map[ids.ID]uint64) atomic.SharedMemory { + fundedSharedMemoryCalls++ + m := atomic.NewMemory(prefixdb.New([]byte{fundedSharedMemoryCalls}, env.baseDB)) + + sm := m.NewSharedMemory(env.ctx.ChainID) + peerSharedMemory := m.NewSharedMemory(peerChain) + + for assetID, amt := range assets { + // #nosec G404 + utxo := &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: ids.GenerateTestID(), + OutputIndex: rand.Uint32(), + }, + Asset: avax.Asset{ID: assetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: amt, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Addrs: []ids.ShortID{sourceKey.PublicKey().Address()}, + Threshold: 1, + }, + }, + } + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) + require.NoError(t, err) + + inputID := utxo.InputID() + require.NoError(t, peerSharedMemory.Apply(map[ids.ID]*atomic.Requests{ + env.ctx.ChainID: { + PutRequests: []*atomic.Element{ + { + Key: inputID[:], + Value: utxoBytes, + Traits: [][]byte{ + sourceKey.PublicKey().Address().Bytes(), + }, + }, + }, + }, + })) + } + + return sm +} diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index e1eeb2bfdd7e..4d4930b37ad4 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -36,7 +36,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/vms/types" ) // This tests that the math performed during TransformSubnetTx execution can @@ -1048,44 +1047,23 @@ func TestDurangoDisabledTransactions(t *testing.T) { { name: "AddValidatorTx", buildTx: func(env *environment) *txs.Tx { - ins, unstakedOuts, stakedOuts, signers, err := env.utxosHandler.Spend( - env.state, - preFundedKeys, - defaultMinValidatorStake, - env.config.AddPrimaryNetworkValidatorFee, - ids.ShortEmpty, - ) - require.NoError(t, err) - var ( nodeID = ids.GenerateTestNodeID() chainTime = env.state.GetTimestamp() endTime = chainTime.Add(defaultMaxStakingDuration) ) - utx := &txs.AddValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Validator: txs.Validator{ - NodeID: nodeID, - Start: 0, - End: uint64(endTime.Unix()), - Wght: env.config.MinValidatorStake, - }, - StakeOuts: stakedOuts, - RewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ids.ShortEmpty}, - }, - DelegationShares: reward.PercentDenominator, - } - - tx, err := txs.NewSigned(utx, txs.Codec, signers) + tx, err := env.txBuilder.NewAddValidatorTx( + defaultMinValidatorStake, + 0, // startTime + uint64(endTime.Unix()), + nodeID, + ids.ShortEmpty, // reward address, + reward.PercentDenominator, // shares + preFundedKeys, + ids.ShortEmpty, // change address + nil, // memo + ) require.NoError(t, err) return tx @@ -1108,38 +1086,18 @@ func TestDurangoDisabledTransactions(t *testing.T) { } it.Release() - ins, unstakedOuts, stakedOuts, signers, err := env.utxosHandler.Spend( - env.state, - preFundedKeys, + tx, err := env.txBuilder.NewAddDelegatorTx( defaultMinValidatorStake, - env.config.AddPrimaryNetworkDelegatorFee, - ids.ShortEmpty, + 0, // startTime + uint64(primaryValidator.EndTime.Unix()), + primaryValidator.NodeID, + ids.ShortEmpty, // reward address, + preFundedKeys, + ids.ShortEmpty, // change address + nil, // memo ) require.NoError(t, err) - utx := &txs.AddDelegatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Validator: txs.Validator{ - NodeID: primaryValidator.NodeID, - End: uint64(primaryValidator.EndTime.Unix()), - Wght: defaultMinValidatorStake, - }, - StakeOuts: stakedOuts, - DelegationRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ids.ShortEmpty}, - }, - } - - tx, err := txs.NewSigned(utx, txs.Codec, signers) - require.NoError(t, err) - return tx }, expectedErr: ErrAddDelegatorTxPostDurango, @@ -1173,13 +1131,13 @@ func TestDurangoDisabledTransactions(t *testing.T) { func TestDurangoMemoField(t *testing.T) { type test struct { name string - setupTest func(*environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) + setupTest func(env *environment, memoField []byte) (*txs.Tx, state.Diff) } tests := []test{ { name: "AddSubnetValidatorTx", - setupTest: func(env *environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) { + setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { var primaryValidator *state.Staker it, err := env.state.GetCurrentStakerIterator() require.NoError(t, err) @@ -1193,205 +1151,122 @@ func TestDurangoMemoField(t *testing.T) { } it.Release() - ins, unstakedOuts, _, signers, err := env.utxosHandler.Spend( - env.state, - preFundedKeys, + tx, err := env.txBuilder.NewAddSubnetValidatorTx( defaultMinValidatorStake, - env.config.TxFee, + 0, // startTime + uint64(primaryValidator.EndTime.Unix()), + primaryValidator.NodeID, + testSubnet1.TxID, + preFundedKeys, ids.ShortEmpty, + memoField, ) require.NoError(t, err) - subnetAuth, subnetSigners, err := env.utxosHandler.Authorize(env.state, testSubnet1.TxID, preFundedKeys) - require.NoError(t, err) - signers = append(signers, subnetSigners) - onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - - tx := &txs.AddSubnetValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - SubnetValidator: txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: primaryValidator.NodeID, - End: uint64(primaryValidator.EndTime.Unix()), - Wght: defaultMinValidatorStake, - }, - Subnet: testSubnet1.TxID, - }, - SubnetAuth: subnetAuth, - } - return tx, signers, onAcceptState, &tx.Memo + return tx, onAcceptState }, }, { name: "CreateChainTx", - setupTest: func(env *environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) { - chainTime := env.state.GetTimestamp() - createBlockchainTxFee := env.config.GetCreateBlockchainTxFee(chainTime) - - ins, unstakedOuts, _, signers, err := env.utxosHandler.Spend( - env.state, + setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { + tx, err := env.txBuilder.NewCreateChainTx( + testSubnet1.TxID, + []byte{}, // genesisData + ids.GenerateTestID(), // vmID + []ids.ID{}, // fxIDs + "aaa", // chain name preFundedKeys, - defaultMinValidatorStake, - createBlockchainTxFee, ids.ShortEmpty, + memoField, ) require.NoError(t, err) - subnetAuth, subnetSigners, err := env.utxosHandler.Authorize(env.state, testSubnet1.TxID, preFundedKeys) - require.NoError(t, err) - signers = append(signers, subnetSigners) - onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - tx := &txs.CreateChainTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - SubnetID: testSubnet1.TxID, - ChainName: "aaa", - VMID: ids.GenerateTestID(), - FxIDs: []ids.ID{}, - GenesisData: []byte{}, - SubnetAuth: subnetAuth, - } - return tx, signers, onAcceptState, &tx.Memo + return tx, onAcceptState }, }, { name: "CreateSubnetTx", - setupTest: func(env *environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) { - chainTime := env.state.GetTimestamp() - createSubnetTxFee := env.config.GetCreateSubnetTxFee(chainTime) - - ins, unstakedOuts, _, signers, err := env.utxosHandler.Spend( - env.state, + setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { + tx, err := env.txBuilder.NewCreateSubnetTx( + 1, + []ids.ShortID{ids.GenerateTestShortID()}, preFundedKeys, - defaultMinValidatorStake, - createSubnetTxFee, ids.ShortEmpty, + memoField, ) require.NoError(t, err) onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - tx := &txs.CreateSubnetTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Owner: &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ids.ShortEmpty}, - }, - } - return tx, signers, onAcceptState, &tx.Memo + return tx, onAcceptState }, }, { name: "ImportTx", - setupTest: func(env *environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) { + setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { // Skip shared memory checks env.backend.Bootstrapped.Set(false) - utxoID := avax.UTXOID{ - TxID: ids.Empty.Prefix(1), - OutputIndex: 1, - } - amount := uint64(50000) - recipientKey := preFundedKeys[1] - - utxo := &avax.UTXO{ - UTXOID: utxoID, - Asset: avax.Asset{ID: env.ctx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: amount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{recipientKey.PublicKey().Address()}, - }, + var ( + sourceChain = env.ctx.XChainID + sourceKey = preFundedKeys[1] + sourceAmount = 10 * units.Avax + ) + + sharedMemory := fundedSharedMemory( + t, + env, + sourceKey, + sourceChain, + map[ids.ID]uint64{ + env.ctx.AVAXAssetID: sourceAmount, }, - } + ) + env.msm.SharedMemory = sharedMemory - signers := [][]*secp256k1.PrivateKey{{recipientKey}} + tx, err := env.txBuilder.NewImportTx( + sourceChain, + sourceKey.PublicKey().Address(), + preFundedKeys, + ids.ShortEmpty, // change address + memoField, + ) + require.NoError(t, err) onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - tx := &txs.ImportTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - }}, - SourceChain: env.ctx.XChainID, - ImportedInputs: []*avax.TransferableInput{ - { - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - In: &secp256k1fx.TransferInput{ - Amt: env.config.TxFee, - }, - }, - }, - } - return tx, signers, onAcceptState, &tx.Memo + return tx, onAcceptState }, }, { name: "ExportTx", - setupTest: func(env *environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) { - amount := units.Avax - ins, unstakedOuts, _, signers, err := env.utxosHandler.Spend( - env.state, + setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { + tx, err := env.txBuilder.NewExportTx( + units.Avax, // amount + env.ctx.XChainID, // destination chain + ids.GenerateTestShortID(), // destination address preFundedKeys, - amount, - env.config.TxFee, - ids.ShortEmpty, + ids.ShortEmpty, // change address + memoField, ) require.NoError(t, err) onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - tx := &txs.ExportTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - DestinationChain: env.ctx.XChainID, - ExportedOutputs: []*avax.TransferableOutput{{ - Asset: avax.Asset{ID: env.ctx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: amount, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ids.GenerateTestShortID()}, - }, - }, - }}, - } - return tx, signers, onAcceptState, &tx.Memo + return tx, onAcceptState }, }, { name: "RemoveSubnetValidatorTx", - setupTest: func(env *environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) { + setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { var primaryValidator *state.Staker it, err := env.state.GetCurrentStakerIterator() require.NoError(t, err) @@ -1427,139 +1302,106 @@ func TestDurangoMemoField(t *testing.T) { Tx: subnetValTx, })) - ins, unstakedOuts, _, signers, err := env.utxosHandler.Spend( - env.state, + tx, err := env.txBuilder.NewRemoveSubnetValidatorTx( + primaryValidator.NodeID, + testSubnet1.ID(), preFundedKeys, - defaultMinValidatorStake, - env.config.TxFee, ids.ShortEmpty, + memoField, ) require.NoError(t, err) - subnetAuth, subnetSigners, err := env.utxosHandler.Authorize(env.state, testSubnet1.TxID, preFundedKeys) - require.NoError(t, err) - signers = append(signers, subnetSigners) - - tx := &txs.RemoveSubnetValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Subnet: testSubnet1.ID(), - NodeID: primaryValidator.NodeID, - SubnetAuth: subnetAuth, - } - return tx, signers, onAcceptState, &tx.Memo + // ins, unstakedOuts, _, signers, err := env.utxosHandler.Spend( + // env.state, + // preFundedKeys, + // defaultMinValidatorStake, + // env.config.TxFee, + // ids.ShortEmpty, + // ) + // require.NoError(t, err) + + // subnetAuth, subnetSigners, err := env.utxosHandler.Authorize(env.state, testSubnet1.TxID, preFundedKeys) + // require.NoError(t, err) + // signers = append(signers, subnetSigners) + + // tx := &txs.RemoveSubnetValidatorTx{ + // BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + // NetworkID: env.ctx.NetworkID, + // BlockchainID: env.ctx.ChainID, + // Ins: ins, + // Outs: unstakedOuts, + // }}, + // Subnet: testSubnet1.ID(), + // NodeID: primaryValidator.NodeID, + // SubnetAuth: subnetAuth, + // } + return tx, onAcceptState }, }, { name: "TransformSubnetTx", - setupTest: func(env *environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) { - ins, unstakedOuts, _, signers, err := env.utxosHandler.Spend( - env.state, + setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { + tx, err := env.txBuilder.NewTransformSubnetTx( + testSubnet1.TxID, // subnetID + ids.GenerateTestID(), // assetID + 10, // initial supply + 10, // max supply + 0, // min consumption rate + reward.PercentDenominator, // max consumption rate + 2, // min validator stake + 10, // max validator stake + time.Minute, // min stake duration + time.Hour, // max stake duration + 1, // min delegation fees + 10, // min delegator stake + 1, // max validator weight factor + 80, // uptime requirement preFundedKeys, - defaultMinValidatorStake, - env.config.TxFee, - ids.ShortEmpty, + ids.ShortEmpty, // change address + memoField, ) require.NoError(t, err) - subnetAuth, subnetSigners, err := env.utxosHandler.Authorize(env.state, testSubnet1.TxID, preFundedKeys) - require.NoError(t, err) - signers = append(signers, subnetSigners) - onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - tx := &txs.TransformSubnetTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Subnet: testSubnet1.TxID, - AssetID: ids.GenerateTestID(), - InitialSupply: 10, - MaximumSupply: 10, - MinConsumptionRate: 0, - MaxConsumptionRate: reward.PercentDenominator, - MinValidatorStake: 2, - MaxValidatorStake: 10, - MinStakeDuration: 1, - MaxStakeDuration: 2, - MinDelegationFee: reward.PercentDenominator, - MinDelegatorStake: 1, - MaxValidatorWeightFactor: 1, - UptimeRequirement: reward.PercentDenominator, - SubnetAuth: subnetAuth, - } - return tx, signers, onAcceptState, &tx.Memo + return tx, onAcceptState }, }, { name: "AddPermissionlessValidatorTx", - setupTest: func(env *environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) { - ins, unstakedOuts, stakedOuts, signers, err := env.utxosHandler.Spend( - env.state, - preFundedKeys, - defaultMinValidatorStake, - env.config.AddPrimaryNetworkValidatorFee, - ids.ShortEmpty, - ) - require.NoError(t, err) - - sk, err := bls.NewSecretKey() - require.NoError(t, err) - + setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { var ( nodeID = ids.GenerateTestNodeID() chainTime = env.state.GetTimestamp() endTime = chainTime.Add(defaultMaxStakingDuration) ) + sk, err := bls.NewSecretKey() + require.NoError(t, err) + + tx, err := env.txBuilder.NewAddPermissionlessValidatorTx( + env.config.MinValidatorStake, + 0, // start Time + uint64(endTime.Unix()), + nodeID, + signer.NewProofOfPossession(sk), + ids.ShortEmpty, // reward address + reward.PercentDenominator, // shares + preFundedKeys, + ids.ShortEmpty, // change address + memoField, + ) + require.NoError(t, err) onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - tx := &txs.AddPermissionlessValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Validator: txs.Validator{ - NodeID: nodeID, - End: uint64(endTime.Unix()), - Wght: env.config.MinValidatorStake, - }, - Subnet: constants.PrimaryNetworkID, - Signer: signer.NewProofOfPossession(sk), - StakeOuts: stakedOuts, - ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - ids.ShortEmpty, - }, - }, - DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ - ids.ShortEmpty, - }, - }, - DelegationShares: reward.PercentDenominator, - } - return tx, signers, onAcceptState, &tx.Memo + return tx, onAcceptState }, }, { name: "AddPermissionlessDelegatorTx", - setupTest: func(env *environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) { + setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { var primaryValidator *state.Staker it, err := env.state.GetCurrentStakerIterator() require.NoError(t, err) @@ -1573,100 +1415,62 @@ func TestDurangoMemoField(t *testing.T) { } it.Release() - ins, unstakedOuts, stakedOuts, signers, err := env.utxosHandler.Spend( - env.state, - preFundedKeys, + tx, err := env.txBuilder.NewAddPermissionlessDelegatorTx( defaultMinValidatorStake, - env.config.AddPrimaryNetworkDelegatorFee, - ids.ShortEmpty, + 0, // start Time + uint64(primaryValidator.EndTime.Unix()), + primaryValidator.NodeID, + ids.ShortEmpty, // reward address + preFundedKeys, + ids.ShortEmpty, // change address + memoField, ) require.NoError(t, err) onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - tx := &txs.AddPermissionlessDelegatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Validator: txs.Validator{ - NodeID: primaryValidator.NodeID, - End: uint64(primaryValidator.EndTime.Unix()), - Wght: defaultMinValidatorStake, - }, - StakeOuts: stakedOuts, - DelegationRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{ids.ShortEmpty}, - }, - } - return tx, signers, onAcceptState, &tx.Memo + return tx, onAcceptState }, }, { name: "TransferSubnetOwnershipTx", - setupTest: func(env *environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) { - ins, unstakedOuts, _, signers, err := env.utxosHandler.Spend( - env.state, + setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { + tx, err := env.txBuilder.NewTransferSubnetOwnershipTx( + testSubnet1.TxID, + 1, + []ids.ShortID{ids.ShortEmpty}, preFundedKeys, - defaultMinValidatorStake, - env.config.TxFee, - ids.ShortEmpty, + ids.ShortEmpty, // change address + memoField, ) require.NoError(t, err) - subnetAuth, subnetSigners, err := env.utxosHandler.Authorize(env.state, testSubnet1.TxID, preFundedKeys) - require.NoError(t, err) - signers = append(signers, subnetSigners) - onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - tx := &txs.TransferSubnetOwnershipTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }}, - Subnet: testSubnet1.TxID, - SubnetAuth: subnetAuth, - Owner: &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ids.ShortEmpty}, - }, - } - return tx, signers, onAcceptState, &tx.Memo + return tx, onAcceptState }, }, { name: "BaseTx", - setupTest: func(env *environment) (txs.UnsignedTx, [][]*secp256k1.PrivateKey, state.Diff, *types.JSONByteSlice) { - ins, unstakedOuts, _, signers, err := env.utxosHandler.Spend( - env.state, + setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { + tx, err := env.txBuilder.NewBaseTx( + 1, + secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, preFundedKeys, - defaultMinValidatorStake, - env.config.TxFee, ids.ShortEmpty, + memoField, ) require.NoError(t, err) onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - tx := &txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - }, - } - return tx, signers, onAcceptState, &tx.Memo + return tx, onAcceptState }, }, } @@ -1679,14 +1483,9 @@ func TestDurangoMemoField(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - utx, signers, onAcceptState, memo := tt.setupTest(env) - // Populated memo field should error - *memo = []byte{'m', 'e', 'm', 'o'} - tx, err := txs.NewSigned(utx, txs.Codec, signers) - require.NoError(err) - - err = tx.Unsigned.Visit(&StandardTxExecutor{ + tx, onAcceptState := tt.setupTest(env, []byte{'m', 'e', 'm', 'o'}) + err := tx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, Tx: tx, @@ -1694,10 +1493,7 @@ func TestDurangoMemoField(t *testing.T) { require.ErrorIs(err, avax.ErrMemoTooLarge) // Empty memo field should not error - *memo = []byte{} - tx, err = txs.NewSigned(utx, txs.Codec, signers) - require.NoError(err) - + tx, onAcceptState = tt.setupTest(env, []byte{}) require.NoError(tx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, From 57619760a14408d22c6d670f05f107ee42ef0dc7 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 8 Feb 2024 19:35:48 +0100 Subject: [PATCH 018/120] removed utxo.Spend method --- vms/platformvm/utxo/handler.go | 264 +-------------------------------- 1 file changed, 3 insertions(+), 261 deletions(-) diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index f716dddd0eb5..1e40f543edc5 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -45,11 +45,11 @@ var ( // TODO: Stake and Authorize should be replaced by similar methods in the // P-chain wallet type Spender interface { - // Spend the provided amount while deducting the provided fee. + // FinanceTx the provided amount while calculating and deducting the provided fee. // Arguments: // - [keys] are the owners of the funds - // - [amount] is the amount of funds that are trying to be staked - // - [fee] is the amount of AVAX that should be burned + // - [amountToStake] is the amount of funds that are trying to be staked + // - [feeCalc] is the fee calculator that tracks and calculates the fees // - [changeAddr] is the address that change, if there is any, is sent to // Returns: // - [inputs] the inputs that should be consumed to fund the outputs @@ -58,20 +58,6 @@ type Spender interface { // - [stakedOutputs] the outputs that should be locked for the duration of // the staking period // - [signers] the proof of ownership of the funds being moved - Spend( - utxoReader avax.UTXOReader, - keys []*secp256k1.PrivateKey, - amount uint64, - fee uint64, - changeAddr ids.ShortID, - ) ( - []*avax.TransferableInput, // inputs - []*avax.TransferableOutput, // returnedOutputs - []*avax.TransferableOutput, // stakedOutputs - [][]*secp256k1.PrivateKey, // signers - error, - ) - FinanceTx( utxoReader avax.UTXOReader, keys []*secp256k1.PrivateKey, @@ -163,250 +149,6 @@ type handler struct { fx fx.Fx } -func (h *handler) Spend( - utxoReader avax.UTXOReader, - keys []*secp256k1.PrivateKey, - amount uint64, - fee uint64, - changeAddr ids.ShortID, -) ( - []*avax.TransferableInput, // inputs - []*avax.TransferableOutput, // returnedOutputs - []*avax.TransferableOutput, // stakedOutputs - [][]*secp256k1.PrivateKey, // signers - error, -) { - addrs := set.NewSet[ids.ShortID](len(keys)) // The addresses controlled by [keys] - for _, key := range keys { - addrs.Add(key.PublicKey().Address()) - } - utxos, err := avax.GetAllUTXOs(utxoReader, addrs) // The UTXOs controlled by [keys] - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("couldn't get UTXOs: %w", err) - } - - kc := secp256k1fx.NewKeychain(keys...) // Keychain consumes UTXOs and creates new ones - - // Minimum time this transaction will be issued at - now := uint64(h.clk.Time().Unix()) - - ins := []*avax.TransferableInput{} - returnedOuts := []*avax.TransferableOutput{} - stakedOuts := []*avax.TransferableOutput{} - signers := [][]*secp256k1.PrivateKey{} - - // Amount of AVAX that has been staked - amountStaked := uint64(0) - - // Consume locked UTXOs - for _, utxo := range utxos { - // If we have consumed more AVAX than we are trying to stake, then we - // have no need to consume more locked AVAX - if amountStaked >= amount { - break - } - - if assetID := utxo.AssetID(); assetID != h.ctx.AVAXAssetID { - continue // We only care about staking AVAX, so ignore other assets - } - - out, ok := utxo.Out.(*stakeable.LockOut) - if !ok { - // This output isn't locked, so it will be handled during the next - // iteration of the UTXO set - continue - } - if out.Locktime <= now { - // This output is no longer locked, so it will be handled during the - // next iteration of the UTXO set - continue - } - - inner, ok := out.TransferableOut.(*secp256k1fx.TransferOutput) - if !ok { - // We only know how to clone secp256k1 outputs for now - continue - } - - inIntf, inSigners, err := kc.Spend(out.TransferableOut, now) - if err != nil { - // We couldn't spend the output, so move on to the next one - continue - } - in, ok := inIntf.(avax.TransferableIn) - if !ok { // should never happen - h.ctx.Log.Warn("wrong input type", - zap.String("expectedType", "avax.TransferableIn"), - zap.String("actualType", fmt.Sprintf("%T", inIntf)), - ) - continue - } - - // The remaining value is initially the full value of the input - remainingValue := in.Amount() - - // Stake any value that should be staked - amountToStake := math.Min( - amount-amountStaked, // Amount we still need to stake - remainingValue, // Amount available to stake - ) - amountStaked += amountToStake - remainingValue -= amountToStake - - // Add the input to the consumed inputs - ins = append(ins, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, - In: &stakeable.LockIn{ - Locktime: out.Locktime, - TransferableIn: in, - }, - }) - - // Add the output to the staked outputs - stakedOuts = append(stakedOuts, &avax.TransferableOutput{ - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, - Out: &stakeable.LockOut{ - Locktime: out.Locktime, - TransferableOut: &secp256k1fx.TransferOutput{ - Amt: amountToStake, - OutputOwners: inner.OutputOwners, - }, - }, - }) - - if remainingValue > 0 { - // This input provided more value than was needed to be locked. - // Some of it must be returned - returnedOuts = append(returnedOuts, &avax.TransferableOutput{ - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, - Out: &stakeable.LockOut{ - Locktime: out.Locktime, - TransferableOut: &secp256k1fx.TransferOutput{ - Amt: remainingValue, - OutputOwners: inner.OutputOwners, - }, - }, - }) - } - - // Add the signers needed for this input to the set of signers - signers = append(signers, inSigners) - } - - // Amount of AVAX that has been burned - amountBurned := uint64(0) - - for _, utxo := range utxos { - // If we have consumed more AVAX than we are trying to stake, - // and we have burned more AVAX than we need to, - // then we have no need to consume more AVAX - if amountBurned >= fee && amountStaked >= amount { - break - } - - if assetID := utxo.AssetID(); assetID != h.ctx.AVAXAssetID { - continue // We only care about burning AVAX, so ignore other assets - } - - out := utxo.Out - inner, ok := out.(*stakeable.LockOut) - if ok { - if inner.Locktime > now { - // This output is currently locked, so this output can't be - // burned. Additionally, it may have already been consumed - // above. Regardless, we skip to the next UTXO - continue - } - out = inner.TransferableOut - } - - inIntf, inSigners, err := kc.Spend(out, now) - if err != nil { - // We couldn't spend this UTXO, so we skip to the next one - continue - } - in, ok := inIntf.(avax.TransferableIn) - if !ok { - // Because we only use the secp Fx right now, this should never - // happen - continue - } - - // The remaining value is initially the full value of the input - remainingValue := in.Amount() - - // Burn any value that should be burned - amountToBurn := math.Min( - fee-amountBurned, // Amount we still need to burn - remainingValue, // Amount available to burn - ) - amountBurned += amountToBurn - remainingValue -= amountToBurn - - // Stake any value that should be staked - amountToStake := math.Min( - amount-amountStaked, // Amount we still need to stake - remainingValue, // Amount available to stake - ) - amountStaked += amountToStake - remainingValue -= amountToStake - - // Add the input to the consumed inputs - ins = append(ins, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, - In: in, - }) - - if amountToStake > 0 { - // Some of this input was put for staking - stakedOuts = append(stakedOuts, &avax.TransferableOutput{ - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: amountToStake, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{changeAddr}, - }, - }, - }) - } - - if remainingValue > 0 { - // This input had extra value, so some of it must be returned - returnedOuts = append(returnedOuts, &avax.TransferableOutput{ - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: remainingValue, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{changeAddr}, - }, - }, - }) - } - - // Add the signers needed for this input to the set of signers - signers = append(signers, inSigners) - } - - if amountBurned < fee || amountStaked < amount { - return nil, nil, nil, nil, fmt.Errorf( - "%w (unlocked, locked) (%d, %d) but need (%d, %d)", - ErrInsufficientFunds, amountBurned, amountStaked, fee, amount, - ) - } - - avax.SortTransferableInputsWithSigners(ins, signers) // sort inputs and keys - avax.SortTransferableOutputs(returnedOuts, txs.Codec) // sort outputs - avax.SortTransferableOutputs(stakedOuts, txs.Codec) // sort outputs - - return ins, returnedOuts, stakedOuts, signers, nil -} - func (h *handler) FinanceTx( utxoReader avax.UTXOReader, keys []*secp256k1.PrivateKey, From 22f69c0e435056a091f497f4f3ac4e275f4c15df Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 9 Feb 2024 17:49:54 +0100 Subject: [PATCH 019/120] fixed txbuilder + updated block builder tests to e-upgrade --- vms/components/fees/helpers.go | 4 +- vms/platformvm/block/builder/builder_test.go | 18 +- vms/platformvm/block/builder/helpers_test.go | 1 + .../block/builder/standard_block_test.go | 2 +- vms/platformvm/config/dynamic_fees_config.go | 9 +- vms/platformvm/txs/builder/builder.go | 56 ++ vms/platformvm/utxo/handler.go | 24 +- vms/platformvm/utxo/handler_test.go | 714 ------------------ wallet/chain/p/builder.go | 2 +- 9 files changed, 97 insertions(+), 733 deletions(-) diff --git a/vms/components/fees/helpers.go b/vms/components/fees/helpers.go index 8db95ae9bff9..153dc7daf6ca 100644 --- a/vms/components/fees/helpers.go +++ b/vms/components/fees/helpers.go @@ -50,13 +50,13 @@ func GetOutputsDimensions(c codec.Manager, v uint16, outs []*avax.TransferableOu return consumedUnits, nil } -func GetCredentialsDimensions(c codec.Manager, v uint16, inputSigIndices []uint32) (Dimensions, error) { +func GetCredentialsDimensions(c codec.Manager, v uint16, keysCount int) (Dimensions, error) { var consumedUnits Dimensions // 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, len(inputSigIndices)), + Sigs: make([][secp256k1.SignatureLen]byte, keysCount), }) credSize, err := c.Size(v, creds) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index a6986e6072b3..41f43a3e263c 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, durangoFork) + env := newEnvironment(t, eUpgradeFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -76,7 +76,7 @@ func TestBuildBlockBasic(t *testing.T) { func TestBuildBlockDoesNotBuildWithEmptyMempool(t *testing.T) { require := require.New(t) - env := newEnvironment(t, durangoFork) + env := newEnvironment(t, eUpgradeFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -93,7 +93,7 @@ func TestBuildBlockDoesNotBuildWithEmptyMempool(t *testing.T) { func TestBuildBlockShouldReward(t *testing.T) { require := require.New(t) - env := newEnvironment(t, durangoFork) + env := newEnvironment(t, eUpgradeFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -195,7 +195,7 @@ func TestBuildBlockShouldReward(t *testing.T) { func TestBuildBlockAdvanceTime(t *testing.T) { require := require.New(t) - env := newEnvironment(t, durangoFork) + env := newEnvironment(t, eUpgradeFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -228,7 +228,7 @@ func TestBuildBlockAdvanceTime(t *testing.T) { func TestBuildBlockForceAdvanceTime(t *testing.T) { require := require.New(t) - env := newEnvironment(t, durangoFork) + env := newEnvironment(t, eUpgradeFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -283,7 +283,7 @@ func TestBuildBlockForceAdvanceTime(t *testing.T) { func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { require := require.New(t) - env := newEnvironment(t, durangoFork) + env := newEnvironment(t, eUpgradeFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -389,7 +389,7 @@ func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { func TestBuildBlockInvalidStakingDurations(t *testing.T) { require := require.New(t) - env := newEnvironment(t, durangoFork) + env := newEnvironment(t, eUpgradeFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -475,7 +475,7 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { func TestPreviouslyDroppedTxsCannotBeReAddedToMempool(t *testing.T) { require := require.New(t) - env := newEnvironment(t, durangoFork) + env := newEnvironment(t, eUpgradeFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -519,7 +519,7 @@ func TestPreviouslyDroppedTxsCannotBeReAddedToMempool(t *testing.T) { func TestNoErrorOnUnexpectedSetPreferenceDuringBootstrapping(t *testing.T) { require := require.New(t) - env := newEnvironment(t, durangoFork) + env := newEnvironment(t, eUpgradeFork) 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 9e6ea4aed3fd..a1503cdddcd0 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -277,6 +277,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/builder/standard_block_test.go b/vms/platformvm/block/builder/standard_block_test.go index 68d7420c6b78..6ce285c75da3 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, durangoFork) + env := newEnvironment(t, eUpgradeFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() diff --git a/vms/platformvm/config/dynamic_fees_config.go b/vms/platformvm/config/dynamic_fees_config.go index b41e3b33b366..88e59477e6cd 100644 --- a/vms/platformvm/config/dynamic_fees_config.go +++ b/vms/platformvm/config/dynamic_fees_config.go @@ -4,6 +4,7 @@ package config import ( + "github.com/ava-labs/avalanchego/utils/units" commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) @@ -18,10 +19,10 @@ import ( var ( EUpgradeDynamicFeesConfig = DynamicFeesConfig{ UnitFees: commonfees.Dimensions{ - 1, - 2, - 3, - 4, + 1 * units.NanoAvax, + 2 * units.NanoAvax, + 3 * units.NanoAvax, + 4 * units.NanoAvax, }, BlockUnitsCap: commonfees.Max, diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 3cfb1599789f..79410b35890f 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -398,6 +398,17 @@ func (b *builder) NewImportTx( return nil, err } + // account for imported inputs credentials + for _, signer := range signers { + credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(signer)) + if err != nil { + return nil, fmt.Errorf("failed calculating credentials size: %w", err) + } + if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { + return nil, fmt.Errorf("account for credentials fees: %w", err) + } + } + if feeCalc.Fee >= importedAVAX { // all imported avax will be burned to pay taxes. // Fees are scaled back accordingly. @@ -593,6 +604,15 @@ func (b *builder) NewCreateChainTx( return nil, err } + // account for subnet authorization credentials + credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(subnetSigners)) + if err != nil { + return nil, fmt.Errorf("failed calculating credentials size: %w", err) + } + if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { + return nil, fmt.Errorf("account for credentials fees: %w", err) + } + ins, outs, _, signers, err := b.FinanceTx( b.state, keys, @@ -750,6 +770,15 @@ func (b *builder) NewTransformSubnetTx( return nil, err } + // account for subnet authorization credentials + credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(subnetSigners)) + if err != nil { + return nil, fmt.Errorf("failed calculating credentials size: %w", err) + } + if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { + return nil, fmt.Errorf("account for credentials fees: %w", err) + } + ins, outs, _, signers, err := b.FinanceTx( b.state, keys, @@ -1134,6 +1163,15 @@ func (b *builder) NewAddSubnetValidatorTx( return nil, err } + // account for subnet authorization credentials + credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(subnetSigners)) + if err != nil { + return nil, fmt.Errorf("failed calculating credentials size: %w", err) + } + if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { + return nil, fmt.Errorf("account for credentials fees: %w", err) + } + ins, outs, _, signers, err := b.FinanceTx( b.state, keys, @@ -1202,6 +1240,15 @@ func (b *builder) NewRemoveSubnetValidatorTx( return nil, err } + // account for subnet authorization credentials + credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(subnetSigners)) + if err != nil { + return nil, fmt.Errorf("failed calculating credentials size: %w", err) + } + if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { + return nil, fmt.Errorf("account for credentials fees: %w", err) + } + ins, outs, _, signers, err := b.FinanceTx( b.state, keys, @@ -1274,6 +1321,15 @@ func (b *builder) NewTransferSubnetOwnershipTx( return nil, err } + // account for subnet authorization credentials + credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(subnetSigners)) + if err != nil { + return nil, fmt.Errorf("failed calculating credentials size: %w", err) + } + if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { + return nil, fmt.Errorf("account for credentials fees: %w", err) + } + ins, outs, _, signers, err := b.FinanceTx( b.state, keys, diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index 00b7c5e07663..21d6da640674 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -238,6 +238,16 @@ func (h *handler) FinanceTx( }, } + credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(inSigners)) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("failed calculating credentials size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(credsDimensions) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("account for credentials fees: %w", err) + } + targetFee += addedFees + // The remaining value is initially the full value of the input remainingValue := in.Amount() @@ -246,7 +256,7 @@ func (h *handler) FinanceTx( if err != nil { return nil, nil, nil, nil, fmt.Errorf("failed calculating input size: %w", err) } - addedFees, err := feeCalc.AddFeesFor(insDimensions) + addedFees, err = feeCalc.AddFeesFor(insDimensions) if err != nil { return nil, nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } @@ -364,6 +374,16 @@ func (h *handler) FinanceTx( In: in, } + credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(inSigners)) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("failed calculating credentials size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(credsDimensions) + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("account for credentials fees: %w", err) + } + targetFee += addedFees + // The remaining value is initially the full value of the input remainingValue := in.Amount() @@ -372,7 +392,7 @@ func (h *handler) FinanceTx( if err != nil { return nil, nil, nil, nil, fmt.Errorf("failed calculating input size: %w", err) } - addedFees, err := feeCalc.AddFeesFor(insDimensions) + addedFees, err = feeCalc.AddFeesFor(insDimensions) if err != nil { return nil, nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } diff --git a/vms/platformvm/utxo/handler_test.go b/vms/platformvm/utxo/handler_test.go index fe6f249c862e..d0224ed4666a 100644 --- a/vms/platformvm/utxo/handler_test.go +++ b/vms/platformvm/utxo/handler_test.go @@ -9,27 +9,18 @@ import ( "time" "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" "github.com/ava-labs/avalanchego/ids" "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/components/verify" - "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/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" "github.com/ava-labs/avalanchego/vms/secp256k1fx" safemath "github.com/ava-labs/avalanchego/utils/math" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var _ txs.UnsignedTx = (*dummyUnsignedTx)(nil) @@ -42,711 +33,6 @@ func (*dummyUnsignedTx) Visit(txs.Visitor) error { return nil } -func TestVerifyFinanceTx(t *testing.T) { - fx := &secp256k1fx.Fx{} - require.NoError(t, fx.InitializeVM(&secp256k1fx.TestVM{})) - require.NoError(t, fx.Bootstrapped()) - - ctx := snowtest.Context(t, snowtest.PChainID) - keys := secp256k1.TestKeys() - - h := &handler{ - ctx: ctx, - clk: &mockable.Clock{}, - fx: fx, - } - - testUnitFees := commonfees.Dimensions{ - 1 * units.MicroAvax, - 2 * units.MicroAvax, - 3 * units.MicroAvax, - 4 * units.MicroAvax, - } - testBlockMaxConsumedUnits := commonfees.Dimensions{ - math.MaxUint64, - math.MaxUint64, - math.MaxUint64, - math.MaxUint64, - } - - var ( - amountToStake = units.MilliAvax - - bigUtxoTxID = ids.ID{0x0, 0x1} - bigUtxoKey = keys[0] - bigUtxoAddr = bigUtxoKey.PublicKey().Address() - bigUtxoAmount = 10 * units.MilliAvax - bigUtxo = &avax.UTXO{ - UTXOID: avax.UTXOID{ - TxID: bigUtxoTxID, - OutputIndex: 0, - }, - Asset: avax.Asset{ID: ctx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: bigUtxoAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Addrs: []ids.ShortID{bigUtxoAddr}, - Threshold: 1, - }, - }, - } - bigUtxoID = bigUtxo.InputID() - - smallUtxoTxID = ids.ID{0x0, 0x2} - smallUtxoKey = keys[1] - smallUtxoAddr = smallUtxoKey.PublicKey().Address() - smallUtxoAmount = 2 * units.MilliAvax - smallUtxo = &avax.UTXO{ - UTXOID: avax.UTXOID{ - TxID: smallUtxoTxID, - OutputIndex: 0, - }, - Asset: avax.Asset{ID: ctx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: smallUtxoAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Addrs: []ids.ShortID{smallUtxoAddr}, - Threshold: 1, - }, - }, - } - smallUtxoID = smallUtxo.InputID() - - lockedUtxoTxID = ids.ID{'c'} - lockedUtxoKey = keys[2] - lockedUtxoAddr = lockedUtxoKey.PublicKey().Address() - lockedUtxoAmount = amountToStake - - lockedUtxo = &avax.UTXO{ - UTXOID: avax.UTXOID{ - TxID: lockedUtxoTxID, - OutputIndex: 0, - }, - Asset: avax.Asset{ID: ctx.AVAXAssetID}, - Out: &stakeable.LockOut{ - Locktime: uint64(time.Now().Add(time.Hour).Unix()), - TransferableOut: &secp256k1fx.TransferOutput{ - Amt: lockedUtxoAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Addrs: []ids.ShortID{lockedUtxoAddr}, - Threshold: 1, - }, - }, - }, - } - lockedUtxoID = lockedUtxo.InputID() - - bigLockedUtxoTxID = ids.ID{'d'} - bigLockedUtxoKey = keys[2] - bigLockedUtxoAddr = bigLockedUtxoKey.PublicKey().Address() - bigLockedUtxoAmount = amountToStake * 10 - - bigLockedUtxo = &avax.UTXO{ - UTXOID: avax.UTXOID{ - TxID: bigLockedUtxoTxID, - OutputIndex: 0, - }, - Asset: avax.Asset{ID: ctx.AVAXAssetID}, - Out: &stakeable.LockOut{ - Locktime: uint64(time.Now().Add(time.Hour).Unix()), - TransferableOut: &secp256k1fx.TransferOutput{ - Amt: bigLockedUtxoAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Addrs: []ids.ShortID{bigLockedUtxoAddr}, - Threshold: 1, - }, - }, - }, - } - bigLockedUtxoID = bigLockedUtxo.InputID() - ) - - // this UTXOs ordering ensures that smallUtxo will be picked first, - // even if bigUtxo would be enough finance the whole tx - require.True(t, smallUtxoID.Compare(bigUtxoID) < 0) - - sk, err := bls.NewSecretKey() - require.NoError(t, err) - - tests := []struct { - description string - utxoReaderF func(ctrl *gomock.Controller) avax.UTXOReader - - // keysF simplifies the utxoReade mock setup. We just specify here - // the only keys referenced by the test scenario - keysF func() []*secp256k1.PrivateKey - amountToStake uint64 - uTxF func(t *testing.T) txs.UnsignedTx - - expectedErr error - checksF func(*testing.T, txs.UnsignedTx, []*avax.TransferableInput, []*avax.TransferableOutput, []*avax.TransferableOutput) - }{ - { - description: "Tx, stake outputs, single locked UTXO and multiple UTXOs", - utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { - s := state.NewMockState(ctrl) - s.EXPECT().UTXOIDs(smallUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{smallUtxoID}, nil).AnyTimes() - s.EXPECT().GetUTXO(smallUtxoID).Return(smallUtxo, nil).AnyTimes() - - s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() - s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() - - s.EXPECT().UTXOIDs(bigLockedUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigLockedUtxoID}, nil).AnyTimes() - s.EXPECT().GetUTXO(bigLockedUtxoID).Return(bigLockedUtxo, nil).AnyTimes() - - return s - }, - keysF: func() []*secp256k1.PrivateKey { - return []*secp256k1.PrivateKey{smallUtxoKey, bigUtxoKey, bigLockedUtxoKey} - }, - - amountToStake: units.MilliAvax, - uTxF: func(t *testing.T) txs.UnsignedTx { - uTx := &txs.AddPermissionlessValidatorTx{ - BaseTx: txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: ctx.NetworkID, - BlockchainID: ctx.ChainID, - Ins: make([]*avax.TransferableInput, 0), - Outs: make([]*avax.TransferableOutput, 0), - Memo: []byte{'a', 'b', 'c'}, - }, - }, - Validator: txs.Validator{ - NodeID: ids.GenerateTestNodeID(), - Start: 0, - End: uint64(time.Now().Unix()), - Wght: amountToStake, - }, - Subnet: constants.PrimaryNetworkID, - Signer: signer.NewProofOfPossession(sk), - StakeOuts: make([]*avax.TransferableOutput, 0), - 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, - } - - bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) - require.NoError(t, err) - - uTx.SetBytes(bytes) - return uTx - }, - expectedErr: nil, - checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { - r := require.New(t) - - fm := commonfees.NewManager(testUnitFees) - calc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: fm, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: []verify.Verifiable{}, - } - - expectedFee := 9131 * units.MicroAvax - - // complete uTx with the utxos - addVal, ok := uTx.(*txs.AddPermissionlessValidatorTx) - r.True(ok) - - addVal.Ins = ins - addVal.Outs = outs - addVal.StakeOuts = staked - - r.NoError(uTx.Visit(calc)) - r.Equal(expectedFee, calc.Fee) - - r.Len(ins, 3) - r.Len(staked, 1) - r.Len(outs, 2) - - r.Equal(amountToStake, staked[0].Out.Amount()) - r.Equal(amountToStake, ins[0].In.Amount()-outs[1].Out.Amount()) - r.Equal(expectedFee, ins[1].In.Amount()+ins[2].In.Amount()-outs[0].Out.Amount()) - }, - }, - { - description: "Tx, stake outputs, single locked and unlocked UTXOs", - utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { - s := state.NewMockState(ctrl) - s.EXPECT().UTXOIDs(lockedUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{lockedUtxoID}, nil).AnyTimes() - s.EXPECT().GetUTXO(lockedUtxoID).Return(lockedUtxo, nil).AnyTimes() - s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() - s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() - return s - }, - keysF: func() []*secp256k1.PrivateKey { - return []*secp256k1.PrivateKey{lockedUtxoKey, bigUtxoKey} - }, - - amountToStake: units.MilliAvax, - uTxF: func(t *testing.T) txs.UnsignedTx { - uTx := &txs.AddPermissionlessValidatorTx{ - BaseTx: txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: ctx.NetworkID, - BlockchainID: ctx.ChainID, - Ins: make([]*avax.TransferableInput, 0), - Outs: make([]*avax.TransferableOutput, 0), - Memo: []byte{'a', 'b', 'c'}, - }, - }, - Validator: txs.Validator{ - NodeID: ids.GenerateTestNodeID(), - Start: 0, - End: uint64(time.Now().Unix()), - Wght: amountToStake, - }, - Subnet: constants.PrimaryNetworkID, - Signer: signer.NewProofOfPossession(sk), - StakeOuts: make([]*avax.TransferableOutput, 0), - 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, - } - - bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) - require.NoError(t, err) - - uTx.SetBytes(bytes) - return uTx - }, - expectedErr: nil, - checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { - r := require.New(t) - - fm := commonfees.NewManager(testUnitFees) - calc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: fm, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: []verify.Verifiable{}, - } - - expectedFee := 6219 * units.MicroAvax - - // complete uTx with the utxos - addVal, ok := uTx.(*txs.AddPermissionlessValidatorTx) - r.True(ok) - - addVal.Ins = ins - addVal.Outs = outs - addVal.StakeOuts = staked - - r.NoError(uTx.Visit(calc)) - r.Equal(expectedFee, calc.Fee) - - r.Len(ins, 2) - r.Len(staked, 1) - r.Len(outs, 1) - - r.Equal(amountToStake, staked[0].Out.Amount()) - r.Equal(amountToStake, ins[1].In.Amount()) - r.Equal(expectedFee, ins[0].In.Amount()-outs[0].Out.Amount()) - }, - }, - { - description: "Tx, stake outputs, multiple UTXOs", - utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { - s := state.NewMockState(ctrl) - s.EXPECT().UTXOIDs(smallUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{smallUtxoID}, nil).AnyTimes() - s.EXPECT().GetUTXO(smallUtxoID).Return(smallUtxo, nil).AnyTimes() - - s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() - s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() - - return s - }, - keysF: func() []*secp256k1.PrivateKey { - return []*secp256k1.PrivateKey{smallUtxoKey, bigUtxoKey} - }, - - amountToStake: units.MilliAvax, - uTxF: func(t *testing.T) txs.UnsignedTx { - uTx := &txs.AddPermissionlessValidatorTx{ - BaseTx: txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: ctx.NetworkID, - BlockchainID: ctx.ChainID, - Ins: make([]*avax.TransferableInput, 0), - Outs: make([]*avax.TransferableOutput, 0), - Memo: []byte{'a', 'b', 'c'}, - }, - }, - Validator: txs.Validator{ - NodeID: ids.GenerateTestNodeID(), - Start: 0, - End: uint64(time.Now().Unix()), - Wght: amountToStake, - }, - Subnet: constants.PrimaryNetworkID, - Signer: signer.NewProofOfPossession(sk), - StakeOuts: make([]*avax.TransferableOutput, 0), - 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, - } - - bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) - require.NoError(t, err) - - uTx.SetBytes(bytes) - return uTx - }, - expectedErr: nil, - checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { - r := require.New(t) - - fm := commonfees.NewManager(testUnitFees) - calc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: fm, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: []verify.Verifiable{}, - } - - expectedFee := 6099 * units.MicroAvax - - // complete uTx with the utxos - addVal, ok := uTx.(*txs.AddPermissionlessValidatorTx) - r.True(ok) - - addVal.Ins = ins - addVal.Outs = outs - addVal.StakeOuts = staked - - r.NoError(uTx.Visit(calc)) - r.Equal(expectedFee, calc.Fee) - - r.Len(ins, 2) - r.Len(staked, 1) - r.Len(outs, 1) - - r.Equal(amountToStake, staked[0].Out.Amount()) - r.Equal(expectedFee, ins[0].In.Amount()+ins[1].In.Amount()-amountToStake-outs[0].Out.Amount()) - }, - }, - { - description: "Tx, stake outputs, single UTXO", - utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { - s := state.NewMockState(ctrl) - s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() - s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() - return s - }, - keysF: func() []*secp256k1.PrivateKey { - return []*secp256k1.PrivateKey{bigUtxoKey} - }, - - amountToStake: units.MilliAvax, - uTxF: func(t *testing.T) txs.UnsignedTx { - uTx := &txs.AddPermissionlessValidatorTx{ - BaseTx: txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: ctx.NetworkID, - BlockchainID: ctx.ChainID, - Ins: make([]*avax.TransferableInput, 0), - Outs: make([]*avax.TransferableOutput, 0), - Memo: []byte{'a', 'b', 'c'}, - }, - }, - Validator: txs.Validator{ - NodeID: ids.GenerateTestNodeID(), - Start: 0, - End: uint64(time.Now().Unix()), - Wght: amountToStake, - }, - Subnet: constants.PrimaryNetworkID, - Signer: signer.NewProofOfPossession(sk), - StakeOuts: make([]*avax.TransferableOutput, 0), - 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, - } - - bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) - require.NoError(t, err) - - uTx.SetBytes(bytes) - return uTx - }, - expectedErr: nil, - checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { - r := require.New(t) - - fm := commonfees.NewManager(testUnitFees) - calc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: fm, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: []verify.Verifiable{}, - } - - expectedFee := 3561 * units.MicroAvax - - // complete uTx with the utxos - addVal, ok := uTx.(*txs.AddPermissionlessValidatorTx) - r.True(ok) - - addVal.Ins = ins - addVal.Outs = outs - addVal.StakeOuts = staked - - r.NoError(uTx.Visit(calc)) - r.Equal(expectedFee, calc.Fee) - - r.Len(ins, 1) - r.Len(staked, 1) - r.Len(outs, 1) - - r.Equal(amountToStake, staked[0].Out.Amount()) - r.Equal(expectedFee, ins[0].In.Amount()-amountToStake-outs[0].Out.Amount()) - }, - }, - { - description: "Tx, no stake outputs, single UTXO", - utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { - s := state.NewMockState(ctrl) - s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() - s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() - return s - }, - keysF: func() []*secp256k1.PrivateKey { - return []*secp256k1.PrivateKey{bigUtxoKey} - }, - - amountToStake: 0, - uTxF: func(t *testing.T) txs.UnsignedTx { - uTx := &txs.CreateChainTx{ - BaseTx: txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: ctx.NetworkID, - BlockchainID: ctx.ChainID, - Ins: make([]*avax.TransferableInput, 0), - Outs: make([]*avax.TransferableOutput, 0), - Memo: []byte{'a', 'b', 'c'}, - }, - }, - SubnetID: ids.GenerateTestID(), - ChainName: "testChain", - VMID: ids.GenerateTestID(), - SubnetAuth: &secp256k1fx.Input{}, - } - - bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) - require.NoError(t, err) - - uTx.SetBytes(bytes) - return uTx - }, - expectedErr: nil, - checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { - r := require.New(t) - - fm := commonfees.NewManager(testUnitFees) - calc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: fm, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: []verify.Verifiable{}, - } - - expectedFee := 3014 * units.MicroAvax - - // complete uTx with the utxos - addVal, ok := uTx.(*txs.CreateChainTx) - r.True(ok) - - addVal.Ins = ins - addVal.Outs = outs - - r.NoError(uTx.Visit(calc)) - r.Equal(expectedFee, calc.Fee) - - r.Len(ins, 1) - r.Len(outs, 1) - r.Equal(expectedFee, ins[0].In.Amount()-outs[0].Out.Amount()) - r.Empty(staked) - }, - }, - { - description: "Tx, no stake outputs, multiple UTXOs", - utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { - s := state.NewMockState(ctrl) - s.EXPECT().UTXOIDs(smallUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{smallUtxoID}, nil).AnyTimes() - s.EXPECT().GetUTXO(smallUtxoID).Return(smallUtxo, nil).AnyTimes() - - s.EXPECT().UTXOIDs(bigUtxoAddr.Bytes(), gomock.Any(), gomock.Any()).Return([]ids.ID{bigUtxoID}, nil).AnyTimes() - s.EXPECT().GetUTXO(bigUtxoID).Return(bigUtxo, nil).AnyTimes() - - return s - }, - keysF: func() []*secp256k1.PrivateKey { - return []*secp256k1.PrivateKey{smallUtxoKey, bigUtxoKey} - }, - - amountToStake: 0, - uTxF: func(t *testing.T) txs.UnsignedTx { - uTx := &txs.CreateChainTx{ - BaseTx: txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: ctx.NetworkID, - BlockchainID: ctx.ChainID, - Ins: make([]*avax.TransferableInput, 0), - Outs: make([]*avax.TransferableOutput, 0), - Memo: []byte{'a', 'b', 'c'}, - }, - }, - SubnetID: ids.GenerateTestID(), - ChainName: "testChain", - VMID: ids.GenerateTestID(), - SubnetAuth: &secp256k1fx.Input{}, - } - - bytes, err := txs.Codec.Marshal(txs.CodecVersion, uTx) - require.NoError(t, err) - - uTx.SetBytes(bytes) - return uTx - }, - expectedErr: nil, - checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { - r := require.New(t) - - fm := commonfees.NewManager(testUnitFees) - calc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: fm, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: []verify.Verifiable{}, - } - - expectedFee := 5552 * units.MicroAvax - - // complete uTx with the utxos - addVal, ok := uTx.(*txs.CreateChainTx) - r.True(ok) - - addVal.Ins = ins - addVal.Outs = outs - - r.NoError(uTx.Visit(calc)) - r.Equal(expectedFee, calc.Fee) - - r.Len(ins, 2) - r.Len(outs, 1) - r.Equal(expectedFee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) - r.Empty(staked) - }, - }, - { - description: "no inputs, no outputs, no fee", - utxoReaderF: func(ctrl *gomock.Controller) avax.UTXOReader { - s := state.NewMockState(ctrl) - s.EXPECT().UTXOIDs(gomock.Any(), gomock.Any(), gomock.Any()).Return([]ids.ID{}, nil).AnyTimes() - return s - }, - keysF: func() []*secp256k1.PrivateKey { - return []*secp256k1.PrivateKey{} - }, - amountToStake: 0, - uTxF: func(t *testing.T) txs.UnsignedTx { - unsignedTx := dummyUnsignedTx{ - BaseTx: txs.BaseTx{}, - } - unsignedTx.SetBytes([]byte{0}) - return &unsignedTx - }, - expectedErr: nil, - checksF: func(t *testing.T, uTx txs.UnsignedTx, ins []*avax.TransferableInput, outs, staked []*avax.TransferableOutput) { - r := require.New(t) - - fm := commonfees.NewManager(testUnitFees) - calc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: fm, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: []verify.Verifiable{}, - } - - r.NoError(uTx.Visit(calc)) - r.Zero(calc.Fee) - - r.Empty(ins) - r.Empty(outs) - r.Empty(staked) - }, - }, - } - - for _, test := range tests { - t.Run(test.description, func(t *testing.T) { - r := require.New(t) - ctrl := gomock.NewController(t) - - uTx := test.uTxF(t) - - fm := commonfees.NewManager(testUnitFees) - feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: fm, - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: []verify.Verifiable{}, - } - - // init fee calc with the uTx data - r.NoError(uTx.Visit(feeCalc)) - - ins, outs, staked, _, err := h.FinanceTx( - test.utxoReaderF(ctrl), - test.keysF(), - test.amountToStake, - feeCalc, - ids.GenerateTestShortID(), - ) - r.ErrorIs(err, test.expectedErr) - test.checksF(t, uTx, ins, outs, staked) - }) - } -} - func TestVerifySpendUTXOs(t *testing.T) { fx := &secp256k1fx.Fx{} diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 7c17e34d84ac..2227f54db938 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -1508,7 +1508,7 @@ func financeOutput(feeCalc *fees.Calculator, output *avax.TransferableOutput) (u } func financeCredential(feeCalc *fees.Calculator, inputSigIndices []uint32) (uint64, error) { - credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, inputSigIndices) + credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(inputSigIndices)) if err != nil { return 0, fmt.Errorf("failed calculating input size: %w", err) } From c2859098fb91cb4e74411c3986b267a2885edf3d Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 9 Feb 2024 20:51:52 +0100 Subject: [PATCH 020/120] updated platformvm tests to e upgrade --- vms/platformvm/service_test.go | 20 ++++++++- .../txs/executor/create_chain_test.go | 5 +-- .../txs/executor/standard_tx_executor_test.go | 25 ----------- vms/platformvm/utxo/handler.go | 2 +- vms/platformvm/vm_test.go | 41 +++++++++++++++++-- 5 files changed, 60 insertions(+), 33 deletions(-) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 9b231a871024..af27ab417cb6 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -36,6 +36,7 @@ import ( "github.com/ava-labs/avalanchego/utils/json" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/components/avax" + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/block/builder" "github.com/ava-labs/avalanchego/vms/platformvm/signer" @@ -48,6 +49,7 @@ import ( pchainapi "github.com/ava-labs/avalanchego/vms/platformvm/api" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" ) var ( @@ -394,7 +396,23 @@ 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()) + var ( + chainTime = service.vm.state.GetTimestamp() + feeCfg = service.vm.Config.GetDynamicFeesConfig(chainTime) + feeMan = commonfees.NewManager(feeCfg.UnitFees) + feeCalc = &fees.Calculator{ + IsEUpgradeActive: service.vm.IsEUpgradeActivated(chainTime), + Config: &service.vm.Config, + ChainTime: chainTime, + FeeManager: feeMan, + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: testSubnet1.Creds, + } + ) + + require.NoError(testSubnet1.Unsigned.Visit(feeCalc)) + + balance = defaultBalance - feeCalc.Fee } require.Equal(json.Uint64(balance), reply.Balance) require.Equal(json.Uint64(balance), reply.Unlocked) diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 59f85ed3e848..958f368eb6e0 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -109,7 +109,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { // its validator set doesn't exist func TestCreateChainTxNoSuchSubnet(t *testing.T) { require := require.New(t) - env := newEnvironment(t, banffFork) + env := newEnvironment(t, eUpgradeFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -145,7 +145,7 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { // Ensure valid tx passes semanticVerify func TestCreateChainTxValid(t *testing.T) { require := require.New(t) - env := newEnvironment(t, banffFork) + env := newEnvironment(t, eUpgradeFork) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() @@ -229,7 +229,6 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { signers = append(signers, subnetSigners) // Create the tx - utx := &txs.CreateChainTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: env.ctx.NetworkID, diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 44d40902b33f..03443ed24ec4 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -1310,31 +1310,6 @@ func TestDurangoMemoField(t *testing.T) { memoField, ) require.NoError(t, err) - - // ins, unstakedOuts, _, signers, err := env.utxosHandler.Spend( - // env.state, - // preFundedKeys, - // defaultMinValidatorStake, - // env.config.TxFee, - // ids.ShortEmpty, - // ) - // require.NoError(t, err) - - // subnetAuth, subnetSigners, err := env.utxosHandler.Authorize(env.state, testSubnet1.TxID, preFundedKeys) - // require.NoError(t, err) - // signers = append(signers, subnetSigners) - - // tx := &txs.RemoveSubnetValidatorTx{ - // BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - // NetworkID: env.ctx.NetworkID, - // BlockchainID: env.ctx.ChainID, - // Ins: ins, - // Outs: unstakedOuts, - // }}, - // Subnet: testSubnet1.ID(), - // NodeID: primaryValidator.NodeID, - // SubnetAuth: subnetAuth, - // } return tx, onAcceptState }, }, diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index 21d6da640674..2cf53aa0866f 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -42,7 +42,7 @@ var ( errLockedFundsNotMarkedAsLocked = errors.New("locked funds not marked as locked") ) -// TODO: Stake and Authorize should be replaced by similar methods in the +// TODO: FinanceTx and Authorize should be replaced by similar methods in the // P-chain wallet type Spender interface { // FinanceTx the provided amount while calculating and deducting the provided fee. diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index c9b58956e8c3..afec3babf0b6 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -66,10 +66,12 @@ import ( smeng "github.com/ava-labs/avalanchego/snow/engine/snowman" snowgetter "github.com/ava-labs/avalanchego/snow/engine/snowman/getter" timetracker "github.com/ava-labs/avalanchego/snow/networking/tracker" + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" blockbuilder "github.com/ava-labs/avalanchego/vms/platformvm/block/builder" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" ) type activeFork uint8 @@ -82,7 +84,7 @@ const ( durangoFork eUpgradeFork - latestFork activeFork = durangoFork + latestFork activeFork = eUpgradeFork defaultWeight uint64 = 10000 ) @@ -371,7 +373,25 @@ func TestGenesis(t *testing.T) { require.NoError(err) require.Equal(utxo.Address, addr) - require.Equal(uint64(utxo.Amount)-vm.CreateSubnetTxFee, out.Amount()) + + // we use the first key to fund a subnet creation in [defaultGenesis]. + // As such we need to account for the subnet creation fee + var ( + chainTime = vm.state.GetTimestamp() + feeCfg = vm.Config.GetDynamicFeesConfig(chainTime) + feeMan = commonfees.NewManager(feeCfg.UnitFees) + feeCalc = &fees.Calculator{ + IsEUpgradeActive: vm.IsEUpgradeActivated(chainTime), + Config: &vm.Config, + ChainTime: chainTime, + FeeManager: feeMan, + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: testSubnet1.Creds, + } + ) + + require.NoError(testSubnet1.Unsigned.Visit(feeCalc)) + require.Equal(uint64(utxo.Amount)-feeCalc.Fee, out.Amount()) } } @@ -2252,7 +2272,22 @@ func TestBaseTx(t *testing.T) { } require.Equal(totalOutputAmt, key0OutputAmt+key1OutputAmt+changeAddrOutputAmt) - require.Equal(vm.TxFee, totalInputAmt-totalOutputAmt) + var ( + chainTime = vm.state.GetTimestamp() + feeCfg = vm.Config.GetDynamicFeesConfig(chainTime) + feeMan = commonfees.NewManager(feeCfg.UnitFees) + feeCalc = &fees.Calculator{ + IsEUpgradeActive: vm.IsEUpgradeActivated(chainTime), + Config: &vm.Config, + ChainTime: chainTime, + FeeManager: feeMan, + ConsumedUnitsCap: feeCfg.BlockUnitsCap, + Credentials: baseTx.Creds, + } + ) + + require.NoError(baseTx.Unsigned.Visit(feeCalc)) + require.Equal(feeCalc.Fee, totalInputAmt-totalOutputAmt) require.Equal(sendAmt, key1OutputAmt) vm.ctx.Lock.Unlock() From d75b0297f733bf1854169ca4cd4ce17f95d92b84 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 9 Feb 2024 22:51:52 +0100 Subject: [PATCH 021/120] minor code duplication removal --- vms/platformvm/txs/builder/builder.go | 53 +++++--------------- vms/platformvm/txs/fees/helpers.go | 48 ++++++++++++++++++ vms/platformvm/utxo/handler.go | 54 ++++---------------- wallet/chain/p/builder.go | 71 ++++++--------------------- 4 files changed, 86 insertions(+), 140 deletions(-) create mode 100644 vms/platformvm/txs/fees/helpers.go diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 79410b35890f..62c9cfb26b7b 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -400,12 +400,8 @@ func (b *builder) NewImportTx( // account for imported inputs credentials for _, signer := range signers { - credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(signer)) - if err != nil { - return nil, fmt.Errorf("failed calculating credentials size: %w", err) - } - if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { - return nil, fmt.Errorf("account for credentials fees: %w", err) + if _, err = fees.FinanceCredential(feeCalc, len(signer)); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) } } @@ -427,11 +423,8 @@ func (b *builder) NewImportTx( } // update fees to target given the extra output added - outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) + _, outDimensions, err := fees.FinanceOutput(feeCalc, changeOut) if err != nil { - return nil, fmt.Errorf("failed calculating output size: %w", err) - } - if _, err := feeCalc.AddFeesFor(outDimensions); err != nil { return nil, fmt.Errorf("account for output fees: %w", err) } @@ -605,12 +598,8 @@ func (b *builder) NewCreateChainTx( } // account for subnet authorization credentials - credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(subnetSigners)) - if err != nil { - return nil, fmt.Errorf("failed calculating credentials size: %w", err) - } - if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { - return nil, fmt.Errorf("account for credentials fees: %w", err) + if _, err = fees.FinanceCredential(feeCalc, len(subnetSigners)); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) } ins, outs, _, signers, err := b.FinanceTx( @@ -771,12 +760,8 @@ func (b *builder) NewTransformSubnetTx( } // account for subnet authorization credentials - credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(subnetSigners)) - if err != nil { - return nil, fmt.Errorf("failed calculating credentials size: %w", err) - } - if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { - return nil, fmt.Errorf("account for credentials fees: %w", err) + if _, err = fees.FinanceCredential(feeCalc, len(subnetSigners)); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) } ins, outs, _, signers, err := b.FinanceTx( @@ -1164,12 +1149,8 @@ func (b *builder) NewAddSubnetValidatorTx( } // account for subnet authorization credentials - credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(subnetSigners)) - if err != nil { - return nil, fmt.Errorf("failed calculating credentials size: %w", err) - } - if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { - return nil, fmt.Errorf("account for credentials fees: %w", err) + if _, err = fees.FinanceCredential(feeCalc, len(subnetSigners)); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) } ins, outs, _, signers, err := b.FinanceTx( @@ -1241,12 +1222,8 @@ func (b *builder) NewRemoveSubnetValidatorTx( } // account for subnet authorization credentials - credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(subnetSigners)) - if err != nil { - return nil, fmt.Errorf("failed calculating credentials size: %w", err) - } - if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { - return nil, fmt.Errorf("account for credentials fees: %w", err) + if _, err = fees.FinanceCredential(feeCalc, len(subnetSigners)); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) } ins, outs, _, signers, err := b.FinanceTx( @@ -1322,12 +1299,8 @@ func (b *builder) NewTransferSubnetOwnershipTx( } // account for subnet authorization credentials - credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(subnetSigners)) - if err != nil { - return nil, fmt.Errorf("failed calculating credentials size: %w", err) - } - if _, err := feeCalc.AddFeesFor(credsDimensions); err != nil { - return nil, fmt.Errorf("account for credentials fees: %w", err) + if _, err = fees.FinanceCredential(feeCalc, len(subnetSigners)); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) } ins, outs, _, signers, err := b.FinanceTx( diff --git a/vms/platformvm/txs/fees/helpers.go b/vms/platformvm/txs/fees/helpers.go new file mode 100644 index 000000000000..973d48a816ea --- /dev/null +++ b/vms/platformvm/txs/fees/helpers.go @@ -0,0 +1,48 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fees + +import ( + "fmt" + + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/fees" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" +) + +func FinanceInput(feeCalc *Calculator, input *avax.TransferableInput) (uint64, error) { + insDimensions, err := fees.GetInputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) + if err != nil { + return 0, fmt.Errorf("failed calculating input size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(insDimensions) + if err != nil { + return 0, fmt.Errorf("account for input fees: %w", err) + } + return addedFees, nil +} + +func FinanceOutput(feeCalc *Calculator, output *avax.TransferableOutput) (uint64, fees.Dimensions, error) { + outDimensions, err := fees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{output}) + if err != nil { + return 0, fees.Empty, fmt.Errorf("failed calculating changeOut size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(outDimensions) + if err != nil { + return 0, fees.Empty, fmt.Errorf("account for stakedOut fees: %w", err) + } + return addedFees, outDimensions, nil +} + +func FinanceCredential(feeCalc *Calculator, keysCount int) (uint64, error) { + credsDimensions, err := fees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, keysCount) + if err != nil { + return 0, fmt.Errorf("failed calculating input size: %w", err) + } + addedFees, err := feeCalc.AddFeesFor(credsDimensions) + if err != nil { + return 0, fmt.Errorf("account for input fees: %w", err) + } + return addedFees, nil +} diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index 2cf53aa0866f..3bdfec22e934 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -24,8 +24,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var ( @@ -238,13 +236,9 @@ func (h *handler) FinanceTx( }, } - credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(inSigners)) - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("failed calculating credentials size: %w", err) - } - addedFees, err := feeCalc.AddFeesFor(credsDimensions) + addedFees, err := fees.FinanceCredential(feeCalc, len(inSigners)) if err != nil { - return nil, nil, nil, nil, fmt.Errorf("account for credentials fees: %w", err) + return nil, nil, nil, nil, fmt.Errorf("account for credential fees: %w", err) } targetFee += addedFees @@ -252,11 +246,7 @@ func (h *handler) FinanceTx( remainingValue := in.Amount() // update fees to target given the extra input added - insDimensions, err := commonfees.GetInputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("failed calculating input size: %w", err) - } - addedFees, err = feeCalc.AddFeesFor(insDimensions) + addedFees, err = fees.FinanceInput(feeCalc, input) if err != nil { return nil, nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } @@ -285,11 +275,7 @@ func (h *handler) FinanceTx( } // update fees to target given the staked output added - outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{stakedOut}) - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("failed calculating stakedOut size: %w", err) - } - addedFees, err = feeCalc.AddFeesFor(outDimensions) + addedFees, _, err = fees.FinanceOutput(feeCalc, stakedOut) if err != nil { return nil, nil, nil, nil, fmt.Errorf("account for stakedOut fees: %w", err) } @@ -313,11 +299,7 @@ func (h *handler) FinanceTx( } // update fees to target given the change output added - outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("failed calculating changeOut size: %w", err) - } - addedFees, err = feeCalc.AddFeesFor(outDimensions) + addedFees, _, err := fees.FinanceOutput(feeCalc, changeOut) if err != nil { return nil, nil, nil, nil, fmt.Errorf("account for stakedOut fees: %w", err) } @@ -374,13 +356,9 @@ func (h *handler) FinanceTx( In: in, } - credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(inSigners)) + addedFees, err := fees.FinanceCredential(feeCalc, len(inSigners)) if err != nil { - return nil, nil, nil, nil, fmt.Errorf("failed calculating credentials size: %w", err) - } - addedFees, err := feeCalc.AddFeesFor(credsDimensions) - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("account for credentials fees: %w", err) + return nil, nil, nil, nil, fmt.Errorf("account for credential fees: %w", err) } targetFee += addedFees @@ -388,11 +366,7 @@ func (h *handler) FinanceTx( remainingValue := in.Amount() // update fees to target given the extra input added - insDimensions, err := commonfees.GetInputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("failed calculating input size: %w", err) - } - addedFees, err = feeCalc.AddFeesFor(insDimensions) + addedFees, err = fees.FinanceInput(feeCalc, input) if err != nil { return nil, nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } @@ -432,11 +406,7 @@ func (h *handler) FinanceTx( } // update fees to target given the extra input added - outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{stakedOut}) - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("failed calculating output size: %w", err) - } - addedFees, err := feeCalc.AddFeesFor(outDimensions) + addedFees, _, err := fees.FinanceOutput(feeCalc, stakedOut) if err != nil { return nil, nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } @@ -466,11 +436,7 @@ func (h *handler) FinanceTx( } // update fees to target given the extra input added - outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("failed calculating output size: %w", err) - } - addedFees, err := feeCalc.AddFeesFor(outDimensions) + addedFees, _, err := fees.FinanceOutput(feeCalc, changeOut) if err != nil { return nil, nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 2227f54db938..d38df9f5f626 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -25,8 +25,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var ( @@ -480,7 +478,7 @@ func (b *builder) NewAddSubnetValidatorTx( toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx // update fees to account for the auth credentials to be added upon tx signing - if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + if _, err = fees.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -528,7 +526,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx // update fees to account for the auth credentials to be added upon tx signing - if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + if _, err = fees.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -627,7 +625,7 @@ func (b *builder) NewCreateChainTx( toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx // update fees to account for the auth credentials to be added upon tx signing - if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + if _, err = fees.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -713,7 +711,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx // update fees to account for the auth credentials to be added upon tx signing - if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + if _, err = fees.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -832,7 +830,7 @@ func (b *builder) NewImportTx( } for _, sigIndices := range importedSigIndices { - if _, err = financeCredential(feeCalc, sigIndices); err != nil { + if _, err = fees.FinanceCredential(feeCalc, len(sigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } } @@ -857,11 +855,8 @@ func (b *builder) NewImportTx( } // update fees to target given the extra output added - outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{changeOut}) + _, outDimensions, err := fees.FinanceOutput(feeCalc, changeOut) if err != nil { - return nil, fmt.Errorf("failed calculating output size: %w", err) - } - if _, err := feeCalc.AddFeesFor(outDimensions); err != nil { return nil, fmt.Errorf("account for output fees: %w", err) } @@ -1004,7 +999,7 @@ func (b *builder) NewTransformSubnetTx( } // fees are calculated in financeTx // update fees to account for the auth credentials to be added upon tx signing - if _, err = financeCredential(feeCalc, subnetAuth.SigIndices); err != nil { + if _, err = fees.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -1270,13 +1265,13 @@ func (b *builder) financeTx( }, } - addedFees, err := financeInput(feeCalc, input) + addedFees, err := fees.FinanceInput(feeCalc, input) if err != nil { return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } amountsToBurn[avaxAssetID] += addedFees - addedFees, err = financeCredential(feeCalc, inputSigIndices) + addedFees, err = fees.FinanceCredential(feeCalc, len(inputSigIndices)) if err != nil { return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } @@ -1302,7 +1297,7 @@ func (b *builder) financeTx( }, } - addedFees, err = financeOutput(feeCalc, stakeOut) + addedFees, _, err = fees.FinanceOutput(feeCalc, stakeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } @@ -1325,7 +1320,7 @@ func (b *builder) financeTx( } // update fees to account for the change output - addedFees, err = financeOutput(feeCalc, changeOut) + addedFees, _, err = fees.FinanceOutput(feeCalc, changeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } @@ -1377,13 +1372,13 @@ func (b *builder) financeTx( }, } - addedFees, err := financeInput(feeCalc, input) + addedFees, err := fees.FinanceInput(feeCalc, input) if err != nil { return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } amountsToBurn[avaxAssetID] += addedFees - addedFees, err = financeCredential(feeCalc, inputSigIndices) + addedFees, err = fees.FinanceCredential(feeCalc, len(inputSigIndices)) if err != nil { return nil, nil, nil, fmt.Errorf("account for credential fees: %w", err) } @@ -1417,7 +1412,7 @@ func (b *builder) financeTx( stakeOutputs = append(stakeOutputs, stakeOut) - addedFees, err = financeOutput(feeCalc, stakeOut) + addedFees, _, err = fees.FinanceOutput(feeCalc, stakeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } @@ -1434,7 +1429,7 @@ func (b *builder) financeTx( } // update fees to account for the change output - addedFees, err = financeOutput(feeCalc, changeOut) + addedFees, _, err = fees.FinanceOutput(feeCalc, changeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } @@ -1483,42 +1478,6 @@ func (b *builder) financeTx( return inputs, changeOutputs, stakeOutputs, nil } -func financeInput(feeCalc *fees.Calculator, input *avax.TransferableInput) (uint64, error) { - insDimensions, err := commonfees.GetInputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) - if err != nil { - return 0, fmt.Errorf("failed calculating input size: %w", err) - } - addedFees, err := feeCalc.AddFeesFor(insDimensions) - if err != nil { - return 0, fmt.Errorf("account for input fees: %w", err) - } - return addedFees, nil -} - -func financeOutput(feeCalc *fees.Calculator, output *avax.TransferableOutput) (uint64, error) { - outDimensions, err := commonfees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{output}) - if err != nil { - return 0, fmt.Errorf("failed calculating changeOut size: %w", err) - } - addedFees, err := feeCalc.AddFeesFor(outDimensions) - if err != nil { - return 0, fmt.Errorf("account for stakedOut fees: %w", err) - } - return addedFees, nil -} - -func financeCredential(feeCalc *fees.Calculator, inputSigIndices []uint32) (uint64, error) { - credsDimensions, err := commonfees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, len(inputSigIndices)) - if err != nil { - return 0, fmt.Errorf("failed calculating input size: %w", err) - } - addedFees, err := feeCalc.AddFeesFor(credsDimensions) - if err != nil { - return 0, fmt.Errorf("account for input fees: %w", err) - } - return addedFees, nil -} - func (b *builder) authorizeSubnet( subnetID ids.ID, options *common.Options, From e1144d5e148d31a8d95bd432e5ba82c504cbbc77 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sat, 10 Feb 2024 00:26:19 +0100 Subject: [PATCH 022/120] consolidated code around tx metering --- vms/components/fees/helpers.go | 6 +-- vms/platformvm/txs/fees/calculator.go | 54 ++++++++++++++++++--------- vms/platformvm/txs/fees/helpers.go | 6 +-- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/vms/components/fees/helpers.go b/vms/components/fees/helpers.go index 153dc7daf6ca..05d785b0dc72 100644 --- a/vms/components/fees/helpers.go +++ b/vms/components/fees/helpers.go @@ -14,7 +14,7 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) -func GetInputsDimensions(c codec.Manager, v uint16, ins []*avax.TransferableInput) (Dimensions, error) { +func MeterInputs(c codec.Manager, v uint16, ins []*avax.TransferableInput) (Dimensions, error) { var consumedUnits Dimensions for _, in := range ins { cost, err := in.In.Cost() @@ -35,7 +35,7 @@ func GetInputsDimensions(c codec.Manager, v uint16, ins []*avax.TransferableInpu return consumedUnits, nil } -func GetOutputsDimensions(c codec.Manager, v uint16, outs []*avax.TransferableOutput) (Dimensions, error) { +func MeterOutputs(c codec.Manager, v uint16, outs []*avax.TransferableOutput) (Dimensions, error) { var consumedUnits Dimensions for _, out := range outs { outSize, err := c.Size(v, out) @@ -50,7 +50,7 @@ func GetOutputsDimensions(c codec.Manager, v uint16, outs []*avax.TransferableOu return consumedUnits, nil } -func GetCredentialsDimensions(c codec.Manager, v uint16, keysCount int) (Dimensions, error) { +func MeterSingleCredential(c codec.Manager, v uint16, keysCount int) (Dimensions, error) { var consumedUnits Dimensions // Ensure that codec picks interface instead of the pointer to evaluate size. diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index 60db001d4884..611c581c0dd1 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -8,12 +8,15 @@ import ( "fmt" "time" + "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) var ( @@ -70,7 +73,7 @@ func (fc *Calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { return nil } - consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } @@ -85,7 +88,7 @@ func (fc *Calculator) CreateChainTx(tx *txs.CreateChainTx) error { return nil } - consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } @@ -100,7 +103,7 @@ func (fc *Calculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { return nil } - consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } @@ -115,7 +118,7 @@ func (fc *Calculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) e return nil } - consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } @@ -130,7 +133,7 @@ func (fc *Calculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { return nil } - consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } @@ -145,7 +148,7 @@ func (fc *Calculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipT return nil } - consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } @@ -168,7 +171,7 @@ func (fc *Calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessVali copy(outs, tx.Outs) copy(outs[len(tx.Outs):], tx.StakeOuts) - consumedUnits, err := fc.commonConsumedUnits(tx, outs, tx.Ins) + consumedUnits, err := fc.meterTx(tx, outs, tx.Ins) if err != nil { return err } @@ -191,7 +194,7 @@ func (fc *Calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDele copy(outs, tx.Outs) copy(outs[len(tx.Outs):], tx.StakeOuts) - consumedUnits, err := fc.commonConsumedUnits(tx, outs, tx.Ins) + consumedUnits, err := fc.meterTx(tx, outs, tx.Ins) if err != nil { return err } @@ -206,7 +209,7 @@ func (fc *Calculator) BaseTx(tx *txs.BaseTx) error { return nil } - consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, tx.Ins) + consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } @@ -225,7 +228,7 @@ func (fc *Calculator) ImportTx(tx *txs.ImportTx) error { copy(ins, tx.Ins) copy(ins[len(tx.Ins):], tx.ImportedInputs) - consumedUnits, err := fc.commonConsumedUnits(tx, tx.Outs, ins) + consumedUnits, err := fc.meterTx(tx, tx.Outs, ins) if err != nil { return err } @@ -244,7 +247,7 @@ func (fc *Calculator) ExportTx(tx *txs.ExportTx) error { copy(outs, tx.Outs) copy(outs[len(tx.Outs):], tx.ExportedOutputs) - consumedUnits, err := fc.commonConsumedUnits(tx, outs, tx.Ins) + consumedUnits, err := fc.meterTx(tx, outs, tx.Ins) if err != nil { return err } @@ -253,7 +256,7 @@ func (fc *Calculator) ExportTx(tx *txs.ExportTx) error { return err } -func (fc *Calculator) commonConsumedUnits( +func (fc *Calculator) meterTx( uTx txs.UnsignedTx, allOuts []*avax.TransferableOutput, allIns []*avax.TransferableInput, @@ -264,13 +267,28 @@ func (fc *Calculator) commonConsumedUnits( if err != nil { return consumedUnits, fmt.Errorf("couldn't calculate UnsignedTx marshal length: %w", err) } - credsSize, err := txs.Codec.Size(txs.CodecVersion, fc.Credentials) - if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving size of credentials: %w", err) + consumedUnits[fees.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 fc.Credentials { + c, ok := cred.(*secp256k1fx.Credential) + if !ok { + return consumedUnits, fmt.Errorf("don't know how to calculate complexity of %T", cred) + } + credDimensions, err := fees.MeterSingleCredential(txs.Codec, txs.CodecVersion, len(c.Sigs)) + if err != nil { + return consumedUnits, fmt.Errorf("failed adding credential %d: %w", i, err) + } + consumedUnits, err = fees.Add(consumedUnits, credDimensions) + if err != nil { + return consumedUnits, fmt.Errorf("failed adding credentials: %w", err) + } } - consumedUnits[fees.Bandwidth] = uint64(uTxSize + credsSize) + consumedUnits[fees.Bandwidth] += wrappers.IntLen // length of the credentials slice + consumedUnits[fees.Bandwidth] += codec.CodecVersionSize - inputDimensions, err := fees.GetInputsDimensions(txs.Codec, txs.CodecVersion, allIns) + inputDimensions, err := fees.MeterInputs(txs.Codec, txs.CodecVersion, allIns) if err != nil { return consumedUnits, fmt.Errorf("failed retrieving size of inputs: %w", err) } @@ -280,7 +298,7 @@ func (fc *Calculator) commonConsumedUnits( return consumedUnits, fmt.Errorf("failed adding inputs: %w", err) } - outputDimensions, err := fees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, allOuts) + outputDimensions, err := fees.MeterOutputs(txs.Codec, txs.CodecVersion, allOuts) if err != nil { return consumedUnits, fmt.Errorf("failed retrieving size of outputs: %w", err) } diff --git a/vms/platformvm/txs/fees/helpers.go b/vms/platformvm/txs/fees/helpers.go index 973d48a816ea..cdcd6935bfb7 100644 --- a/vms/platformvm/txs/fees/helpers.go +++ b/vms/platformvm/txs/fees/helpers.go @@ -12,7 +12,7 @@ import ( ) func FinanceInput(feeCalc *Calculator, input *avax.TransferableInput) (uint64, error) { - insDimensions, err := fees.GetInputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) + insDimensions, err := fees.MeterInputs(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) if err != nil { return 0, fmt.Errorf("failed calculating input size: %w", err) } @@ -24,7 +24,7 @@ func FinanceInput(feeCalc *Calculator, input *avax.TransferableInput) (uint64, e } func FinanceOutput(feeCalc *Calculator, output *avax.TransferableOutput) (uint64, fees.Dimensions, error) { - outDimensions, err := fees.GetOutputsDimensions(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{output}) + outDimensions, err := fees.MeterOutputs(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{output}) if err != nil { return 0, fees.Empty, fmt.Errorf("failed calculating changeOut size: %w", err) } @@ -36,7 +36,7 @@ func FinanceOutput(feeCalc *Calculator, output *avax.TransferableOutput) (uint64 } func FinanceCredential(feeCalc *Calculator, keysCount int) (uint64, error) { - credsDimensions, err := fees.GetCredentialsDimensions(txs.Codec, txs.CodecVersion, keysCount) + credsDimensions, err := fees.MeterSingleCredential(txs.Codec, txs.CodecVersion, keysCount) if err != nil { return 0, fmt.Errorf("failed calculating input size: %w", err) } From dcc3b06786ca62fdcfea5fc3339b72aa6080e934 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sat, 10 Feb 2024 01:07:05 +0100 Subject: [PATCH 023/120] fixed compute dimension of p-chain tx metering --- vms/components/fees/helpers.go | 5 +- vms/platformvm/txs/fees/calculator_test.go | 90 +++++++++++----------- wallet/chain/p/builder_fees_test.go | 22 +++--- 3 files changed, 59 insertions(+), 58 deletions(-) diff --git a/vms/components/fees/helpers.go b/vms/components/fees/helpers.go index 05d785b0dc72..436107e37ec6 100644 --- a/vms/components/fees/helpers.go +++ b/vms/components/fees/helpers.go @@ -29,8 +29,9 @@ func MeterInputs(c codec.Manager, v uint16, ins []*avax.TransferableInput) (Dime uInSize := uint64(inSize) consumedUnits[Bandwidth] += uInSize - codec.CodecVersionSize - consumedUnits[UTXORead] += cost + uInSize // inputs are read - consumedUnits[UTXOWrite] += uInSize // inputs are deleted + consumedUnits[UTXORead] += uInSize // inputs are read + consumedUnits[UTXOWrite] += uInSize // inputs are deleted + consumedUnits[Compute] += cost } return consumedUnits, nil } diff --git a/vms/platformvm/txs/fees/calculator_test.go b/vms/platformvm/txs/fees/calculator_test.go index 8cbabc1d33dc..84ff1b68f0fe 100644 --- a/vms/platformvm/txs/fees/calculator_test.go +++ b/vms/platformvm/txs/fees/calculator_test.go @@ -36,7 +36,7 @@ var ( 3000, 3500, 1000, - 1000, + 2000, } feeTestsDefaultCfg = config.Config{ @@ -178,13 +178,13 @@ func TestTxFees(t *testing.T) { expectedError: nil, unsignedAndSignedTx: addSubnetValidatorTx, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3345*units.MicroAvax, fc.Fee) + require.Equal(t, 5345*units.MicroAvax, fc.Fee) require.Equal(t, fees.Dimensions{ 649, - 1090, + 90, 172, - 0, + 1000, }, fc.FeeManager.GetCumulatedUnits(), ) @@ -204,7 +204,7 @@ func TestTxFees(t *testing.T) { }, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 + caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: addSubnetValidatorTx, @@ -280,13 +280,13 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: createChainTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3388*units.MicroAvax, fc.Fee) + require.Equal(t, 5388*units.MicroAvax, fc.Fee) require.Equal(t, fees.Dimensions{ 692, - 1090, + 90, 172, - 0, + 1000, }, fc.FeeManager.GetCumulatedUnits(), ) @@ -307,7 +307,7 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: createChainTx, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 + caps[fees.UTXORead] = 90 - 1 return caps }, expectedError: errFailedConsumedUnitsCumulation, @@ -346,13 +346,13 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: createSubnetTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3293*units.MicroAvax, fc.Fee) + require.Equal(t, 5293*units.MicroAvax, fc.Fee) require.Equal(t, fees.Dimensions{ 597, - 1090, + 90, 172, - 0, + 1000, }, fc.FeeManager.GetCumulatedUnits(), ) @@ -372,7 +372,7 @@ func TestTxFees(t *testing.T) { }, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 + caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: createSubnetTx, @@ -412,13 +412,13 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: removeSubnetValidatorTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3321*units.MicroAvax, fc.Fee) + require.Equal(t, 5321*units.MicroAvax, fc.Fee) require.Equal(t, fees.Dimensions{ 625, - 1090, + 90, 172, - 0, + 1000, }, fc.FeeManager.GetCumulatedUnits(), ) @@ -438,7 +438,7 @@ func TestTxFees(t *testing.T) { }, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 + caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: removeSubnetValidatorTx, @@ -478,13 +478,13 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: transformSubnetTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3406*units.MicroAvax, fc.Fee) + require.Equal(t, 5406*units.MicroAvax, fc.Fee) require.Equal(t, fees.Dimensions{ 710, - 1090, + 90, 172, - 0, + 1000, }, fc.FeeManager.GetCumulatedUnits(), ) @@ -504,7 +504,7 @@ func TestTxFees(t *testing.T) { }, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 + caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: transformSubnetTx, @@ -544,13 +544,13 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: transferSubnetOwnershipTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3337*units.MicroAvax, fc.Fee) + require.Equal(t, 5337*units.MicroAvax, fc.Fee) require.Equal(t, fees.Dimensions{ 641, - 1090, + 90, 172, - 0, + 1000, }, fc.FeeManager.GetCumulatedUnits(), ) @@ -570,7 +570,7 @@ func TestTxFees(t *testing.T) { }, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 + caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: transferSubnetOwnershipTx, @@ -610,13 +610,13 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: addPermissionlessValidatorTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3939*units.MicroAvax, fc.Fee) + require.Equal(t, 5939*units.MicroAvax, fc.Fee) require.Equal(t, fees.Dimensions{ 961, - 1090, + 90, 266, - 0, + 1000, }, fc.FeeManager.GetCumulatedUnits(), ) @@ -636,7 +636,7 @@ func TestTxFees(t *testing.T) { }, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 + caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: addPermissionlessValidatorTx, @@ -676,13 +676,13 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: addPermissionlessDelegatorTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3747*units.MicroAvax, fc.Fee) + require.Equal(t, 5747*units.MicroAvax, fc.Fee) require.Equal(t, fees.Dimensions{ 769, - 1090, + 90, 266, - 0, + 1000, }, fc.FeeManager.GetCumulatedUnits(), ) @@ -702,7 +702,7 @@ func TestTxFees(t *testing.T) { }, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 + caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: addPermissionlessDelegatorTx, @@ -742,13 +742,13 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: baseTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3253*units.MicroAvax, fc.Fee) + require.Equal(t, 5253*units.MicroAvax, fc.Fee) require.Equal(t, fees.Dimensions{ 557, - 1090, + 90, 172, - 0, + 1000, }, fc.FeeManager.GetCumulatedUnits(), ) @@ -768,7 +768,7 @@ func TestTxFees(t *testing.T) { }, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 + caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: baseTx, @@ -808,13 +808,13 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: importTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 5827*units.MicroAvax, fc.Fee) + require.Equal(t, 9827*units.MicroAvax, fc.Fee) require.Equal(t, fees.Dimensions{ 681, - 2180, + 180, 262, - 0, + 2000, }, fc.FeeManager.GetCumulatedUnits(), ) @@ -834,7 +834,7 @@ func TestTxFees(t *testing.T) { }, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 + caps[fees.UTXORead] = 180 - 1 return caps }, unsignedAndSignedTx: importTx, @@ -874,13 +874,13 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: exportTx, expectedError: nil, checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, 3663*units.MicroAvax, fc.Fee) + require.Equal(t, 5663*units.MicroAvax, fc.Fee) require.Equal(t, fees.Dimensions{ 685, - 1090, + 90, 266, - 0, + 1000, }, fc.FeeManager.GetCumulatedUnits(), ) @@ -900,7 +900,7 @@ func TestTxFees(t *testing.T) { }, consumedUnitCapsF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits - caps[fees.UTXORead] = 1090 - 1 + caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: exportTx, diff --git a/wallet/chain/p/builder_fees_test.go b/wallet/chain/p/builder_fees_test.go index a2c11eab249a..9c4a24ef88a3 100644 --- a/wallet/chain/p/builder_fees_test.go +++ b/wallet/chain/p/builder_fees_test.go @@ -110,7 +110,7 @@ func TestBaseTx(t *testing.T) { Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) - require.Equal(5930*units.MicroAvax, fc.Fee) + require.Equal(9930*units.MicroAvax, fc.Fee) ins := utx.Ins outs := utx.Outs @@ -228,7 +228,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) - require.Equal(5765*units.MicroAvax, fc.Fee) + require.Equal(9765*units.MicroAvax, fc.Fee) ins := utx.Ins outs := utx.Outs @@ -334,7 +334,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) - require.Equal(5741*units.MicroAvax, fc.Fee) + require.Equal(9741*units.MicroAvax, fc.Fee) ins := utx.Ins outs := utx.Outs @@ -450,7 +450,7 @@ func TestCreateChainTx(t *testing.T) { Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) - require.Equal(5808*units.MicroAvax, fc.Fee) + require.Equal(9808*units.MicroAvax, fc.Fee) ins := utx.Ins outs := utx.Outs @@ -556,7 +556,7 @@ func TestCreateSubnetTx(t *testing.T) { Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) - require.Equal(5644*units.MicroAvax, fc.Fee) + require.Equal(9644*units.MicroAvax, fc.Fee) ins := utx.Ins outs := utx.Outs @@ -663,7 +663,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) - require.Equal(5761*units.MicroAvax, fc.Fee) + require.Equal(9761*units.MicroAvax, fc.Fee) ins := utx.Ins outs := utx.Outs @@ -775,7 +775,7 @@ func TestImportTx(t *testing.T) { Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) - require.Equal(5640*units.MicroAvax, fc.Fee) + require.Equal(9640*units.MicroAvax, fc.Fee) ins := utx.Ins outs := utx.Outs @@ -889,7 +889,7 @@ func TestExportTx(t *testing.T) { Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) - require.Equal(5966*units.MicroAvax, fc.Fee) + require.Equal(9966*units.MicroAvax, fc.Fee) ins := utx.Ins outs := utx.Outs @@ -1014,7 +1014,7 @@ func TestTransformSubnetTx(t *testing.T) { Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) - require.Equal(8763*units.MicroAvax, fc.Fee) + require.Equal(14763*units.MicroAvax, fc.Fee) ins := utx.Ins outs := utx.Outs @@ -1154,7 +1154,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) - require.Equal(12404*units.MicroAvax, fc.Fee) + require.Equal(20404*units.MicroAvax, fc.Fee) ins := utx.Ins staked := utx.StakeOuts @@ -1287,7 +1287,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) - require.Equal(12212*units.MicroAvax, fc.Fee) + require.Equal(20212*units.MicroAvax, fc.Fee) ins := utx.Ins staked := utx.StakeOuts From 25b99e4c787f406ddd92e399f43e81bcb1dc140e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sat, 10 Feb 2024 01:16:03 +0100 Subject: [PATCH 024/120] nit --- vms/components/fees/helpers.go | 50 ++++++++++++--------------- vms/platformvm/txs/fees/calculator.go | 38 +++++++++++--------- vms/platformvm/txs/fees/helpers.go | 10 +++--- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/vms/components/fees/helpers.go b/vms/components/fees/helpers.go index 436107e37ec6..069cfa9a0305 100644 --- a/vms/components/fees/helpers.go +++ b/vms/components/fees/helpers.go @@ -14,44 +14,40 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) -func MeterInputs(c codec.Manager, v uint16, ins []*avax.TransferableInput) (Dimensions, error) { +func MeterInput(c codec.Manager, v uint16, in *avax.TransferableInput) (Dimensions, error) { var consumedUnits Dimensions - for _, in := range ins { - cost, err := in.In.Cost() - if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving cost of input %s: %w", in.ID, err) - } - - inSize, err := c.Size(v, in) - if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving size of input %s: %w", in.ID, err) - } - uInSize := uint64(inSize) + cost, err := in.In.Cost() + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving cost of input %s: %w", in.ID, err) + } - consumedUnits[Bandwidth] += uInSize - codec.CodecVersionSize - consumedUnits[UTXORead] += uInSize // inputs are read - consumedUnits[UTXOWrite] += uInSize // inputs are deleted - consumedUnits[Compute] += cost + inSize, err := c.Size(v, in) + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving size of input %s: %w", in.ID, err) } + uInSize := uint64(inSize) + + consumedUnits[Bandwidth] += uInSize - codec.CodecVersionSize + consumedUnits[UTXORead] += uInSize // inputs are read + consumedUnits[UTXOWrite] += uInSize // inputs are deleted + consumedUnits[Compute] += cost return consumedUnits, nil } -func MeterOutputs(c codec.Manager, v uint16, outs []*avax.TransferableOutput) (Dimensions, error) { +func MeterOutput(c codec.Manager, v uint16, out *avax.TransferableOutput) (Dimensions, error) { var consumedUnits Dimensions - for _, out := range outs { - outSize, err := c.Size(v, out) - if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving size of output %s: %w", out.ID, err) - } - uOutSize := uint64(outSize) - - consumedUnits[Bandwidth] += uOutSize - codec.CodecVersionSize - consumedUnits[UTXOWrite] += uOutSize + outSize, err := c.Size(v, out) + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving size of output %s: %w", out.ID, err) } + uOutSize := uint64(outSize) + + consumedUnits[Bandwidth] += uOutSize - codec.CodecVersionSize + consumedUnits[UTXOWrite] += uOutSize return consumedUnits, nil } -func MeterSingleCredential(c codec.Manager, v uint16, keysCount int) (Dimensions, error) { +func MeterCredential(c codec.Manager, v uint16, keysCount int) (Dimensions, error) { var consumedUnits Dimensions // Ensure that codec picks interface instead of the pointer to evaluate size. diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index 611c581c0dd1..3005f84f4b73 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -276,7 +276,7 @@ func (fc *Calculator) meterTx( if !ok { return consumedUnits, fmt.Errorf("don't know how to calculate complexity of %T", cred) } - credDimensions, err := fees.MeterSingleCredential(txs.Codec, txs.CodecVersion, len(c.Sigs)) + credDimensions, err := fees.MeterCredential(txs.Codec, txs.CodecVersion, len(c.Sigs)) if err != nil { return consumedUnits, fmt.Errorf("failed adding credential %d: %w", i, err) } @@ -288,24 +288,28 @@ func (fc *Calculator) meterTx( consumedUnits[fees.Bandwidth] += wrappers.IntLen // length of the credentials slice consumedUnits[fees.Bandwidth] += codec.CodecVersionSize - inputDimensions, err := fees.MeterInputs(txs.Codec, txs.CodecVersion, allIns) - if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving size of inputs: %w", err) - } - inputDimensions[fees.Bandwidth] = 0 // inputs bandwidth is already accounted for above, so we zero it - consumedUnits, err = fees.Add(consumedUnits, inputDimensions) - if err != nil { - return consumedUnits, fmt.Errorf("failed adding inputs: %w", err) + for _, in := range allIns { + inputDimensions, err := fees.MeterInput(txs.Codec, txs.CodecVersion, in) + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving size of inputs: %w", err) + } + inputDimensions[fees.Bandwidth] = 0 // inputs bandwidth is already accounted for above, so we zero it + consumedUnits, err = fees.Add(consumedUnits, inputDimensions) + if err != nil { + return consumedUnits, fmt.Errorf("failed adding inputs: %w", err) + } } - outputDimensions, err := fees.MeterOutputs(txs.Codec, txs.CodecVersion, allOuts) - if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving size of outputs: %w", err) - } - outputDimensions[fees.Bandwidth] = 0 // outputs bandwidth is already accounted for above, so we zero it - consumedUnits, err = fees.Add(consumedUnits, outputDimensions) - if err != nil { - return consumedUnits, fmt.Errorf("failed adding outputs: %w", err) + for _, out := range allOuts { + outputDimensions, err := fees.MeterOutput(txs.Codec, txs.CodecVersion, out) + if err != nil { + return consumedUnits, fmt.Errorf("failed retrieving size of outputs: %w", err) + } + outputDimensions[fees.Bandwidth] = 0 // outputs bandwidth is already accounted for above, so we zero it + consumedUnits, err = fees.Add(consumedUnits, outputDimensions) + if err != nil { + return consumedUnits, fmt.Errorf("failed adding outputs: %w", err) + } } return consumedUnits, nil diff --git a/vms/platformvm/txs/fees/helpers.go b/vms/platformvm/txs/fees/helpers.go index cdcd6935bfb7..9c9f6817dabe 100644 --- a/vms/platformvm/txs/fees/helpers.go +++ b/vms/platformvm/txs/fees/helpers.go @@ -12,11 +12,11 @@ import ( ) func FinanceInput(feeCalc *Calculator, input *avax.TransferableInput) (uint64, error) { - insDimensions, err := fees.MeterInputs(txs.Codec, txs.CodecVersion, []*avax.TransferableInput{input}) + inDimensions, err := fees.MeterInput(txs.Codec, txs.CodecVersion, input) if err != nil { return 0, fmt.Errorf("failed calculating input size: %w", err) } - addedFees, err := feeCalc.AddFeesFor(insDimensions) + addedFees, err := feeCalc.AddFeesFor(inDimensions) if err != nil { return 0, fmt.Errorf("account for input fees: %w", err) } @@ -24,7 +24,7 @@ func FinanceInput(feeCalc *Calculator, input *avax.TransferableInput) (uint64, e } func FinanceOutput(feeCalc *Calculator, output *avax.TransferableOutput) (uint64, fees.Dimensions, error) { - outDimensions, err := fees.MeterOutputs(txs.Codec, txs.CodecVersion, []*avax.TransferableOutput{output}) + outDimensions, err := fees.MeterOutput(txs.Codec, txs.CodecVersion, output) if err != nil { return 0, fees.Empty, fmt.Errorf("failed calculating changeOut size: %w", err) } @@ -36,11 +36,11 @@ func FinanceOutput(feeCalc *Calculator, output *avax.TransferableOutput) (uint64 } func FinanceCredential(feeCalc *Calculator, keysCount int) (uint64, error) { - credsDimensions, err := fees.MeterSingleCredential(txs.Codec, txs.CodecVersion, keysCount) + credDimensions, err := fees.MeterCredential(txs.Codec, txs.CodecVersion, keysCount) if err != nil { return 0, fmt.Errorf("failed calculating input size: %w", err) } - addedFees, err := feeCalc.AddFeesFor(credsDimensions) + addedFees, err := feeCalc.AddFeesFor(credDimensions) if err != nil { return 0, fmt.Errorf("account for input fees: %w", err) } From d505154817b59a3fa5f11392f0732a127a7eb79b Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sat, 17 Feb 2024 20:04:17 +0100 Subject: [PATCH 025/120] nit --- wallet/chain/p/{builder_fees_test.go => builder_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename wallet/chain/p/{builder_fees_test.go => builder_test.go} (100%) diff --git a/wallet/chain/p/builder_fees_test.go b/wallet/chain/p/builder_test.go similarity index 100% rename from wallet/chain/p/builder_fees_test.go rename to wallet/chain/p/builder_test.go From 231ff5ed11a5830d6a86964827486c3eb0e964cd Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 18 Feb 2024 10:15:08 +0100 Subject: [PATCH 026/120] dropped SignerBackend mock --- wallet/chain/p/builder.go | 1 + wallet/chain/p/builder_test.go | 398 ++++++++++++++++----------------- 2 files changed, 195 insertions(+), 204 deletions(-) diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 09b82d7a7e03..d25f57022115 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -701,6 +701,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( BlockchainID: constants.PlatformChainID, Memo: ops.Memo(), }}, + Subnet: subnetID, SubnetAuth: subnetAuth, Owner: owner, } diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 09dacb0c7138..af1da6075e96 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -9,8 +9,8 @@ import ( "time" "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" + "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -19,13 +19,13 @@ import ( "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/fx" "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/txs/fees" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/chain/p/mocks" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" stdcontext "context" @@ -68,19 +68,23 @@ var ( func TestBaseTx(t *testing.T) { var ( require = require.New(t) - ctrl = gomock.NewController(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) - chainUTXOs = newChainUTXOs(require, map[ids.ID][]*avax.UTXO{ - constants.PlatformChainID: utxos, - }) - backend = NewBackend(testCtx, chainUTXOs, nil) + utxosKey = testKeys[1] + utxos = makeTestUTXOs(utxosKey) + genericBackend = newDeterministicGenericBackend( + require, + map[ids.ID][]*avax.UTXO{ + constants.PlatformChainID: utxos, + }, nil, + ) + backend = NewBackend(testCtx, genericBackend, nil) - // builder + // builder and signer utxoAddr = utxosKey.Address() builder = NewBuilder(set.Of(utxoAddr), backend) + kc = secp256k1fx.NewKeychain(utxosKey) + s = NewSigner(kc, genericBackend) // data to build the transaction outputsToMove = []*avax.TransferableOutput{{ @@ -93,17 +97,8 @@ func TestBaseTx(t *testing.T) { }, }, }} - - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) ) - // set expectations - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, @@ -186,15 +181,10 @@ func TestBaseTx(t *testing.T) { func TestAddSubnetValidatorTx(t *testing.T) { var ( require = require.New(t) - ctrl = gomock.NewController(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) - chainUTXOs = newChainUTXOs(require, map[ids.ID][]*avax.UTXO{ - constants.PlatformChainID: utxos, - }) - + utxosKey = testKeys[1] + utxos = makeTestUTXOs(utxosKey) subnetID = ids.GenerateTestID() subnetAuthKey = testKeys[0] subnetAuthAddr = subnetAuthKey.Address() @@ -202,6 +192,17 @@ func TestAddSubnetValidatorTx(t *testing.T) { Threshold: 1, Addrs: []ids.ShortID{subnetAuthAddr}, } + + genericBackend = newDeterministicGenericBackend( + require, + map[ids.ID][]*avax.UTXO{ + constants.PlatformChainID: utxos, + }, + map[ids.ID]fx.Owner{ + subnetID: subnetOwner, + }, + ) + subnets = map[ids.ID]*txs.Tx{ subnetID: { Unsigned: &txs.CreateSubnetTx{ @@ -209,12 +210,13 @@ func TestAddSubnetValidatorTx(t *testing.T) { }, }, } + backend = NewBackend(testCtx, genericBackend, subnets) - backend = NewBackend(testCtx, chainUTXOs, subnets) - - // builder + // builder and signer utxoAddr = utxosKey.Address() builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + kc = secp256k1fx.NewKeychain(utxosKey) + s = NewSigner(kc, genericBackend) // data to build the transaction subnetValidator = &txs.SubnetValidator{ @@ -224,18 +226,8 @@ func TestAddSubnetValidatorTx(t *testing.T) { }, Subnet: subnetID, } - - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) ) - // set expectations - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() - { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, @@ -313,15 +305,10 @@ func TestAddSubnetValidatorTx(t *testing.T) { func TestRemoveSubnetValidatorTx(t *testing.T) { var ( require = require.New(t) - ctrl = gomock.NewController(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) - chainUTXOs = newChainUTXOs(require, map[ids.ID][]*avax.UTXO{ - constants.PlatformChainID: utxos, - }) - + utxosKey = testKeys[1] + utxos = makeTestUTXOs(utxosKey) subnetID = ids.GenerateTestID() subnetAuthKey = testKeys[0] subnetAuthAddr = subnetAuthKey.Address() @@ -329,6 +316,17 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { Threshold: 1, Addrs: []ids.ShortID{subnetAuthAddr}, } + + genericBackend = newDeterministicGenericBackend( + require, + map[ids.ID][]*avax.UTXO{ + constants.PlatformChainID: utxos, + }, + map[ids.ID]fx.Owner{ + subnetID: subnetOwner, + }, + ) + subnets = map[ids.ID]*txs.Tx{ subnetID: { Unsigned: &txs.CreateSubnetTx{ @@ -337,23 +335,15 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { }, } - backend = NewBackend(testCtx, chainUTXOs, subnets) + backend = NewBackend(testCtx, genericBackend, subnets) - // builder + // builder and signer utxoAddr = utxosKey.Address() builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) - - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) + kc = secp256k1fx.NewKeychain(utxosKey) + s = NewSigner(kc, genericBackend) ) - // set expectations - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() - { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, @@ -437,15 +427,10 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { func TestCreateChainTx(t *testing.T) { var ( require = require.New(t) - ctrl = gomock.NewController(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) - chainUTXOs = newChainUTXOs(require, map[ids.ID][]*avax.UTXO{ - constants.PlatformChainID: utxos, - }) - + utxosKey = testKeys[1] + utxos = makeTestUTXOs(utxosKey) subnetID = ids.GenerateTestID() subnetAuthKey = testKeys[0] subnetAuthAddr = subnetAuthKey.Address() @@ -453,6 +438,17 @@ func TestCreateChainTx(t *testing.T) { Threshold: 1, Addrs: []ids.ShortID{subnetAuthAddr}, } + + genericBackend = newDeterministicGenericBackend( + require, + map[ids.ID][]*avax.UTXO{ + constants.PlatformChainID: utxos, + }, + map[ids.ID]fx.Owner{ + subnetID: subnetOwner, + }, + ) + subnets = map[ids.ID]*txs.Tx{ subnetID: { Unsigned: &txs.CreateSubnetTx{ @@ -461,28 +457,21 @@ func TestCreateChainTx(t *testing.T) { }, } - backend = NewBackend(testCtx, chainUTXOs, subnets) + backend = NewBackend(testCtx, genericBackend, subnets) + // builder and signer utxoAddr = utxosKey.Address() builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + kc = secp256k1fx.NewKeychain(utxosKey) + s = NewSigner(kc, genericBackend) // data to build the transaction genesisBytes = []byte{'a', 'b', 'c'} vmID = ids.GenerateTestID() fxIDs = []ids.ID{ids.GenerateTestID()} chainName = "dummyChain" - - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) ) - // set expectations - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() - { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, @@ -570,15 +559,10 @@ func TestCreateChainTx(t *testing.T) { func TestCreateSubnetTx(t *testing.T) { var ( require = require.New(t) - ctrl = gomock.NewController(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) - chainUTXOs = newChainUTXOs(require, map[ids.ID][]*avax.UTXO{ - constants.PlatformChainID: utxos, - }) - + utxosKey = testKeys[1] + utxos = makeTestUTXOs(utxosKey) subnetID = ids.GenerateTestID() subnetAuthKey = testKeys[0] subnetAuthAddr = subnetAuthKey.Address() @@ -586,6 +570,17 @@ func TestCreateSubnetTx(t *testing.T) { Threshold: 1, Addrs: []ids.ShortID{subnetAuthAddr}, } + + genericBackend = newDeterministicGenericBackend( + require, + map[ids.ID][]*avax.UTXO{ + constants.PlatformChainID: utxos, + }, + map[ids.ID]fx.Owner{ + subnetID: subnetOwner, + }, + ) + subnets = map[ids.ID]*txs.Tx{ subnetID: { Unsigned: &txs.CreateSubnetTx{ @@ -594,22 +589,15 @@ func TestCreateSubnetTx(t *testing.T) { }, } - backend = NewBackend(testCtx, chainUTXOs, subnets) + backend = NewBackend(testCtx, genericBackend, subnets) - // builder + // builder and signer utxoAddr = utxosKey.Address() builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) - - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) + kc = secp256k1fx.NewKeychain(utxosKey) + s = NewSigner(kc, genericBackend) ) - // setup expectations - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, @@ -690,15 +678,10 @@ func TestCreateSubnetTx(t *testing.T) { func TestTransferSubnetOwnershipTx(t *testing.T) { var ( require = require.New(t) - ctrl = gomock.NewController(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) - chainUTXOs = newChainUTXOs(require, map[ids.ID][]*avax.UTXO{ - constants.PlatformChainID: utxos, - }) - + utxosKey = testKeys[1] + utxos = makeTestUTXOs(utxosKey) subnetID = ids.GenerateTestID() subnetAuthKey = testKeys[0] subnetAuthAddr = subnetAuthKey.Address() @@ -706,6 +689,17 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { Threshold: 1, Addrs: []ids.ShortID{subnetAuthAddr}, } + + genericBackend = newDeterministicGenericBackend( + require, + map[ids.ID][]*avax.UTXO{ + constants.PlatformChainID: utxos, + }, + map[ids.ID]fx.Owner{ + subnetID: subnetOwner, + }, + ) + subnets = map[ids.ID]*txs.Tx{ subnetID: { Unsigned: &txs.CreateSubnetTx{ @@ -714,23 +708,16 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { }, } - backend = NewBackend(testCtx, chainUTXOs, subnets) + backend = NewBackend(testCtx, genericBackend, subnets) // builder utxoAddr = utxosKey.Address() builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) + kc = secp256k1fx.NewKeychain(utxosKey) + s = NewSigner(kc, genericBackend) ) - // setup expectations - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - sbe.EXPECT().GetSubnetOwner(gomock.Any(), gomock.Any()).Return(subnetOwner, nil).AnyTimes() - { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, @@ -813,23 +800,28 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { func TestImportTx(t *testing.T) { var ( require = require.New(t) - ctrl = gomock.NewController(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) - sourceChainID = ids.GenerateTestID() - importedUTXOs = utxos[:1] - chainUTXOs = newChainUTXOs(require, map[ids.ID][]*avax.UTXO{ - constants.PlatformChainID: utxos, - sourceChainID: importedUTXOs, - }) + utxosKey = testKeys[1] + utxos = makeTestUTXOs(utxosKey) + sourceChainID = ids.GenerateTestID() + importedUTXOs = utxos[:1] + genericBackend = newDeterministicGenericBackend( + require, + map[ids.ID][]*avax.UTXO{ + constants.PlatformChainID: utxos, + sourceChainID: importedUTXOs, + }, + nil, + ) - backend = NewBackend(testCtx, chainUTXOs, nil) + backend = NewBackend(testCtx, genericBackend, nil) - // builder + // builder and signer utxoAddr = utxosKey.Address() builder = NewBuilder(set.Of(utxoAddr), backend) + kc = secp256k1fx.NewKeychain(utxosKey) + s = NewSigner(kc, genericBackend) // data to build the transaction importKey = testKeys[0] @@ -839,18 +831,8 @@ func TestImportTx(t *testing.T) { importKey.Address(), }, } - - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) ) - // setup expectations - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), importedUTXOs[0].InputID()).Return(importedUTXOs[0], nil).AnyTimes() - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, @@ -937,19 +919,24 @@ func TestImportTx(t *testing.T) { func TestExportTx(t *testing.T) { var ( require = require.New(t) - ctrl = gomock.NewController(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) - chainUTXOs = newChainUTXOs(require, map[ids.ID][]*avax.UTXO{ - constants.PlatformChainID: utxos, - }) - backend = NewBackend(testCtx, chainUTXOs, nil) + utxosKey = testKeys[1] + utxos = makeTestUTXOs(utxosKey) + genericBackend = newDeterministicGenericBackend( + require, + map[ids.ID][]*avax.UTXO{ + constants.PlatformChainID: utxos, + }, + nil, + ) + backend = NewBackend(testCtx, genericBackend, nil) - // builder + // builder and signer utxoAddr = utxosKey.Address() builder = NewBuilder(set.Of(utxoAddr), backend) + kc = secp256k1fx.NewKeychain(utxosKey) + s = NewSigner(kc, genericBackend) // data to build the transaction subnetID = ids.GenerateTestID() @@ -963,17 +950,8 @@ func TestExportTx(t *testing.T) { }, }, }} - - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) ) - // setup expectation - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, @@ -1058,15 +1036,10 @@ func TestExportTx(t *testing.T) { func TestTransformSubnetTx(t *testing.T) { var ( require = require.New(t) - ctrl = gomock.NewController(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) - chainUTXOs = newChainUTXOs(require, map[ids.ID][]*avax.UTXO{ - constants.PlatformChainID: utxos, - }) - + utxosKey = testKeys[1] + utxos = makeTestUTXOs(utxosKey) subnetID = ids.GenerateTestID() subnetAuthKey = testKeys[0] subnetAuthAddr = subnetAuthKey.Address() @@ -1074,6 +1047,17 @@ func TestTransformSubnetTx(t *testing.T) { Threshold: 1, Addrs: []ids.ShortID{subnetAuthAddr}, } + + genericBackend = newDeterministicGenericBackend( + require, + map[ids.ID][]*avax.UTXO{ + constants.PlatformChainID: utxos, + }, + map[ids.ID]fx.Owner{ + subnetID: subnetOwner, + }, + ) + subnets = map[ids.ID]*txs.Tx{ subnetID: { Unsigned: &txs.CreateSubnetTx{ @@ -1082,26 +1066,19 @@ func TestTransformSubnetTx(t *testing.T) { }, } - backend = NewBackend(testCtx, chainUTXOs, subnets) + backend = NewBackend(testCtx, genericBackend, subnets) - // builder + // builder and signer utxoAddr = utxosKey.Address() builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + kc = secp256k1fx.NewKeychain(utxosKey) + s = NewSigner(kc, genericBackend) // data to build the transaction initialSupply = 40 * units.MegaAvax maxSupply = 100 * units.MegaAvax - - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) ) - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - sbe.EXPECT().GetSubnetOwner(gomock.Any(), subnetID).Return(subnetOwner, nil).AnyTimes() - { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, @@ -1214,21 +1191,26 @@ func TestTransformSubnetTx(t *testing.T) { func TestAddPermissionlessValidatorTx(t *testing.T) { var ( require = require.New(t) - ctrl = gomock.NewController(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) - chainUTXOs = newChainUTXOs(require, map[ids.ID][]*avax.UTXO{ - constants.PlatformChainID: utxos, - }) - backend = NewBackend(testCtx, chainUTXOs, nil) + utxosKey = testKeys[1] + utxos = makeTestUTXOs(utxosKey) + genericBackend = newDeterministicGenericBackend( + require, + map[ids.ID][]*avax.UTXO{ + constants.PlatformChainID: utxos, + }, + nil, + ) + backend = NewBackend(testCtx, genericBackend, nil) // builder utxoAddr = utxosKey.Address() rewardKey = testKeys[0] rewardAddr = rewardKey.Address() builder = NewBuilder(set.Of(utxoAddr, rewardAddr), backend) + kc = secp256k1fx.NewKeychain(utxosKey) + s = NewSigner(kc, genericBackend) // data to build the transaction validationRewardsOwner = &secp256k1fx.OutputOwners{ @@ -1243,20 +1225,11 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { rewardAddr, }, } - - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) ) sk, err := bls.NewSecretKey() require.NoError(err) - // setup expectations - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, @@ -1371,21 +1344,26 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { func TestAddPermissionlessDelegatorTx(t *testing.T) { var ( require = require.New(t) - ctrl = gomock.NewController(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) - chainUTXOs = newChainUTXOs(require, map[ids.ID][]*avax.UTXO{ - constants.PlatformChainID: utxos, - }) - backend = NewBackend(testCtx, chainUTXOs, nil) + utxosKey = testKeys[1] + utxos = makeTestUTXOs(utxosKey) + genericBackend = newDeterministicGenericBackend( + require, + map[ids.ID][]*avax.UTXO{ + constants.PlatformChainID: utxos, + }, + nil, + ) + backend = NewBackend(testCtx, genericBackend, nil) - // builder + // builder and signer utxoAddr = utxosKey.Address() rewardKey = testKeys[0] rewardAddr = rewardKey.Address() builder = NewBuilder(set.Of(utxoAddr, rewardAddr), backend) + kc = secp256k1fx.NewKeychain(utxosKey) + s = NewSigner(kc, genericBackend) // data to build the transaction rewardsOwner = &secp256k1fx.OutputOwners{ @@ -1394,16 +1372,8 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { rewardAddr, }, } - - kc = secp256k1fx.NewKeychain(utxosKey) - sbe = mocks.NewMockSignerBackend(ctrl) - s = NewSigner(kc, sbe) ) - for _, utxo := range utxos { - sbe.EXPECT().GetUTXO(gomock.Any(), gomock.Any(), utxo.InputID()).Return(utxo, nil).AnyTimes() - } - { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, @@ -1598,7 +1568,11 @@ func makeTestUTXOs(utxosKey *secp256k1.PrivateKey) []*avax.UTXO { } } -func newChainUTXOs(require *require.Assertions, utxoSets map[ids.ID][]*avax.UTXO) common.ChainUTXOs { +func newDeterministicGenericBackend( + require *require.Assertions, + utxoSets map[ids.ID][]*avax.UTXO, + subnetOwners map[ids.ID]fx.Owner, +) *deterministicGenericBackend { globalUTXOs := common.NewUTXOs() for subnetID, utxos := range utxoSets { for _, utxo := range utxos { @@ -1607,16 +1581,23 @@ func newChainUTXOs(require *require.Assertions, utxoSets map[ids.ID][]*avax.UTXO ) } } - return &deterministicChainUTXOs{ - ChainUTXOs: common.NewChainUTXOs(constants.PlatformChainID, globalUTXOs), + return &deterministicGenericBackend{ + ChainUTXOs: common.NewChainUTXOs(constants.PlatformChainID, globalUTXOs), + subnetOwners: subnetOwners, } } -type deterministicChainUTXOs struct { +var ( + _ common.ChainUTXOs = (*deterministicGenericBackend)(nil) + _ SignerBackend = (*deterministicGenericBackend)(nil) +) + +type deterministicGenericBackend struct { common.ChainUTXOs + subnetOwners map[ids.ID]fx.Owner // subnetID --> fx.Owner } -func (c *deterministicChainUTXOs) UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) { +func (c *deterministicGenericBackend) UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) { utxos, err := c.ChainUTXOs.UTXOs(ctx, sourceChainID) if err != nil { return nil, err @@ -1627,3 +1608,12 @@ func (c *deterministicChainUTXOs) UTXOs(ctx stdcontext.Context, sourceChainID id }) return utxos, nil } + +func (c *deterministicGenericBackend) GetSubnetOwner(_ stdcontext.Context, subnetID ids.ID) (fx.Owner, error) { + owner, found := c.subnetOwners[subnetID] + if !found { + return nil, database.ErrNotFound + } + + return owner, nil +} From 16fdab715a9c15b607eb3093542d9fe040b861bd Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 18 Feb 2024 16:09:01 +0100 Subject: [PATCH 027/120] cleaned up wallet mocks --- scripts/mocks.mockgen.txt | 2 - wallet/chain/p/mocks/mock_builder_backend.go | 213 ------------------- wallet/chain/p/mocks/mock_signer_backend.go | 73 ------- 3 files changed, 288 deletions(-) delete mode 100644 wallet/chain/p/mocks/mock_builder_backend.go delete mode 100644 wallet/chain/p/mocks/mock_signer_backend.go diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 701da0a02ac9..ba2be886b0b6 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -40,7 +40,5 @@ github.com/ava-labs/avalanchego/vms/proposervm=PostForkBlock=vms/proposervm/mock github.com/ava-labs/avalanchego/vms/registry=VMGetter=vms/registry/mock_vm_getter.go github.com/ava-labs/avalanchego/vms/registry=VMRegistry=vms/registry/mock_vm_registry.go github.com/ava-labs/avalanchego/vms=Factory,Manager=vms/mock_manager.go -github.com/ava-labs/avalanchego/wallet/chain/p=BuilderBackend=wallet/chain/p/mocks/mock_builder_backend.go -github.com/ava-labs/avalanchego/wallet/chain/p=SignerBackend=wallet/chain/p/mocks/mock_signer_backend.go github.com/ava-labs/avalanchego/x/sync=Client=x/sync/mock_client.go github.com/ava-labs/avalanchego/x/sync=NetworkClient=x/sync/mock_network_client.go diff --git a/wallet/chain/p/mocks/mock_builder_backend.go b/wallet/chain/p/mocks/mock_builder_backend.go deleted file mode 100644 index e3f8cdeb5523..000000000000 --- a/wallet/chain/p/mocks/mock_builder_backend.go +++ /dev/null @@ -1,213 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/wallet/chain/p (interfaces: BuilderBackend) -// -// Generated by this command: -// -// mockgen -package=mocks -destination=wallet/chain/p/mocks/mock_builder_backend.go github.com/ava-labs/avalanchego/wallet/chain/p BuilderBackend -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - reflect "reflect" - - ids "github.com/ava-labs/avalanchego/ids" - avax "github.com/ava-labs/avalanchego/vms/components/avax" - fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" - gomock "go.uber.org/mock/gomock" -) - -// MockBuilderBackend is a mock of BuilderBackend interface. -type MockBuilderBackend struct { - ctrl *gomock.Controller - recorder *MockBuilderBackendMockRecorder -} - -// MockBuilderBackendMockRecorder is the mock recorder for MockBuilderBackend. -type MockBuilderBackendMockRecorder struct { - mock *MockBuilderBackend -} - -// NewMockBuilderBackend creates a new mock instance. -func NewMockBuilderBackend(ctrl *gomock.Controller) *MockBuilderBackend { - mock := &MockBuilderBackend{ctrl: ctrl} - mock.recorder = &MockBuilderBackendMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockBuilderBackend) EXPECT() *MockBuilderBackendMockRecorder { - return m.recorder -} - -// AVAXAssetID mocks base method. -func (m *MockBuilderBackend) AVAXAssetID() ids.ID { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AVAXAssetID") - ret0, _ := ret[0].(ids.ID) - return ret0 -} - -// AVAXAssetID indicates an expected call of AVAXAssetID. -func (mr *MockBuilderBackendMockRecorder) AVAXAssetID() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AVAXAssetID", reflect.TypeOf((*MockBuilderBackend)(nil).AVAXAssetID)) -} - -// AddPrimaryNetworkDelegatorFee mocks base method. -func (m *MockBuilderBackend) AddPrimaryNetworkDelegatorFee() uint64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddPrimaryNetworkDelegatorFee") - ret0, _ := ret[0].(uint64) - return ret0 -} - -// AddPrimaryNetworkDelegatorFee indicates an expected call of AddPrimaryNetworkDelegatorFee. -func (mr *MockBuilderBackendMockRecorder) AddPrimaryNetworkDelegatorFee() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPrimaryNetworkDelegatorFee", reflect.TypeOf((*MockBuilderBackend)(nil).AddPrimaryNetworkDelegatorFee)) -} - -// AddPrimaryNetworkValidatorFee mocks base method. -func (m *MockBuilderBackend) AddPrimaryNetworkValidatorFee() uint64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddPrimaryNetworkValidatorFee") - ret0, _ := ret[0].(uint64) - return ret0 -} - -// AddPrimaryNetworkValidatorFee indicates an expected call of AddPrimaryNetworkValidatorFee. -func (mr *MockBuilderBackendMockRecorder) AddPrimaryNetworkValidatorFee() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPrimaryNetworkValidatorFee", reflect.TypeOf((*MockBuilderBackend)(nil).AddPrimaryNetworkValidatorFee)) -} - -// AddSubnetDelegatorFee mocks base method. -func (m *MockBuilderBackend) AddSubnetDelegatorFee() uint64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddSubnetDelegatorFee") - ret0, _ := ret[0].(uint64) - return ret0 -} - -// AddSubnetDelegatorFee indicates an expected call of AddSubnetDelegatorFee. -func (mr *MockBuilderBackendMockRecorder) AddSubnetDelegatorFee() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetDelegatorFee", reflect.TypeOf((*MockBuilderBackend)(nil).AddSubnetDelegatorFee)) -} - -// AddSubnetValidatorFee mocks base method. -func (m *MockBuilderBackend) AddSubnetValidatorFee() uint64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddSubnetValidatorFee") - ret0, _ := ret[0].(uint64) - return ret0 -} - -// AddSubnetValidatorFee indicates an expected call of AddSubnetValidatorFee. -func (mr *MockBuilderBackendMockRecorder) AddSubnetValidatorFee() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetValidatorFee", reflect.TypeOf((*MockBuilderBackend)(nil).AddSubnetValidatorFee)) -} - -// BaseTxFee mocks base method. -func (m *MockBuilderBackend) BaseTxFee() uint64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BaseTxFee") - ret0, _ := ret[0].(uint64) - return ret0 -} - -// BaseTxFee indicates an expected call of BaseTxFee. -func (mr *MockBuilderBackendMockRecorder) BaseTxFee() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BaseTxFee", reflect.TypeOf((*MockBuilderBackend)(nil).BaseTxFee)) -} - -// CreateBlockchainTxFee mocks base method. -func (m *MockBuilderBackend) CreateBlockchainTxFee() uint64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateBlockchainTxFee") - ret0, _ := ret[0].(uint64) - return ret0 -} - -// CreateBlockchainTxFee indicates an expected call of CreateBlockchainTxFee. -func (mr *MockBuilderBackendMockRecorder) CreateBlockchainTxFee() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateBlockchainTxFee", reflect.TypeOf((*MockBuilderBackend)(nil).CreateBlockchainTxFee)) -} - -// CreateSubnetTxFee mocks base method. -func (m *MockBuilderBackend) CreateSubnetTxFee() uint64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateSubnetTxFee") - ret0, _ := ret[0].(uint64) - return ret0 -} - -// CreateSubnetTxFee indicates an expected call of CreateSubnetTxFee. -func (mr *MockBuilderBackendMockRecorder) CreateSubnetTxFee() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSubnetTxFee", reflect.TypeOf((*MockBuilderBackend)(nil).CreateSubnetTxFee)) -} - -// GetSubnetOwner mocks base method. -func (m *MockBuilderBackend) GetSubnetOwner(arg0 context.Context, arg1 ids.ID) (fx.Owner, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetOwner", arg0, arg1) - ret0, _ := ret[0].(fx.Owner) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockBuilderBackendMockRecorder) GetSubnetOwner(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockBuilderBackend)(nil).GetSubnetOwner), arg0, arg1) -} - -// NetworkID mocks base method. -func (m *MockBuilderBackend) NetworkID() uint32 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NetworkID") - ret0, _ := ret[0].(uint32) - return ret0 -} - -// NetworkID indicates an expected call of NetworkID. -func (mr *MockBuilderBackendMockRecorder) NetworkID() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkID", reflect.TypeOf((*MockBuilderBackend)(nil).NetworkID)) -} - -// TransformSubnetTxFee mocks base method. -func (m *MockBuilderBackend) TransformSubnetTxFee() uint64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TransformSubnetTxFee") - ret0, _ := ret[0].(uint64) - return ret0 -} - -// TransformSubnetTxFee indicates an expected call of TransformSubnetTxFee. -func (mr *MockBuilderBackendMockRecorder) TransformSubnetTxFee() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransformSubnetTxFee", reflect.TypeOf((*MockBuilderBackend)(nil).TransformSubnetTxFee)) -} - -// UTXOs mocks base method. -func (m *MockBuilderBackend) UTXOs(arg0 context.Context, arg1 ids.ID) ([]*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UTXOs", arg0, arg1) - ret0, _ := ret[0].([]*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// UTXOs indicates an expected call of UTXOs. -func (mr *MockBuilderBackendMockRecorder) UTXOs(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UTXOs", reflect.TypeOf((*MockBuilderBackend)(nil).UTXOs), arg0, arg1) -} diff --git a/wallet/chain/p/mocks/mock_signer_backend.go b/wallet/chain/p/mocks/mock_signer_backend.go deleted file mode 100644 index 9ad6db9e76dd..000000000000 --- a/wallet/chain/p/mocks/mock_signer_backend.go +++ /dev/null @@ -1,73 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/wallet/chain/p (interfaces: SignerBackend) -// -// Generated by this command: -// -// mockgen -package=mocks -destination=wallet/chain/p/mocks/mock_signer_backend.go github.com/ava-labs/avalanchego/wallet/chain/p SignerBackend -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - reflect "reflect" - - ids "github.com/ava-labs/avalanchego/ids" - avax "github.com/ava-labs/avalanchego/vms/components/avax" - fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" - gomock "go.uber.org/mock/gomock" -) - -// MockSignerBackend is a mock of SignerBackend interface. -type MockSignerBackend struct { - ctrl *gomock.Controller - recorder *MockSignerBackendMockRecorder -} - -// MockSignerBackendMockRecorder is the mock recorder for MockSignerBackend. -type MockSignerBackendMockRecorder struct { - mock *MockSignerBackend -} - -// NewMockSignerBackend creates a new mock instance. -func NewMockSignerBackend(ctrl *gomock.Controller) *MockSignerBackend { - mock := &MockSignerBackend{ctrl: ctrl} - mock.recorder = &MockSignerBackendMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockSignerBackend) EXPECT() *MockSignerBackendMockRecorder { - return m.recorder -} - -// GetSubnetOwner mocks base method. -func (m *MockSignerBackend) GetSubnetOwner(arg0 context.Context, arg1 ids.ID) (fx.Owner, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetOwner", arg0, arg1) - ret0, _ := ret[0].(fx.Owner) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockSignerBackendMockRecorder) GetSubnetOwner(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockSignerBackend)(nil).GetSubnetOwner), arg0, arg1) -} - -// GetUTXO mocks base method. -func (m *MockSignerBackend) GetUTXO(arg0 context.Context, arg1, arg2 ids.ID) (*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUTXO", arg0, arg1, arg2) - ret0, _ := ret[0].(*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetUTXO indicates an expected call of GetUTXO. -func (mr *MockSignerBackendMockRecorder) GetUTXO(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockSignerBackend)(nil).GetUTXO), arg0, arg1, arg2) -} From 7f11841b57789a26fcdab0b627acbe4ca82f655e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 19 Feb 2024 12:04:40 +0100 Subject: [PATCH 028/120] minor fix --- wallet/chain/p/builder.go | 10 +++++++++- wallet/chain/p/builder_test.go | 6 +++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index d25f57022115..5b8d86547a51 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -385,8 +385,16 @@ func (b *builder) newBaseTxPreEUpgrade( } // 2. Finance the tx by building the utxos (inputs, outputs and stakes) - toStake := map[ids.ID]uint64{} toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx + for _, out := range outputs { + assetID := out.AssetID() + amountToBurn, err := math.Add64(toBurn[assetID], out.Out.Amount()) + if err != nil { + return nil, err + } + toBurn[assetID] = amountToBurn + } + toStake := map[ids.ID]uint64{} // feesMan cumulates consumed units. Let's init it with utx filled so far if err := feeCalc.CreateSubnetTx(utx); err != nil { diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index af1da6075e96..1adc211a51bf 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -168,11 +168,11 @@ func TestBaseTx(t *testing.T) { // check UTXOs selection and fee financing ins := utx.Ins outs := utx.Outs - require.Len(ins, 1) + require.Len(ins, 2) require.Len(outs, 2) - expectedConsumed := fc.Fee - consumed := ins[0].In.Amount() - outs[0].Out.Amount() + expectedConsumed := fc.Fee + outputsToMove[0].Out.Amount() + consumed := ins[0].In.Amount() + ins[1].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) require.Equal(outputsToMove[0], outs[1]) } From f5ff8d67902e8b1ff64e87e59414174817f52afe Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 19 Feb 2024 18:32:57 +0100 Subject: [PATCH 029/120] spend cleanup --- vms/platformvm/txs/builder/builder.go | 90 +++++- .../txs/executor/create_chain_test.go | 6 +- .../txs/executor/create_subnet_test.go | 6 +- vms/platformvm/utxo/handler.go | 263 +++++++++--------- 4 files changed, 212 insertions(+), 153 deletions(-) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 626edf6e56ee..03be8303c4f8 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -340,7 +340,11 @@ func (b *builder) NewImportTx( switch { case importedAVAX < b.cfg.TxFee: // imported amount goes toward paying tx fee var baseSigners [][]*secp256k1.PrivateKey - ins, outs, _, baseSigners, err = b.Spend(b.state, keys, 0, b.cfg.TxFee-importedAVAX, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: b.cfg.TxFee - importedAVAX, + } + toStake := make(map[ids.ID]uint64) + ins, outs, _, baseSigners, err = b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -396,11 +400,15 @@ func (b *builder) NewExportTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - toBurn, err := math.Add64(amount, b.cfg.TxFee) + amtToBurn, err := math.Add64(amount, b.cfg.TxFee) if err != nil { return nil, fmt.Errorf("amount (%d) + tx fee(%d) overflows", amount, b.cfg.TxFee) } - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, toBurn, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: amtToBurn, + } + toStake := make(map[ids.ID]uint64) + ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -446,7 +454,11 @@ func (b *builder) NewCreateChainTx( ) (*txs.Tx, error) { timestamp := b.state.GetTimestamp() createBlockchainTxFee := b.cfg.GetCreateBlockchainTxFee(timestamp) - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, createBlockchainTxFee, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: createBlockchainTxFee, + } + toStake := make(map[ids.ID]uint64) + ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -492,7 +504,11 @@ func (b *builder) NewCreateSubnetTx( ) (*txs.Tx, error) { timestamp := b.state.GetTimestamp() createSubnetTxFee := b.cfg.GetCreateSubnetTxFee(timestamp) - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, createSubnetTxFee, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: createSubnetTxFee, + } + toStake := make(map[ids.ID]uint64) + ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -540,7 +556,11 @@ func (b *builder) NewTransformSubnetTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, b.cfg.TransformSubnetTxFee, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: b.cfg.TransformSubnetTxFee, + } + toStake := make(map[ids.ID]uint64) + ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -596,7 +616,13 @@ func (b *builder) NewAddValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - ins, unstakedOuts, stakedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkValidatorFee, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: b.cfg.AddPrimaryNetworkValidatorFee, + } + toStake := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: stakeAmount, + } + ins, unstakedOuts, stakedOuts, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -642,7 +668,13 @@ func (b *builder) NewAddPermissionlessValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - ins, unstakedOuts, stakedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkValidatorFee, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: b.cfg.AddPrimaryNetworkValidatorFee, + } + toStake := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: stakeAmount, + } + ins, unstakedOuts, stakedOuts, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -693,7 +725,13 @@ func (b *builder) NewAddDelegatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - ins, unlockedOuts, lockedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkDelegatorFee, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: b.cfg.AddPrimaryNetworkDelegatorFee, + } + toStake := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: stakeAmount, + } + ins, unlockedOuts, lockedOuts, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -736,7 +774,13 @@ func (b *builder) NewAddPermissionlessDelegatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - ins, unlockedOuts, lockedOuts, signers, err := b.Spend(b.state, keys, stakeAmount, b.cfg.AddPrimaryNetworkDelegatorFee, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: b.cfg.AddPrimaryNetworkDelegatorFee, + } + toStake := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: stakeAmount, + } + ins, unlockedOuts, lockedOuts, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -780,7 +824,11 @@ func (b *builder) NewAddSubnetValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: b.cfg.TxFee, + } + toStake := make(map[ids.ID]uint64) + ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -825,7 +873,11 @@ func (b *builder) NewRemoveSubnetValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: b.cfg.TxFee, + } + toStake := make(map[ids.ID]uint64) + ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -864,7 +916,11 @@ func (b *builder) NewTransferSubnetOwnershipTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, b.cfg.TxFee, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: b.cfg.TxFee, + } + toStake := make(map[ids.ID]uint64) + ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -904,11 +960,15 @@ func (b *builder) NewBaseTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - toBurn, err := math.Add64(amount, b.cfg.TxFee) + amtToBurn, err := math.Add64(amount, b.cfg.TxFee) if err != nil { return nil, fmt.Errorf("amount (%d) + tx fee(%d) overflows", amount, b.cfg.TxFee) } - ins, outs, _, signers, err := b.Spend(b.state, keys, 0, toBurn, changeAddr) + toBurn := map[ids.ID]uint64{ + b.ctx.AVAXAssetID: amtToBurn, + } + toStake := make(map[ids.ID]uint64) + ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 8da002d2c5cb..b7a5abfd1ee7 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -194,7 +194,11 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.config.ApricotPhase3Time = ap3Time - ins, outs, _, signers, err := env.utxosHandler.Spend(env.state, preFundedKeys, 0, test.fee, ids.ShortEmpty) + toBurn := map[ids.ID]uint64{ + env.ctx.AVAXAssetID: test.fee, + } + toStake := make(map[ids.ID]uint64) + ins, outs, _, signers, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) require.NoError(err) subnetAuth, subnetSigners, err := env.utxosHandler.Authorize(env.state, testSubnet1.ID(), preFundedKeys) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 6d968daa4df0..dae8c5e08fc5 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -54,7 +54,11 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - ins, outs, _, signers, err := env.utxosHandler.Spend(env.state, preFundedKeys, 0, test.fee, ids.ShortEmpty) + toBurn := map[ids.ID]uint64{ + env.ctx.AVAXAssetID: test.fee, + } + toStake := make(map[ids.ID]uint64) + ins, outs, _, signers, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) require.NoError(err) // Create the tx diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index 6368d97c11c8..39e688eb6bad 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -37,6 +37,7 @@ var ( errLocktimeMismatch = errors.New("input locktime does not match UTXO locktime") errCantSign = errors.New("can't sign") errLockedFundsNotMarkedAsLocked = errors.New("locked funds not marked as locked") + errUnknownOutputType = errors.New("unknown output type") ) // TODO: Stake and Authorize should be replaced by similar methods in the @@ -58,8 +59,8 @@ type Spender interface { Spend( utxoReader avax.UTXOReader, keys []*secp256k1.PrivateKey, - amount uint64, - fee uint64, + amountsToBurn map[ids.ID]uint64, + amountsToStake map[ids.ID]uint64, changeAddr ids.ShortID, ) ( []*avax.TransferableInput, // inputs @@ -149,15 +150,15 @@ type handler struct { func (h *handler) Spend( utxoReader avax.UTXOReader, keys []*secp256k1.PrivateKey, - amount uint64, - fee uint64, + amountsToBurn map[ids.ID]uint64, + amountsToStake map[ids.ID]uint64, changeAddr ids.ShortID, ) ( - []*avax.TransferableInput, // inputs - []*avax.TransferableOutput, // returnedOutputs - []*avax.TransferableOutput, // stakedOutputs - [][]*secp256k1.PrivateKey, // signers - error, + inputs []*avax.TransferableInput, + changeOutputs []*avax.TransferableOutput, + stakeOutputs []*avax.TransferableOutput, + signers [][]*secp256k1.PrivateKey, + err error, ) { addrs := set.NewSet[ids.ShortID](len(keys)) // The addresses controlled by [keys] for _, key := range keys { @@ -171,47 +172,43 @@ func (h *handler) Spend( kc := secp256k1fx.NewKeychain(keys...) // Keychain consumes UTXOs and creates new ones // Minimum time this transaction will be issued at - now := uint64(h.clk.Time().Unix()) - - ins := []*avax.TransferableInput{} - returnedOuts := []*avax.TransferableOutput{} - stakedOuts := []*avax.TransferableOutput{} - signers := [][]*secp256k1.PrivateKey{} + minIssuanceTime := uint64(h.clk.Time().Unix()) - // Amount of AVAX that has been staked - amountStaked := uint64(0) + changeOwner := &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + } - // Consume locked UTXOs + // Iterate over the locked UTXOs for _, utxo := range utxos { - // If we have consumed more AVAX than we are trying to stake, then we - // have no need to consume more locked AVAX - if amountStaked >= amount { - break - } + assetID := utxo.AssetID() + remainingAmountToStake := amountsToStake[assetID] - if assetID := utxo.AssetID(); assetID != h.ctx.AVAXAssetID { - continue // We only care about staking AVAX, so ignore other assets + // If we have staked enough of the asset, then we have no need burn + // more. + if remainingAmountToStake == 0 { + continue } - out, ok := utxo.Out.(*stakeable.LockOut) + outIntf := utxo.Out + lockedOut, ok := outIntf.(*stakeable.LockOut) if !ok { // This output isn't locked, so it will be handled during the next // iteration of the UTXO set continue } - if out.Locktime <= now { - // This output is no longer locked, so it will be handled during the - // next iteration of the UTXO set + if minIssuanceTime >= lockedOut.Locktime { + // This output isn't locked, so it will be handled during the next + // iteration of the UTXO set continue } - inner, ok := out.TransferableOut.(*secp256k1fx.TransferOutput) + out, ok := lockedOut.TransferableOut.(*secp256k1fx.TransferOutput) if !ok { - // We only know how to clone secp256k1 outputs for now - continue + return nil, nil, nil, nil, errUnknownOutputType } - inIntf, inSigners, err := kc.Spend(out.TransferableOut, now) + inIntf, inSigners, err := kc.Spend(out, minIssuanceTime) if err != nil { // We couldn't spend the output, so move on to the next one continue @@ -225,169 +222,163 @@ func (h *handler) Spend( continue } - // The remaining value is initially the full value of the input - remainingValue := in.Amount() - - // Stake any value that should be staked - amountToStake := min( - amount-amountStaked, // Amount we still need to stake - remainingValue, // Amount available to stake - ) - amountStaked += amountToStake - remainingValue -= amountToStake - - // Add the input to the consumed inputs - ins = append(ins, &avax.TransferableInput{ + inputs = append(inputs, &avax.TransferableInput{ UTXOID: utxo.UTXOID, - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, + Asset: utxo.Asset, In: &stakeable.LockIn{ - Locktime: out.Locktime, + Locktime: lockedOut.Locktime, TransferableIn: in, }, }) + // Add the signers needed for this input to the set of signers + signers = append(signers, inSigners) + + // Stake any value that should be staked + amountToStake := min( + remainingAmountToStake, // Amount we still need to stake + out.Amt, // Amount available to stake + ) + // Add the output to the staked outputs - stakedOuts = append(stakedOuts, &avax.TransferableOutput{ - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, + stakeOutputs = append(stakeOutputs, &avax.TransferableOutput{ + Asset: utxo.Asset, Out: &stakeable.LockOut{ - Locktime: out.Locktime, + Locktime: lockedOut.Locktime, TransferableOut: &secp256k1fx.TransferOutput{ Amt: amountToStake, - OutputOwners: inner.OutputOwners, + OutputOwners: out.OutputOwners, }, }, }) - if remainingValue > 0 { - // This input provided more value than was needed to be locked. - // Some of it must be returned - returnedOuts = append(returnedOuts, &avax.TransferableOutput{ - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, + amountsToStake[assetID] -= amountToStake + if remainingAmount := out.Amt - amountToStake; remainingAmount > 0 { + // This input had extra value, so some of it must be returned + changeOutputs = append(changeOutputs, &avax.TransferableOutput{ + Asset: utxo.Asset, Out: &stakeable.LockOut{ - Locktime: out.Locktime, + Locktime: lockedOut.Locktime, TransferableOut: &secp256k1fx.TransferOutput{ - Amt: remainingValue, - OutputOwners: inner.OutputOwners, + Amt: remainingAmount, + OutputOwners: out.OutputOwners, }, }, }) } - - // Add the signers needed for this input to the set of signers - signers = append(signers, inSigners) } - // Amount of AVAX that has been burned - amountBurned := uint64(0) - + // Iterate over the unlocked UTXOs for _, utxo := range utxos { - // If we have consumed more AVAX than we are trying to stake, - // and we have burned more AVAX than we need to, - // then we have no need to consume more AVAX - if amountBurned >= fee && amountStaked >= amount { - break - } + assetID := utxo.AssetID() + remainingAmountToStake := amountsToStake[assetID] + remainingAmountToBurn := amountsToBurn[assetID] - if assetID := utxo.AssetID(); assetID != h.ctx.AVAXAssetID { - continue // We only care about burning AVAX, so ignore other assets + // If we have consumed enough of the asset, then we have no need burn + // more. + if remainingAmountToStake == 0 && remainingAmountToBurn == 0 { + continue } - out := utxo.Out - inner, ok := out.(*stakeable.LockOut) - if ok { - if inner.Locktime > now { + outIntf := utxo.Out + if lockedOut, ok := outIntf.(*stakeable.LockOut); ok { + if lockedOut.Locktime > minIssuanceTime { // This output is currently locked, so this output can't be - // burned. Additionally, it may have already been consumed - // above. Regardless, we skip to the next UTXO + // burned. continue } - out = inner.TransferableOut + outIntf = lockedOut.TransferableOut + } + + out, ok := outIntf.(*secp256k1fx.TransferOutput) + if !ok { + return nil, nil, nil, nil, errUnknownOutputType } - inIntf, inSigners, err := kc.Spend(out, now) + inIntf, inSigners, err := kc.Spend(out, minIssuanceTime) if err != nil { - // We couldn't spend this UTXO, so we skip to the next one + // We couldn't spend the output, so move on to the next one continue } in, ok := inIntf.(avax.TransferableIn) - if !ok { - // Because we only use the secp Fx right now, this should never - // happen + if !ok { // should never happen + h.ctx.Log.Warn("wrong input type", + zap.String("expectedType", "avax.TransferableIn"), + zap.String("actualType", fmt.Sprintf("%T", inIntf)), + ) continue } - // The remaining value is initially the full value of the input - remainingValue := in.Amount() + inputs = append(inputs, &avax.TransferableInput{ + UTXOID: utxo.UTXOID, + Asset: utxo.Asset, + In: in, + }) + + // Add the signers needed for this input to the set of signers + signers = append(signers, inSigners) // Burn any value that should be burned amountToBurn := min( - fee-amountBurned, // Amount we still need to burn - remainingValue, // Amount available to burn + remainingAmountToBurn, // Amount we still need to burn + out.Amt, // Amount available to burn ) - amountBurned += amountToBurn - remainingValue -= amountToBurn + amountsToBurn[assetID] -= amountToBurn - // Stake any value that should be staked + amountAvalibleToStake := out.Amt - amountToBurn + // Burn any value that should be burned amountToStake := min( - amount-amountStaked, // Amount we still need to stake - remainingValue, // Amount available to stake + remainingAmountToStake, // Amount we still need to stake + amountAvalibleToStake, // Amount available to stake ) - amountStaked += amountToStake - remainingValue -= amountToStake - - // Add the input to the consumed inputs - ins = append(ins, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, - In: in, - }) - + amountsToStake[assetID] -= amountToStake if amountToStake > 0 { // Some of this input was put for staking - stakedOuts = append(stakedOuts, &avax.TransferableOutput{ - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, + stakeOutputs = append(stakeOutputs, &avax.TransferableOutput{ + Asset: utxo.Asset, Out: &secp256k1fx.TransferOutput{ - Amt: amountToStake, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{changeAddr}, - }, + Amt: amountToStake, + OutputOwners: *changeOwner, }, }) } - - if remainingValue > 0 { + if remainingAmount := amountAvalibleToStake - amountToStake; remainingAmount > 0 { // This input had extra value, so some of it must be returned - returnedOuts = append(returnedOuts, &avax.TransferableOutput{ - Asset: avax.Asset{ID: h.ctx.AVAXAssetID}, + changeOutputs = append(changeOutputs, &avax.TransferableOutput{ + Asset: utxo.Asset, Out: &secp256k1fx.TransferOutput{ - Amt: remainingValue, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{changeAddr}, - }, + Amt: remainingAmount, + OutputOwners: *changeOwner, }, }) } - - // Add the signers needed for this input to the set of signers - signers = append(signers, inSigners) } - if amountBurned < fee || amountStaked < amount { - return nil, nil, nil, nil, fmt.Errorf( - "%w (unlocked, locked) (%d, %d) but need (%d, %d)", - ErrInsufficientFunds, amountBurned, amountStaked, fee, amount, - ) + for assetID, amount := range amountsToStake { + if amount != 0 { + return nil, nil, nil, nil, fmt.Errorf( + "%w: provided UTXOs need %d more units of asset %q to stake", + ErrInsufficientFunds, + amount, + assetID, + ) + } + } + for assetID, amount := range amountsToBurn { + if amount != 0 { + return nil, nil, nil, nil, fmt.Errorf( + "%w: provided UTXOs need %d more units of asset %q", + ErrInsufficientFunds, + amount, + assetID, + ) + } } - avax.SortTransferableInputsWithSigners(ins, signers) // sort inputs and keys - avax.SortTransferableOutputs(returnedOuts, txs.Codec) // sort outputs - avax.SortTransferableOutputs(stakedOuts, txs.Codec) // sort outputs - - return ins, returnedOuts, stakedOuts, signers, nil + avax.SortTransferableInputsWithSigners(inputs, signers) // sort inputs and keys + avax.SortTransferableOutputs(changeOutputs, txs.Codec) // sort the change outputs + avax.SortTransferableOutputs(stakeOutputs, txs.Codec) // sort stake outputs + return inputs, changeOutputs, stakeOutputs, signers, nil } func (h *handler) Authorize( From 7f594ea0ff5d6a39b4261472e92cb0be9b321121 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 19 Feb 2024 23:39:38 +0100 Subject: [PATCH 030/120] repackaged signer from wallet to pchain txs subpackage --- vms/platformvm/txs/signer/backend.go | 17 +++++ .../p => vms/platformvm/txs/signer}/signer.go | 30 ++++----- .../platformvm/txs/signer/visitor.go | 62 +++++++++---------- wallet/chain/p/backend.go | 3 +- wallet/chain/p/backend_visitor.go | 5 +- wallet/chain/p/builder.go | 13 ++-- wallet/chain/p/wallet.go | 18 +++--- wallet/chain/p/wallet_with_options.go | 5 +- wallet/subnet/primary/example_test.go | 5 +- wallet/subnet/primary/wallet.go | 4 +- 10 files changed, 90 insertions(+), 72 deletions(-) create mode 100644 vms/platformvm/txs/signer/backend.go rename {wallet/chain/p => vms/platformvm/txs/signer}/signer.go (57%) rename wallet/chain/p/signer_visitor.go => vms/platformvm/txs/signer/visitor.go (82%) diff --git a/vms/platformvm/txs/signer/backend.go b/vms/platformvm/txs/signer/backend.go new file mode 100644 index 000000000000..e864da0ec3d6 --- /dev/null +++ b/vms/platformvm/txs/signer/backend.go @@ -0,0 +1,17 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package signer + +import ( + "context" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" +) + +type Backend interface { + GetUTXO(ctx context.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) + GetSubnetOwner(ctx context.Context, subnetID ids.ID) (fx.Owner, error) +} diff --git a/wallet/chain/p/signer.go b/vms/platformvm/txs/signer/signer.go similarity index 57% rename from wallet/chain/p/signer.go rename to vms/platformvm/txs/signer/signer.go index bedbbdbf562a..1902f99d2b75 100644 --- a/wallet/chain/p/signer.go +++ b/vms/platformvm/txs/signer/signer.go @@ -1,16 +1,13 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package p +package signer import ( - "github.com/ava-labs/avalanchego/ids" + "context" + "github.com/ava-labs/avalanchego/utils/crypto/keychain" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - stdcontext "context" ) var _ Signer = (*txSigner)(nil) @@ -24,28 +21,23 @@ type Signer interface { // // If the signer doesn't have the ability to provide a required signature, // the signature slot will be skipped without reporting an error. - Sign(ctx stdcontext.Context, tx *txs.Tx) error -} - -type SignerBackend interface { - GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) - GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) + Sign(ctx context.Context, tx *txs.Tx) error } type txSigner struct { kc keychain.Keychain - backend SignerBackend + backend Backend } -func NewSigner(kc keychain.Keychain, backend SignerBackend) Signer { +func New(kc keychain.Keychain, backend Backend) Signer { return &txSigner{ kc: kc, backend: backend, } } -func (s *txSigner) Sign(ctx stdcontext.Context, tx *txs.Tx) error { - return tx.Unsigned.Visit(&signerVisitor{ +func (s *txSigner) Sign(ctx context.Context, tx *txs.Tx) error { + return tx.Unsigned.Visit(&Visitor{ kc: s.kc, backend: s.backend, ctx: ctx, @@ -54,10 +46,10 @@ func (s *txSigner) Sign(ctx stdcontext.Context, tx *txs.Tx) error { } func SignUnsigned( - ctx stdcontext.Context, - signer Signer, + ctx context.Context, + s Signer, utx txs.UnsignedTx, ) (*txs.Tx, error) { tx := &txs.Tx{Unsigned: utx} - return tx, signer.Sign(ctx, tx) + return tx, s.Sign(ctx, tx) } diff --git a/wallet/chain/p/signer_visitor.go b/vms/platformvm/txs/signer/visitor.go similarity index 82% rename from wallet/chain/p/signer_visitor.go rename to vms/platformvm/txs/signer/visitor.go index 7c9dd4cb95ca..3e41a6952d7d 100644 --- a/wallet/chain/p/signer_visitor.go +++ b/vms/platformvm/txs/signer/visitor.go @@ -1,9 +1,10 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package p +package signer import ( + "context" "errors" "fmt" @@ -18,40 +19,39 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - - stdcontext "context" ) var ( - _ txs.Visitor = (*signerVisitor)(nil) + _ txs.Visitor = (*Visitor)(nil) - errUnsupportedTxType = errors.New("unsupported tx type") + ErrUnknownOwnerType = errors.New("unknown owner type") + ErrUnknownOutputType = errors.New("unknown output type") + ErrUnsupportedTxType = errors.New("unsupported tx type") errUnknownInputType = errors.New("unknown input type") errUnknownCredentialType = errors.New("unknown credential type") - errUnknownOutputType = errors.New("unknown output type") errUnknownSubnetAuthType = errors.New("unknown subnet auth type") errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") emptySig [secp256k1.SignatureLen]byte ) -// signerVisitor handles signing transactions for the signer -type signerVisitor struct { +// Visitor handles signing transactions for the signer +type Visitor struct { kc keychain.Keychain - backend SignerBackend - ctx stdcontext.Context + backend Backend + ctx context.Context tx *txs.Tx } -func (*signerVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - return errUnsupportedTxType +func (*Visitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + return ErrUnsupportedTxType } -func (*signerVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { - return errUnsupportedTxType +func (*Visitor) RewardValidatorTx(*txs.RewardValidatorTx) error { + return ErrUnsupportedTxType } -func (s *signerVisitor) BaseTx(tx *txs.BaseTx) error { +func (s *Visitor) BaseTx(tx *txs.BaseTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -59,7 +59,7 @@ func (s *signerVisitor) BaseTx(tx *txs.BaseTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) AddValidatorTx(tx *txs.AddValidatorTx) error { +func (s *Visitor) AddValidatorTx(tx *txs.AddValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -67,7 +67,7 @@ func (s *signerVisitor) AddValidatorTx(tx *txs.AddValidatorTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { +func (s *Visitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -80,7 +80,7 @@ func (s *signerVisitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error return sign(s.tx, false, txSigners) } -func (s *signerVisitor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { +func (s *Visitor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -88,7 +88,7 @@ func (s *signerVisitor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) CreateChainTx(tx *txs.CreateChainTx) error { +func (s *Visitor) CreateChainTx(tx *txs.CreateChainTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -101,7 +101,7 @@ func (s *signerVisitor) CreateChainTx(tx *txs.CreateChainTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { +func (s *Visitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -109,7 +109,7 @@ func (s *signerVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) ImportTx(tx *txs.ImportTx) error { +func (s *Visitor) ImportTx(tx *txs.ImportTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -122,7 +122,7 @@ func (s *signerVisitor) ImportTx(tx *txs.ImportTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) ExportTx(tx *txs.ExportTx) error { +func (s *Visitor) ExportTx(tx *txs.ExportTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -130,7 +130,7 @@ func (s *signerVisitor) ExportTx(tx *txs.ExportTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { +func (s *Visitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -143,7 +143,7 @@ func (s *signerVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) return sign(s.tx, true, txSigners) } -func (s *signerVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { +func (s *Visitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -156,7 +156,7 @@ func (s *signerVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershi return sign(s.tx, true, txSigners) } -func (s *signerVisitor) TransformSubnetTx(tx *txs.TransformSubnetTx) error { +func (s *Visitor) TransformSubnetTx(tx *txs.TransformSubnetTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -169,7 +169,7 @@ func (s *signerVisitor) TransformSubnetTx(tx *txs.TransformSubnetTx) error { return sign(s.tx, true, txSigners) } -func (s *signerVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { +func (s *Visitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -177,7 +177,7 @@ func (s *signerVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessVa return sign(s.tx, true, txSigners) } -func (s *signerVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { +func (s *Visitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -185,7 +185,7 @@ func (s *signerVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDe return sign(s.tx, true, txSigners) } -func (s *signerVisitor) getSigners(sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { +func (s *Visitor) getSigners(sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { txSigners := make([][]keychain.Signer, len(ins)) for credIndex, transferInput := range ins { inIntf := transferInput.In @@ -219,7 +219,7 @@ func (s *signerVisitor) getSigners(sourceChainID ids.ID, ins []*avax.Transferabl out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, errUnknownOutputType + return nil, ErrUnknownOutputType } for sigIndex, addrIndex := range input.SigIndices { @@ -240,7 +240,7 @@ func (s *signerVisitor) getSigners(sourceChainID ids.ID, ins []*avax.Transferabl return txSigners, nil } -func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Verifiable) ([]keychain.Signer, error) { +func (s *Visitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Verifiable) ([]keychain.Signer, error) { subnetInput, ok := subnetAuth.(*secp256k1fx.Input) if !ok { return nil, errUnknownSubnetAuthType @@ -256,7 +256,7 @@ func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Veri } owner, ok := ownerIntf.(*secp256k1fx.OutputOwners) if !ok { - return nil, errUnknownOwnerType + return nil, ErrUnknownOwnerType } authSigners := make([]keychain.Signer, len(subnetInput.SigIndices)) diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index 5b8001808ceb..ac42880451bf 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -13,6 +13,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" stdcontext "context" @@ -24,7 +25,7 @@ var _ Backend = (*backend)(nil) type Backend interface { common.ChainUTXOs BuilderBackend - SignerBackend + signer.Backend AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error } diff --git a/wallet/chain/p/backend_visitor.go b/wallet/chain/p/backend_visitor.go index d8b118fa21b7..7de12ce42fcb 100644 --- a/wallet/chain/p/backend_visitor.go +++ b/wallet/chain/p/backend_visitor.go @@ -8,6 +8,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" stdcontext "context" ) @@ -22,11 +23,11 @@ type backendVisitor struct { } func (*backendVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - return errUnsupportedTxType + return signer.ErrUnsupportedTxType } func (*backendVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { - return errUnsupportedTxType + return signer.ErrUnsupportedTxType } func (b *backendVisitor) AddValidatorTx(tx *txs.AddValidatorTx) error { diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 85f9b6111010..7b51c3e7acc9 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -15,13 +15,14 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" "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/platformvm/txs/signer" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" stdcontext "context" + blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) var ( @@ -232,7 +233,7 @@ type Builder interface { // the delegation reward will be sent to the validator's [rewardsOwner]. NewAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer signer.Signer, + signer blssigner.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, @@ -787,7 +788,7 @@ func (b *builder) NewTransformSubnetTx( func (b *builder) NewAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer signer.Signer, + signer blssigner.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, @@ -900,7 +901,7 @@ func (b *builder) getBalance( out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, errUnknownOutputType + return nil, signer.ErrUnknownOutputType } _, ok = common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) @@ -982,7 +983,7 @@ func (b *builder) spend( out, ok := lockedOut.TransferableOut.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, errUnknownOutputType + return nil, nil, nil, signer.ErrUnknownOutputType } inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) @@ -1063,7 +1064,7 @@ func (b *builder) spend( out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, errUnknownOutputType + return nil, nil, nil, signer.ErrUnknownOutputType } inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 44cc7e2a4da4..6eab4bb2eab1 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -11,11 +11,13 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" - "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/signer" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) var ( @@ -31,7 +33,7 @@ type Wallet interface { Builder() Builder // Signer returns the signer that will be used to sign the transactions. - Signer() Signer + Signer() signer.Signer // IssueBaseTx creates, signs, and issues a new simple value transfer. // Because the P-chain doesn't intend for balance transfers to occur, this @@ -221,7 +223,7 @@ type Wallet interface { // the delegation reward will be sent to the validator's [rewardsOwner]. IssueAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer signer.Signer, + signer blssigner.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, @@ -259,7 +261,7 @@ type Wallet interface { func NewWallet( builder Builder, - signer Signer, + signer signer.Signer, client platformvm.Client, backend Backend, ) Wallet { @@ -274,7 +276,7 @@ func NewWallet( type wallet struct { Backend builder Builder - signer Signer + signer signer.Signer client platformvm.Client } @@ -282,7 +284,7 @@ func (w *wallet) Builder() Builder { return w.builder } -func (w *wallet) Signer() Signer { +func (w *wallet) Signer() signer.Signer { return w.signer } @@ -449,7 +451,7 @@ func (w *wallet) IssueTransformSubnetTx( func (w *wallet) IssueAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer signer.Signer, + signer blssigner.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, @@ -495,7 +497,7 @@ func (w *wallet) IssueUnsignedTx( ) (*txs.Tx, error) { ops := common.NewOptions(options) ctx := ops.Context() - tx, err := SignUnsigned(ctx, w.signer, utx) + tx, err := signer.SignUnsigned(ctx, w.signer, utx) if err != nil { return nil, err } diff --git a/wallet/chain/p/wallet_with_options.go b/wallet/chain/p/wallet_with_options.go index 4982e77f8a51..41be6109dc3a 100644 --- a/wallet/chain/p/wallet_with_options.go +++ b/wallet/chain/p/wallet_with_options.go @@ -8,10 +8,11 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) var _ Wallet = (*walletWithOptions)(nil) @@ -198,7 +199,7 @@ func (w *walletWithOptions) IssueTransformSubnetTx( func (w *walletWithOptions) IssueAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer signer.Signer, + signer blssigner.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 2b8d8b8eeec8..3f1bd27be10b 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -15,9 +15,10 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + + blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) func ExampleWallet() { @@ -151,7 +152,7 @@ func ExampleWallet() { }, Subnet: createSubnetTxID, }, - &signer.Empty{}, + &blssigner.Empty{}, createAssetTx.ID(), &secp256k1fx.OutputOwners{}, &secp256k1fx.OutputOwners{}, diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 9aabf651cff7..a84421cf84b1 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -15,6 +15,8 @@ import ( "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + psigner "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" ) var _ Wallet = (*wallet)(nil) @@ -119,7 +121,7 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, avaxState.UTXOs) pBackend := p.NewBackend(avaxState.PCTX, pUTXOs, pChainTxs) pBuilder := p.NewBuilder(avaxAddrs, pBackend) - pSigner := p.NewSigner(config.AVAXKeychain, pBackend) + pSigner := psigner.New(config.AVAXKeychain, pBackend) xChainID := avaxState.XCTX.BlockchainID() xUTXOs := common.NewChainUTXOs(xChainID, avaxState.UTXOs) From 89da2ba169aed6eec20062d904375b2522d4b886 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 20 Feb 2024 10:04:10 +0100 Subject: [PATCH 031/120] introduced wallet signer visitor in pchain txs builder subpackage --- vms/platformvm/txs/builder/builder.go | 142 +++++++++++++----- vms/platformvm/txs/builder/signer_backend.go | 58 +++++++ .../txs/executor/create_chain_test.go | 17 ++- .../txs/executor/create_subnet_test.go | 13 +- 4 files changed, 180 insertions(+), 50 deletions(-) create mode 100644 vms/platformvm/txs/builder/signer_backend.go diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 03be8303c4f8..63e5fcb03e9f 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -4,6 +4,7 @@ package builder import ( + "context" "errors" "fmt" "time" @@ -18,11 +19,13 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" - "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/signer" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + + blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) // Max number of items allowed in a page @@ -167,7 +170,7 @@ type ProposalTxBuilder interface { startTime, endTime uint64, nodeID ids.NodeID, - pop *signer.ProofOfPossession, + pop *blssigner.ProofOfPossession, rewardAddress ids.ShortID, shares uint32, keys []*secp256k1.PrivateKey, @@ -339,16 +342,14 @@ func (b *builder) NewImportTx( outs := []*avax.TransferableOutput{} switch { case importedAVAX < b.cfg.TxFee: // imported amount goes toward paying tx fee - var baseSigners [][]*secp256k1.PrivateKey toBurn := map[ids.ID]uint64{ b.ctx.AVAXAssetID: b.cfg.TxFee - importedAVAX, } toStake := make(map[ids.ID]uint64) - ins, outs, _, baseSigners, err = b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, _, err = b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } - signers = append(baseSigners, signers...) delete(importedAmounts, b.ctx.AVAXAssetID) case importedAVAX == b.cfg.TxFee: delete(importedAmounts, b.ctx.AVAXAssetID) @@ -384,7 +385,12 @@ func (b *builder) NewImportTx( SourceChain: from, ImportedInputs: importedInputs, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, from, atomicUTXOs), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -408,7 +414,7 @@ func (b *builder) NewExportTx( b.ctx.AVAXAssetID: amtToBurn, } toStake := make(map[ids.ID]uint64) - ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -435,7 +441,12 @@ func (b *builder) NewExportTx( }, }}, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -458,16 +469,15 @@ func (b *builder) NewCreateChainTx( b.ctx.AVAXAssetID: createBlockchainTxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } - subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) + subnetAuth, _, err := b.Authorize(b.state, subnetID, keys) if err != nil { return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) } - signers = append(signers, subnetSigners) // Sort the provided fxIDs utils.Sort(fxIDs) @@ -488,7 +498,12 @@ func (b *builder) NewCreateChainTx( GenesisData: genesisData, SubnetAuth: subnetAuth, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -508,7 +523,7 @@ func (b *builder) NewCreateSubnetTx( b.ctx.AVAXAssetID: createSubnetTxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -530,7 +545,12 @@ func (b *builder) NewCreateSubnetTx( Addrs: ownerAddrs, }, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -560,16 +580,15 @@ func (b *builder) NewTransformSubnetTx( b.ctx.AVAXAssetID: b.cfg.TransformSubnetTxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } - subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) + subnetAuth, _, err := b.Authorize(b.state, subnetID, keys) if err != nil { return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) } - signers = append(signers, subnetSigners) utx := &txs.TransformSubnetTx{ BaseTx: txs.BaseTx{ @@ -598,7 +617,11 @@ func (b *builder) NewTransformSubnetTx( SubnetAuth: subnetAuth, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -622,7 +645,7 @@ func (b *builder) NewAddValidatorTx( toStake := map[ids.ID]uint64{ b.ctx.AVAXAssetID: stakeAmount, } - ins, unstakedOuts, stakedOuts, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, unstakedOuts, stakedOuts, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -649,7 +672,12 @@ func (b *builder) NewAddValidatorTx( }, DelegationShares: shares, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -661,7 +689,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( startTime, endTime uint64, nodeID ids.NodeID, - pop *signer.ProofOfPossession, + pop *blssigner.ProofOfPossession, rewardAddress ids.ShortID, shares uint32, keys []*secp256k1.PrivateKey, @@ -674,7 +702,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( toStake := map[ids.ID]uint64{ b.ctx.AVAXAssetID: stakeAmount, } - ins, unstakedOuts, stakedOuts, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, unstakedOuts, stakedOuts, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -708,7 +736,12 @@ func (b *builder) NewAddPermissionlessValidatorTx( }, DelegationShares: shares, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -731,7 +764,7 @@ func (b *builder) NewAddDelegatorTx( toStake := map[ids.ID]uint64{ b.ctx.AVAXAssetID: stakeAmount, } - ins, unlockedOuts, lockedOuts, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, unlockedOuts, lockedOuts, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -757,7 +790,12 @@ func (b *builder) NewAddDelegatorTx( Addrs: []ids.ShortID{rewardAddress}, }, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -780,7 +818,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( toStake := map[ids.ID]uint64{ b.ctx.AVAXAssetID: stakeAmount, } - ins, unlockedOuts, lockedOuts, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, unlockedOuts, lockedOuts, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -807,7 +845,12 @@ func (b *builder) NewAddPermissionlessDelegatorTx( Addrs: []ids.ShortID{rewardAddress}, }, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -828,16 +871,15 @@ func (b *builder) NewAddSubnetValidatorTx( b.ctx.AVAXAssetID: b.cfg.TxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } - subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) + subnetAuth, _, err := b.Authorize(b.state, subnetID, keys) if err != nil { return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) } - signers = append(signers, subnetSigners) // Create the tx utx := &txs.AddSubnetValidatorTx{ @@ -859,7 +901,12 @@ func (b *builder) NewAddSubnetValidatorTx( }, SubnetAuth: subnetAuth, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -877,16 +924,15 @@ func (b *builder) NewRemoveSubnetValidatorTx( b.ctx.AVAXAssetID: b.cfg.TxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } - subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) + subnetAuth, _, err := b.Authorize(b.state, subnetID, keys) if err != nil { return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) } - signers = append(signers, subnetSigners) // Create the tx utx := &txs.RemoveSubnetValidatorTx{ @@ -901,7 +947,12 @@ func (b *builder) NewRemoveSubnetValidatorTx( NodeID: nodeID, SubnetAuth: subnetAuth, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -920,16 +971,15 @@ func (b *builder) NewTransferSubnetOwnershipTx( b.ctx.AVAXAssetID: b.cfg.TxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } - subnetAuth, subnetSigners, err := b.Authorize(b.state, subnetID, keys) + subnetAuth, _, err := b.Authorize(b.state, subnetID, keys) if err != nil { return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) } - signers = append(signers, subnetSigners) utx := &txs.TransferSubnetOwnershipTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ @@ -946,7 +996,12 @@ func (b *builder) NewTransferSubnetOwnershipTx( Addrs: ownerAddrs, }, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -968,7 +1023,7 @@ func (b *builder) NewBaseTx( b.ctx.AVAXAssetID: amtToBurn, } toStake := make(map[ids.ID]uint64) - ins, outs, _, signers, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -992,7 +1047,12 @@ func (b *builder) NewBaseTx( Memo: memo, }, } - tx, err := txs.NewSigned(utx, txs.Codec, signers) + + s := signer.New( + secp256k1fx.NewKeychain(keys...), + NewSignerBackend(b.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } diff --git a/vms/platformvm/txs/builder/signer_backend.go b/vms/platformvm/txs/builder/signer_backend.go new file mode 100644 index 000000000000..680bb47a6ea6 --- /dev/null +++ b/vms/platformvm/txs/builder/signer_backend.go @@ -0,0 +1,58 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package builder + +import ( + "context" + "fmt" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" + "github.com/ava-labs/avalanchego/vms/platformvm/state" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" +) + +var _ signer.Backend = (*signerBackend)(nil) + +func NewSignerBackend(state state.State, sourceChain ids.ID, atomicUTXOs []*avax.UTXO) signer.Backend { + importedUTXO := make(map[ids.ID]*avax.UTXO, len(atomicUTXOs)) + for _, utxo := range atomicUTXOs { + importedUTXO[utxo.InputID()] = utxo + } + + return &signerBackend{ + state: state, + importedChainID: sourceChain, + importedUTXOs: importedUTXO, + } +} + +type signerBackend struct { + state state.State + + importedChainID ids.ID + importedUTXOs map[ids.ID]*avax.UTXO // utxoID --> utxo +} + +func (s *signerBackend) GetUTXO(_ context.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) { + switch chainID { + case constants.PlatformChainID: + return s.state.GetUTXO(utxoID) + case s.importedChainID: + utxo, found := s.importedUTXOs[utxoID] + if !found { + return nil, database.ErrNotFound + } + return utxo, nil + default: + return nil, fmt.Errorf("unexpected chain ID %s", chainID) + } +} + +func (s *signerBackend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { + return s.state.GetSubnetOwner(subnetID) +} diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index fa394cee4d58..971aa54edd05 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -4,6 +4,7 @@ package executor import ( + "context" "testing" "time" @@ -18,6 +19,8 @@ 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/builder" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -198,14 +201,12 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { env.ctx.AVAXAssetID: test.fee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, signers, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) + ins, outs, _, _, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) require.NoError(err) - subnetAuth, subnetSigners, err := env.utxosHandler.Authorize(env.state, testSubnet1.ID(), preFundedKeys) + subnetAuth, _, err := env.utxosHandler.Authorize(env.state, testSubnet1.ID(), preFundedKeys) require.NoError(err) - signers = append(signers, subnetSigners) - // Create the tx utx := &txs.CreateChainTx{ @@ -219,8 +220,12 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { VMID: constants.AVMID, SubnetAuth: subnetAuth, } - tx := &txs.Tx{Unsigned: utx} - require.NoError(tx.Sign(txs.Codec, signers)) + s := signer.New( + secp256k1fx.NewKeychain(preFundedKeys...), + builder.NewSignerBackend(env.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) + require.NoError(err) stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index caec47b386c5..a99f32f36dbb 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -4,6 +4,7 @@ package executor import ( + "context" "testing" "time" @@ -14,6 +15,8 @@ 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/builder" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -58,7 +61,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { env.ctx.AVAXAssetID: test.fee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, signers, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) + ins, outs, _, _, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) require.NoError(err) // Create the tx @@ -71,8 +74,12 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { }}, Owner: &secp256k1fx.OutputOwners{}, } - tx := &txs.Tx{Unsigned: utx} - require.NoError(tx.Sign(txs.Codec, signers)) + s := signer.New( + secp256k1fx.NewKeychain(preFundedKeys...), + builder.NewSignerBackend(env.state, ids.Empty, nil), + ) + tx, err := signer.SignUnsigned(context.Background(), s, utx) + require.NoError(err) stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) From e26bec90a7e6e4ab1c64670e1c0423220161a197 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 20 Feb 2024 11:16:44 +0100 Subject: [PATCH 032/120] drop signers from utxos.Spend handler --- vms/platformvm/txs/builder/builder.go | 26 +++---- .../txs/executor/create_chain_test.go | 2 +- .../txs/executor/create_subnet_test.go | 2 +- vms/platformvm/utxo/handler.go | 78 ++++++++----------- 4 files changed, 46 insertions(+), 62 deletions(-) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 63e5fcb03e9f..215aba10dab4 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -346,7 +346,7 @@ func (b *builder) NewImportTx( b.ctx.AVAXAssetID: b.cfg.TxFee - importedAVAX, } toStake := make(map[ids.ID]uint64) - ins, outs, _, _, err = b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, err = b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -414,7 +414,7 @@ func (b *builder) NewExportTx( b.ctx.AVAXAssetID: amtToBurn, } toStake := make(map[ids.ID]uint64) - ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -469,7 +469,7 @@ func (b *builder) NewCreateChainTx( b.ctx.AVAXAssetID: createBlockchainTxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -523,7 +523,7 @@ func (b *builder) NewCreateSubnetTx( b.ctx.AVAXAssetID: createSubnetTxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -580,7 +580,7 @@ func (b *builder) NewTransformSubnetTx( b.ctx.AVAXAssetID: b.cfg.TransformSubnetTxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -645,7 +645,7 @@ func (b *builder) NewAddValidatorTx( toStake := map[ids.ID]uint64{ b.ctx.AVAXAssetID: stakeAmount, } - ins, unstakedOuts, stakedOuts, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, unstakedOuts, stakedOuts, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -702,7 +702,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( toStake := map[ids.ID]uint64{ b.ctx.AVAXAssetID: stakeAmount, } - ins, unstakedOuts, stakedOuts, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, unstakedOuts, stakedOuts, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -764,7 +764,7 @@ func (b *builder) NewAddDelegatorTx( toStake := map[ids.ID]uint64{ b.ctx.AVAXAssetID: stakeAmount, } - ins, unlockedOuts, lockedOuts, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, unlockedOuts, lockedOuts, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -818,7 +818,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( toStake := map[ids.ID]uint64{ b.ctx.AVAXAssetID: stakeAmount, } - ins, unlockedOuts, lockedOuts, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, unlockedOuts, lockedOuts, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -871,7 +871,7 @@ func (b *builder) NewAddSubnetValidatorTx( b.ctx.AVAXAssetID: b.cfg.TxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -924,7 +924,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( b.ctx.AVAXAssetID: b.cfg.TxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -971,7 +971,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( b.ctx.AVAXAssetID: b.cfg.TxFee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } @@ -1023,7 +1023,7 @@ func (b *builder) NewBaseTx( b.ctx.AVAXAssetID: amtToBurn, } toStake := make(map[ids.ID]uint64) - ins, outs, _, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) + ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) if err != nil { return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) } diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 971aa54edd05..cc4952505109 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -201,7 +201,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { env.ctx.AVAXAssetID: test.fee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, _, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) + ins, outs, _, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) require.NoError(err) subnetAuth, _, err := env.utxosHandler.Authorize(env.state, testSubnet1.ID(), preFundedKeys) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index a99f32f36dbb..21a45d4bc300 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -61,7 +61,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { env.ctx.AVAXAssetID: test.fee, } toStake := make(map[ids.ID]uint64) - ins, outs, _, _, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) + ins, outs, _, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) require.NoError(err) // Create the tx diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index 39e688eb6bad..562a2ca94e59 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -7,10 +7,9 @@ import ( "errors" "fmt" - "go.uber.org/zap" - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/utils/math" @@ -22,7 +21,9 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) var ( @@ -37,7 +38,6 @@ var ( errLocktimeMismatch = errors.New("input locktime does not match UTXO locktime") errCantSign = errors.New("can't sign") errLockedFundsNotMarkedAsLocked = errors.New("locked funds not marked as locked") - errUnknownOutputType = errors.New("unknown output type") ) // TODO: Stake and Authorize should be replaced by similar methods in the @@ -66,7 +66,6 @@ type Spender interface { []*avax.TransferableInput, // inputs []*avax.TransferableOutput, // returnedOutputs []*avax.TransferableOutput, // stakedOutputs - [][]*secp256k1.PrivateKey, // signers error, ) @@ -157,7 +156,6 @@ func (h *handler) Spend( inputs []*avax.TransferableInput, changeOutputs []*avax.TransferableOutput, stakeOutputs []*avax.TransferableOutput, - signers [][]*secp256k1.PrivateKey, err error, ) { addrs := set.NewSet[ids.ShortID](len(keys)) // The addresses controlled by [keys] @@ -166,11 +164,9 @@ func (h *handler) Spend( } utxos, err := avax.GetAllUTXOs(utxoReader, addrs) // The UTXOs controlled by [keys] if err != nil { - return nil, nil, nil, nil, fmt.Errorf("couldn't get UTXOs: %w", err) + return nil, nil, nil, fmt.Errorf("couldn't get UTXOs: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) // Keychain consumes UTXOs and creates new ones - // Minimum time this transaction will be issued at minIssuanceTime := uint64(h.clk.Time().Unix()) @@ -205,20 +201,12 @@ func (h *handler) Spend( out, ok := lockedOut.TransferableOut.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, nil, errUnknownOutputType + return nil, nil, nil, signer.ErrUnknownOutputType } - inIntf, inSigners, err := kc.Spend(out, minIssuanceTime) - if err != nil { - // We couldn't spend the output, so move on to the next one - continue - } - in, ok := inIntf.(avax.TransferableIn) - if !ok { // should never happen - h.ctx.Log.Warn("wrong input type", - zap.String("expectedType", "avax.TransferableIn"), - zap.String("actualType", fmt.Sprintf("%T", inIntf)), - ) + inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) + if !ok { + // We couldn't spend this UTXO, so we skip to the next one continue } @@ -226,14 +214,16 @@ func (h *handler) Spend( UTXOID: utxo.UTXOID, Asset: utxo.Asset, In: &stakeable.LockIn{ - Locktime: lockedOut.Locktime, - TransferableIn: in, + Locktime: lockedOut.Locktime, + TransferableIn: &secp256k1fx.TransferInput{ + Amt: out.Amt, + Input: secp256k1fx.Input{ + SigIndices: inputSigIndices, + }, + }, }, }) - // Add the signers needed for this input to the set of signers - signers = append(signers, inSigners) - // Stake any value that should be staked amountToStake := min( remainingAmountToStake, // Amount we still need to stake @@ -292,32 +282,26 @@ func (h *handler) Spend( out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, nil, errUnknownOutputType + return nil, nil, nil, signer.ErrUnknownOutputType } - inIntf, inSigners, err := kc.Spend(out, minIssuanceTime) - if err != nil { - // We couldn't spend the output, so move on to the next one - continue - } - in, ok := inIntf.(avax.TransferableIn) - if !ok { // should never happen - h.ctx.Log.Warn("wrong input type", - zap.String("expectedType", "avax.TransferableIn"), - zap.String("actualType", fmt.Sprintf("%T", inIntf)), - ) + inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) + if !ok { + // We couldn't spend this UTXO, so we skip to the next one continue } inputs = append(inputs, &avax.TransferableInput{ UTXOID: utxo.UTXOID, Asset: utxo.Asset, - In: in, + In: &secp256k1fx.TransferInput{ + Amt: out.Amt, + Input: secp256k1fx.Input{ + SigIndices: inputSigIndices, + }, + }, }) - // Add the signers needed for this input to the set of signers - signers = append(signers, inSigners) - // Burn any value that should be burned amountToBurn := min( remainingAmountToBurn, // Amount we still need to burn @@ -356,7 +340,7 @@ func (h *handler) Spend( for assetID, amount := range amountsToStake { if amount != 0 { - return nil, nil, nil, nil, fmt.Errorf( + return nil, nil, nil, fmt.Errorf( "%w: provided UTXOs need %d more units of asset %q to stake", ErrInsufficientFunds, amount, @@ -366,7 +350,7 @@ func (h *handler) Spend( } for assetID, amount := range amountsToBurn { if amount != 0 { - return nil, nil, nil, nil, fmt.Errorf( + return nil, nil, nil, fmt.Errorf( "%w: provided UTXOs need %d more units of asset %q", ErrInsufficientFunds, amount, @@ -375,10 +359,10 @@ func (h *handler) Spend( } } - avax.SortTransferableInputsWithSigners(inputs, signers) // sort inputs and keys - avax.SortTransferableOutputs(changeOutputs, txs.Codec) // sort the change outputs - avax.SortTransferableOutputs(stakeOutputs, txs.Codec) // sort stake outputs - return inputs, changeOutputs, stakeOutputs, signers, nil + utils.Sort(inputs) // sort inputs + avax.SortTransferableOutputs(changeOutputs, txs.Codec) // sort the change outputs + avax.SortTransferableOutputs(stakeOutputs, txs.Codec) // sort stake outputs + return inputs, changeOutputs, stakeOutputs, nil } func (h *handler) Authorize( From dd17dbb982ae05d3b45c9ae3e48ffad7f5634522 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 20 Feb 2024 12:32:03 +0100 Subject: [PATCH 033/120] moved wallet builder backend to pchain --- vms/platformvm/txs/backends/backends.go | 35 ++++++ vms/platformvm/txs/backends/context.go | 100 +++++++++++++++++ .../txs/{signer => backends}/signer.go | 16 +-- .../visitor.go => backends/signer_visitor.go} | 4 +- vms/platformvm/txs/builder/builder.go | 61 +++++------ vms/platformvm/txs/builder/builder_backend.go | 56 ++++++++++ vms/platformvm/txs/builder/signer_backend.go | 6 +- .../txs/executor/create_chain_test.go | 6 +- .../txs/executor/create_subnet_test.go | 6 +- vms/platformvm/txs/signer/backend.go | 17 --- vms/platformvm/utxo/handler.go | 6 +- wallet/chain/p/backend.go | 10 +- wallet/chain/p/backend_visitor.go | 6 +- wallet/chain/p/builder.go | 31 ++---- wallet/chain/p/builder_test.go | 3 +- wallet/chain/p/context.go | 103 +----------------- wallet/chain/p/wallet.go | 21 ++-- wallet/chain/p/wallet_with_options.go | 5 +- wallet/subnet/primary/api.go | 3 +- wallet/subnet/primary/example_test.go | 5 +- wallet/subnet/primary/wallet.go | 2 +- 21 files changed, 284 insertions(+), 218 deletions(-) create mode 100644 vms/platformvm/txs/backends/backends.go create mode 100644 vms/platformvm/txs/backends/context.go rename vms/platformvm/txs/{signer => backends}/signer.go (78%) rename vms/platformvm/txs/{signer/visitor.go => backends/signer_visitor.go} (99%) create mode 100644 vms/platformvm/txs/builder/builder_backend.go delete mode 100644 vms/platformvm/txs/signer/backend.go diff --git a/vms/platformvm/txs/backends/backends.go b/vms/platformvm/txs/backends/backends.go new file mode 100644 index 000000000000..cce25523dfc1 --- /dev/null +++ b/vms/platformvm/txs/backends/backends.go @@ -0,0 +1,35 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package backends + +import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" + + stdcontext "context" +) + +var ( + _ BuilderBackend = WalletBackend(nil) + _ SignerBackend = WalletBackend(nil) +) + +type WalletBackend interface { + Context + UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) + GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) + GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +} + +type SignerBackend interface { + GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) + GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) +} + +type BuilderBackend interface { + Context + UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) + GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) +} diff --git a/vms/platformvm/txs/backends/context.go b/vms/platformvm/txs/backends/context.go new file mode 100644 index 000000000000..0406db65f719 --- /dev/null +++ b/vms/platformvm/txs/backends/context.go @@ -0,0 +1,100 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package backends + +import "github.com/ava-labs/avalanchego/ids" + +var _ Context = (*builderCtx)(nil) + +type Context interface { + NetworkID() uint32 + AVAXAssetID() ids.ID + BaseTxFee() uint64 + CreateSubnetTxFee() uint64 + TransformSubnetTxFee() uint64 + CreateBlockchainTxFee() uint64 + AddPrimaryNetworkValidatorFee() uint64 + AddPrimaryNetworkDelegatorFee() uint64 + AddSubnetValidatorFee() uint64 + AddSubnetDelegatorFee() uint64 +} + +type builderCtx struct { + networkID uint32 + avaxAssetID ids.ID + baseTxFee uint64 + createSubnetTxFee uint64 + transformSubnetTxFee uint64 + createBlockchainTxFee uint64 + addPrimaryNetworkValidatorFee uint64 + addPrimaryNetworkDelegatorFee uint64 + addSubnetValidatorFee uint64 + addSubnetDelegatorFee uint64 +} + +func NewContext( + networkID uint32, + avaxAssetID ids.ID, + baseTxFee uint64, + createSubnetTxFee uint64, + transformSubnetTxFee uint64, + createBlockchainTxFee uint64, + addPrimaryNetworkValidatorFee uint64, + addPrimaryNetworkDelegatorFee uint64, + addSubnetValidatorFee uint64, + addSubnetDelegatorFee uint64, +) Context { + return &builderCtx{ + networkID: networkID, + avaxAssetID: avaxAssetID, + baseTxFee: baseTxFee, + createSubnetTxFee: createSubnetTxFee, + transformSubnetTxFee: transformSubnetTxFee, + createBlockchainTxFee: createBlockchainTxFee, + addPrimaryNetworkValidatorFee: addPrimaryNetworkValidatorFee, + addPrimaryNetworkDelegatorFee: addPrimaryNetworkDelegatorFee, + addSubnetValidatorFee: addSubnetValidatorFee, + addSubnetDelegatorFee: addSubnetDelegatorFee, + } +} + +func (c *builderCtx) NetworkID() uint32 { + return c.networkID +} + +func (c *builderCtx) AVAXAssetID() ids.ID { + return c.avaxAssetID +} + +func (c *builderCtx) BaseTxFee() uint64 { + return c.baseTxFee +} + +func (c *builderCtx) CreateSubnetTxFee() uint64 { + return c.createSubnetTxFee +} + +func (c *builderCtx) TransformSubnetTxFee() uint64 { + return c.transformSubnetTxFee +} + +func (c *builderCtx) CreateBlockchainTxFee() uint64 { + return c.createBlockchainTxFee +} + +func (c *builderCtx) AddPrimaryNetworkValidatorFee() uint64 { + return c.addPrimaryNetworkValidatorFee +} + +func (c *builderCtx) AddPrimaryNetworkDelegatorFee() uint64 { + return c.addPrimaryNetworkDelegatorFee +} + +func (c *builderCtx) AddSubnetValidatorFee() uint64 { + return c.addSubnetValidatorFee +} + +func (c *builderCtx) AddSubnetDelegatorFee() uint64 { + return c.addSubnetDelegatorFee +} diff --git a/vms/platformvm/txs/signer/signer.go b/vms/platformvm/txs/backends/signer.go similarity index 78% rename from vms/platformvm/txs/signer/signer.go rename to vms/platformvm/txs/backends/signer.go index 1902f99d2b75..976442c8ee7b 100644 --- a/vms/platformvm/txs/signer/signer.go +++ b/vms/platformvm/txs/backends/signer.go @@ -1,13 +1,13 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package signer +package backends import ( - "context" - "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + + stdcontext "context" ) var _ Signer = (*txSigner)(nil) @@ -21,22 +21,22 @@ type Signer interface { // // If the signer doesn't have the ability to provide a required signature, // the signature slot will be skipped without reporting an error. - Sign(ctx context.Context, tx *txs.Tx) error + Sign(ctx stdcontext.Context, tx *txs.Tx) error } type txSigner struct { kc keychain.Keychain - backend Backend + backend SignerBackend } -func New(kc keychain.Keychain, backend Backend) Signer { +func New(kc keychain.Keychain, backend SignerBackend) Signer { return &txSigner{ kc: kc, backend: backend, } } -func (s *txSigner) Sign(ctx context.Context, tx *txs.Tx) error { +func (s *txSigner) Sign(ctx stdcontext.Context, tx *txs.Tx) error { return tx.Unsigned.Visit(&Visitor{ kc: s.kc, backend: s.backend, @@ -46,7 +46,7 @@ func (s *txSigner) Sign(ctx context.Context, tx *txs.Tx) error { } func SignUnsigned( - ctx context.Context, + ctx stdcontext.Context, s Signer, utx txs.UnsignedTx, ) (*txs.Tx, error) { diff --git a/vms/platformvm/txs/signer/visitor.go b/vms/platformvm/txs/backends/signer_visitor.go similarity index 99% rename from vms/platformvm/txs/signer/visitor.go rename to vms/platformvm/txs/backends/signer_visitor.go index 3e41a6952d7d..5ae15131570c 100644 --- a/vms/platformvm/txs/signer/visitor.go +++ b/vms/platformvm/txs/backends/signer_visitor.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package signer +package backends import ( "context" @@ -38,7 +38,7 @@ var ( // Visitor handles signing transactions for the signer type Visitor struct { kc keychain.Keychain - backend Backend + backend SignerBackend ctx context.Context tx *txs.Tx } diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 215aba10dab4..49b241542b5c 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -19,13 +19,12 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" + "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/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - - blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) // Max number of items allowed in a page @@ -170,7 +169,7 @@ type ProposalTxBuilder interface { startTime, endTime uint64, nodeID ids.NodeID, - pop *blssigner.ProofOfPossession, + pop *signer.ProofOfPossession, rewardAddress ids.ShortID, shares uint32, keys []*secp256k1.PrivateKey, @@ -386,11 +385,11 @@ func (b *builder) NewImportTx( ImportedInputs: importedInputs, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, from, atomicUTXOs), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -442,11 +441,11 @@ func (b *builder) NewExportTx( }}, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -499,11 +498,11 @@ func (b *builder) NewCreateChainTx( SubnetAuth: subnetAuth, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -546,11 +545,11 @@ func (b *builder) NewCreateSubnetTx( }, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -617,11 +616,11 @@ func (b *builder) NewTransformSubnetTx( SubnetAuth: subnetAuth, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -673,11 +672,11 @@ func (b *builder) NewAddValidatorTx( DelegationShares: shares, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -689,7 +688,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( startTime, endTime uint64, nodeID ids.NodeID, - pop *blssigner.ProofOfPossession, + pop *signer.ProofOfPossession, rewardAddress ids.ShortID, shares uint32, keys []*secp256k1.PrivateKey, @@ -737,11 +736,11 @@ func (b *builder) NewAddPermissionlessValidatorTx( DelegationShares: shares, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -791,11 +790,11 @@ func (b *builder) NewAddDelegatorTx( }, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -846,11 +845,11 @@ func (b *builder) NewAddPermissionlessDelegatorTx( }, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -902,11 +901,11 @@ func (b *builder) NewAddSubnetValidatorTx( SubnetAuth: subnetAuth, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -948,11 +947,11 @@ func (b *builder) NewRemoveSubnetValidatorTx( SubnetAuth: subnetAuth, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -997,11 +996,11 @@ func (b *builder) NewTransferSubnetOwnershipTx( }, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } @@ -1048,11 +1047,11 @@ func (b *builder) NewBaseTx( }, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(keys...), NewSignerBackend(b.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err } diff --git a/vms/platformvm/txs/builder/builder_backend.go b/vms/platformvm/txs/builder/builder_backend.go new file mode 100644 index 000000000000..b7fd6abcf836 --- /dev/null +++ b/vms/platformvm/txs/builder/builder_backend.go @@ -0,0 +1,56 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package builder + +import ( + "context" + "errors" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/config" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" + "github.com/ava-labs/avalanchego/vms/platformvm/state" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" +) + +var _ backends.BuilderBackend = (*buiderBackend)(nil) + +func NewBuilderBackend( + ctx *snow.Context, + cfg *config.Config, + state state.State, +) backends.BuilderBackend { + backendCtx := backends.NewContext( + ctx.NetworkID, + ctx.AVAXAssetID, + cfg.TxFee, + cfg.CreateSubnetTxFee, + cfg.TransformSubnetTxFee, + cfg.CreateBlockchainTxFee, + cfg.AddPrimaryNetworkValidatorFee, + cfg.AddPrimaryNetworkDelegatorFee, + cfg.AddSubnetValidatorFee, + cfg.AddSubnetDelegatorFee, + ) + return &buiderBackend{ + Context: backendCtx, + state: state, + } +} + +type buiderBackend struct { + backends.Context + + state state.State +} + +func (*buiderBackend) UTXOs(_ context.Context /*sourceChainID*/, _ ids.ID) ([]*avax.UTXO, error) { + return nil, errors.New("not yet implemented") +} + +func (b *buiderBackend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { + return b.state.GetSubnetOwner(subnetID) +} diff --git a/vms/platformvm/txs/builder/signer_backend.go b/vms/platformvm/txs/builder/signer_backend.go index 680bb47a6ea6..058b13082641 100644 --- a/vms/platformvm/txs/builder/signer_backend.go +++ b/vms/platformvm/txs/builder/signer_backend.go @@ -13,12 +13,12 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/state" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" ) -var _ signer.Backend = (*signerBackend)(nil) +var _ backends.SignerBackend = (*signerBackend)(nil) -func NewSignerBackend(state state.State, sourceChain ids.ID, atomicUTXOs []*avax.UTXO) signer.Backend { +func NewSignerBackend(state state.State, sourceChain ids.ID, atomicUTXOs []*avax.UTXO) backends.SignerBackend { importedUTXO := make(map[ids.ID]*avax.UTXO, len(atomicUTXOs)) for _, utxo := range atomicUTXOs { importedUTXO[utxo.InputID()] = utxo diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index cc4952505109..b8b2c9deecb8 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -19,8 +19,8 @@ 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/backends" "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -220,11 +220,11 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { VMID: constants.AVMID, SubnetAuth: subnetAuth, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(preFundedKeys...), builder.NewSignerBackend(env.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) require.NoError(err) stateDiff, err := state.NewDiff(lastAcceptedID, env) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 21a45d4bc300..f9667cd94ceb 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -15,8 +15,8 @@ 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/backends" "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -74,11 +74,11 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { }}, Owner: &secp256k1fx.OutputOwners{}, } - s := signer.New( + s := backends.New( secp256k1fx.NewKeychain(preFundedKeys...), builder.NewSignerBackend(env.state, ids.Empty, nil), ) - tx, err := signer.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), s, utx) require.NoError(err) stateDiff, err := state.NewDiff(lastAcceptedID, env) diff --git a/vms/platformvm/txs/signer/backend.go b/vms/platformvm/txs/signer/backend.go deleted file mode 100644 index e864da0ec3d6..000000000000 --- a/vms/platformvm/txs/signer/backend.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package signer - -import ( - "context" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/fx" -) - -type Backend interface { - GetUTXO(ctx context.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) - GetSubnetOwner(ctx context.Context, subnetID ids.ID) (fx.Owner, error) -} diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index 562a2ca94e59..019c1ca3d3b3 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -21,7 +21,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -201,7 +201,7 @@ func (h *handler) Spend( out, ok := lockedOut.TransferableOut.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, signer.ErrUnknownOutputType + return nil, nil, nil, backends.ErrUnknownOutputType } inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) @@ -282,7 +282,7 @@ func (h *handler) Spend( out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, signer.ErrUnknownOutputType + return nil, nil, nil, backends.ErrUnknownOutputType } inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index ac42880451bf..08c8c83737fc 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -13,7 +13,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" stdcontext "context" @@ -23,22 +23,20 @@ var _ Backend = (*backend)(nil) // Backend defines the full interface required to support a P-chain wallet. type Backend interface { - common.ChainUTXOs - BuilderBackend - signer.Backend + backends.WalletBackend AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error } type backend struct { - Context + backends.Context common.ChainUTXOs subnetOwnerLock sync.RWMutex subnetOwner map[ids.ID]fx.Owner // subnetID -> owner } -func NewBackend(ctx Context, utxos common.ChainUTXOs, subnetTxs map[ids.ID]*txs.Tx) Backend { +func NewBackend(ctx backends.Context, utxos common.ChainUTXOs, subnetTxs map[ids.ID]*txs.Tx) Backend { subnetOwner := make(map[ids.ID]fx.Owner) for txID, tx := range subnetTxs { // first get owners from the CreateSubnetTx createSubnetTx, ok := tx.Unsigned.(*txs.CreateSubnetTx) diff --git a/wallet/chain/p/backend_visitor.go b/wallet/chain/p/backend_visitor.go index 7de12ce42fcb..d3668cac9f1d 100644 --- a/wallet/chain/p/backend_visitor.go +++ b/wallet/chain/p/backend_visitor.go @@ -8,7 +8,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" stdcontext "context" ) @@ -23,11 +23,11 @@ type backendVisitor struct { } func (*backendVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - return signer.ErrUnsupportedTxType + return backends.ErrUnsupportedTxType } func (*backendVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { - return signer.ErrUnsupportedTxType + return backends.ErrUnsupportedTxType } func (b *backendVisitor) AddValidatorTx(tx *txs.AddValidatorTx) error { diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 7b51c3e7acc9..f90bdfb4a801 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -14,15 +14,12 @@ import ( "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" - "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/platformvm/txs/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - - stdcontext "context" - blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) var ( @@ -222,7 +219,7 @@ type Builder interface { // - [vdr] specifies all the details of the validation period such as the // subnetID, startTime, endTime, stake weight, and nodeID. // - [signer] if the subnetID is the primary network, this is the BLS key - // for this validator. Otherwise, this value should be the empty signer. + // for this validator. Otherwise, this value should be the empty backends. // - [assetID] specifies the asset to stake. // - [validationRewardsOwner] specifies the owner of all the rewards this // validator earns for its validation period. @@ -233,7 +230,7 @@ type Builder interface { // the delegation reward will be sent to the validator's [rewardsOwner]. NewAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer blssigner.Signer, + signer signer.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, @@ -257,17 +254,9 @@ type Builder interface { ) (*txs.AddPermissionlessDelegatorTx, error) } -// BuilderBackend specifies the required information needed to build unsigned -// P-chain transactions. -type BuilderBackend interface { - Context - UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) - GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) -} - type builder struct { addrs set.Set[ids.ShortID] - backend BuilderBackend + backend backends.BuilderBackend } // NewBuilder returns a new transaction builder. @@ -276,7 +265,7 @@ type builder struct { // signing the transactions in the future. // - [backend] provides the required access to the chain's context and state // to build out the transactions. -func NewBuilder(addrs set.Set[ids.ShortID], backend BuilderBackend) Builder { +func NewBuilder(addrs set.Set[ids.ShortID], backend backends.BuilderBackend) Builder { return &builder{ addrs: addrs, backend: backend, @@ -788,7 +777,7 @@ func (b *builder) NewTransformSubnetTx( func (b *builder) NewAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer blssigner.Signer, + signer signer.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, @@ -901,7 +890,7 @@ func (b *builder) getBalance( out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, signer.ErrUnknownOutputType + return nil, backends.ErrUnknownOutputType } _, ok = common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) @@ -983,7 +972,7 @@ func (b *builder) spend( out, ok := lockedOut.TransferableOut.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, signer.ErrUnknownOutputType + return nil, nil, nil, backends.ErrUnknownOutputType } inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) @@ -1064,7 +1053,7 @@ func (b *builder) spend( out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, signer.ErrUnknownOutputType + return nil, nil, nil, backends.ErrUnknownOutputType } inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 473103147549..16da083ea6a7 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/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -32,7 +33,7 @@ var ( avaxAssetID = ids.Empty.Prefix(1789) subnetAssetID = ids.Empty.Prefix(2024) - testCtx = NewContext( + testCtx = backends.NewContext( constants.UnitTestID, avaxAssetID, units.MicroAvax, // BaseTxFee diff --git a/wallet/chain/p/context.go b/wallet/chain/p/context.go index 2511a19a9dbf..235cf74a57f5 100644 --- a/wallet/chain/p/context.go +++ b/wallet/chain/p/context.go @@ -10,41 +10,14 @@ 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/backends" stdcontext "context" ) const Alias = "P" -var _ Context = (*context)(nil) - -type Context interface { - NetworkID() uint32 - AVAXAssetID() ids.ID - BaseTxFee() uint64 - CreateSubnetTxFee() uint64 - TransformSubnetTxFee() uint64 - CreateBlockchainTxFee() uint64 - AddPrimaryNetworkValidatorFee() uint64 - AddPrimaryNetworkDelegatorFee() uint64 - AddSubnetValidatorFee() uint64 - AddSubnetDelegatorFee() uint64 -} - -type context struct { - networkID uint32 - avaxAssetID ids.ID - baseTxFee uint64 - createSubnetTxFee uint64 - transformSubnetTxFee uint64 - createBlockchainTxFee uint64 - addPrimaryNetworkValidatorFee uint64 - addPrimaryNetworkDelegatorFee uint64 - addSubnetValidatorFee uint64 - addSubnetDelegatorFee uint64 -} - -func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { +func NewContextFromURI(ctx stdcontext.Context, uri string) (backends.Context, error) { infoClient := info.NewClient(uri) xChainClient := avm.NewClient(uri, "X") return NewContextFromClients(ctx, infoClient, xChainClient) @@ -54,7 +27,7 @@ func NewContextFromClients( ctx stdcontext.Context, infoClient info.Client, xChainClient avm.Client, -) (Context, error) { +) (backends.Context, error) { networkID, err := infoClient.GetNetworkID(ctx) if err != nil { return nil, err @@ -70,7 +43,7 @@ func NewContextFromClients( return nil, err } - return NewContext( + return backends.NewContext( networkID, asset.AssetID, uint64(txFees.TxFee), @@ -84,73 +57,7 @@ func NewContextFromClients( ), nil } -func NewContext( - networkID uint32, - avaxAssetID ids.ID, - baseTxFee uint64, - createSubnetTxFee uint64, - transformSubnetTxFee uint64, - createBlockchainTxFee uint64, - addPrimaryNetworkValidatorFee uint64, - addPrimaryNetworkDelegatorFee uint64, - addSubnetValidatorFee uint64, - addSubnetDelegatorFee uint64, -) Context { - return &context{ - networkID: networkID, - avaxAssetID: avaxAssetID, - baseTxFee: baseTxFee, - createSubnetTxFee: createSubnetTxFee, - transformSubnetTxFee: transformSubnetTxFee, - createBlockchainTxFee: createBlockchainTxFee, - addPrimaryNetworkValidatorFee: addPrimaryNetworkValidatorFee, - addPrimaryNetworkDelegatorFee: addPrimaryNetworkDelegatorFee, - addSubnetValidatorFee: addSubnetValidatorFee, - addSubnetDelegatorFee: addSubnetDelegatorFee, - } -} - -func (c *context) NetworkID() uint32 { - return c.networkID -} - -func (c *context) AVAXAssetID() ids.ID { - return c.avaxAssetID -} - -func (c *context) BaseTxFee() uint64 { - return c.baseTxFee -} - -func (c *context) CreateSubnetTxFee() uint64 { - return c.createSubnetTxFee -} - -func (c *context) TransformSubnetTxFee() uint64 { - return c.transformSubnetTxFee -} - -func (c *context) CreateBlockchainTxFee() uint64 { - return c.createBlockchainTxFee -} - -func (c *context) AddPrimaryNetworkValidatorFee() uint64 { - return c.addPrimaryNetworkValidatorFee -} - -func (c *context) AddPrimaryNetworkDelegatorFee() uint64 { - return c.addPrimaryNetworkDelegatorFee -} - -func (c *context) AddSubnetValidatorFee() uint64 { - return c.addSubnetValidatorFee -} - -func (c *context) AddSubnetDelegatorFee() uint64 { - return c.addSubnetDelegatorFee -} - -func newSnowContext(c Context) (*snow.Context, error) { +func newSnowContext(c backends.Context) (*snow.Context, error) { lookup := ids.NewAliaser() return &snow.Context{ NetworkID: c.NetworkID(), diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 6eab4bb2eab1..d4b7667d6325 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -11,13 +11,12 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" + "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/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - - blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) var ( @@ -27,13 +26,13 @@ var ( ) type Wallet interface { - Context + backends.Context // Builder returns the builder that will be used to create the transactions. Builder() Builder // Signer returns the signer that will be used to sign the transactions. - Signer() signer.Signer + Signer() backends.Signer // IssueBaseTx creates, signs, and issues a new simple value transfer. // Because the P-chain doesn't intend for balance transfers to occur, this @@ -223,7 +222,7 @@ type Wallet interface { // the delegation reward will be sent to the validator's [rewardsOwner]. IssueAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer blssigner.Signer, + signer signer.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, @@ -261,7 +260,7 @@ type Wallet interface { func NewWallet( builder Builder, - signer signer.Signer, + signer backends.Signer, client platformvm.Client, backend Backend, ) Wallet { @@ -276,7 +275,7 @@ func NewWallet( type wallet struct { Backend builder Builder - signer signer.Signer + signer backends.Signer client platformvm.Client } @@ -284,7 +283,7 @@ func (w *wallet) Builder() Builder { return w.builder } -func (w *wallet) Signer() signer.Signer { +func (w *wallet) Signer() backends.Signer { return w.signer } @@ -451,7 +450,7 @@ func (w *wallet) IssueTransformSubnetTx( func (w *wallet) IssueAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer blssigner.Signer, + signer signer.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, @@ -497,7 +496,7 @@ func (w *wallet) IssueUnsignedTx( ) (*txs.Tx, error) { ops := common.NewOptions(options) ctx := ops.Context() - tx, err := signer.SignUnsigned(ctx, w.signer, utx) + tx, err := backends.SignUnsigned(ctx, w.signer, utx) if err != nil { return nil, err } diff --git a/wallet/chain/p/wallet_with_options.go b/wallet/chain/p/wallet_with_options.go index 41be6109dc3a..4982e77f8a51 100644 --- a/wallet/chain/p/wallet_with_options.go +++ b/wallet/chain/p/wallet_with_options.go @@ -8,11 +8,10 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - - blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) var _ Wallet = (*walletWithOptions)(nil) @@ -199,7 +198,7 @@ func (w *walletWithOptions) IssueTransformSubnetTx( func (w *walletWithOptions) IssueAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer blssigner.Signer, + signer signer.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 3c30b60d81c2..2b5ef8c155ce 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -20,6 +20,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" @@ -57,7 +58,7 @@ type UTXOClient interface { type AVAXState struct { PClient platformvm.Client - PCTX p.Context + PCTX backends.Context XClient avm.Client XCTX x.Context CClient evm.Client diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 3f1bd27be10b..2b8d8b8eeec8 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -15,10 +15,9 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - - blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) func ExampleWallet() { @@ -152,7 +151,7 @@ func ExampleWallet() { }, Subnet: createSubnetTxID, }, - &blssigner.Empty{}, + &signer.Empty{}, createAssetTx.ID(), &secp256k1fx.OutputOwners{}, &secp256k1fx.OutputOwners{}, diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index a84421cf84b1..6a0fc71ac715 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -16,7 +16,7 @@ import ( "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - psigner "github.com/ava-labs/avalanchego/vms/platformvm/txs/signer" + psigner "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" ) var _ Wallet = (*wallet)(nil) From 09047873fc3826e92e5eccf99b4afb0a6a98c617 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 20 Feb 2024 19:54:26 +0100 Subject: [PATCH 034/120] some more repackaging --- .../platformvm/txs/backends}/builder.go | 13 +++++------ vms/platformvm/txs/backends/context.go | 21 +++++++++++++++++- wallet/chain/p/builder_test.go | 22 +++++++++---------- wallet/chain/p/builder_with_options.go | 7 +++--- wallet/chain/p/context.go | 18 --------------- wallet/chain/p/wallet.go | 8 +++---- wallet/chain/p/wallet_with_options.go | 3 ++- .../examples/get-p-chain-balance/main.go | 4 +++- wallet/subnet/primary/wallet.go | 2 +- 9 files changed, 51 insertions(+), 47 deletions(-) rename {wallet/chain/p => vms/platformvm/txs/backends}/builder.go (99%) diff --git a/wallet/chain/p/builder.go b/vms/platformvm/txs/backends/builder.go similarity index 99% rename from wallet/chain/p/builder.go rename to vms/platformvm/txs/backends/builder.go index f90bdfb4a801..86cc3a782bb2 100644 --- a/wallet/chain/p/builder.go +++ b/vms/platformvm/txs/backends/builder.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package p +package backends import ( "errors" @@ -17,7 +17,6 @@ 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/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -256,7 +255,7 @@ type Builder interface { type builder struct { addrs set.Set[ids.ShortID] - backend backends.BuilderBackend + backend BuilderBackend } // NewBuilder returns a new transaction builder. @@ -265,7 +264,7 @@ type builder struct { // signing the transactions in the future. // - [backend] provides the required access to the chain's context and state // to build out the transactions. -func NewBuilder(addrs set.Set[ids.ShortID], backend backends.BuilderBackend) Builder { +func NewBuilder(addrs set.Set[ids.ShortID], backend BuilderBackend) Builder { return &builder{ addrs: addrs, backend: backend, @@ -890,7 +889,7 @@ func (b *builder) getBalance( out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, backends.ErrUnknownOutputType + return nil, ErrUnknownOutputType } _, ok = common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) @@ -972,7 +971,7 @@ func (b *builder) spend( out, ok := lockedOut.TransferableOut.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, backends.ErrUnknownOutputType + return nil, nil, nil, ErrUnknownOutputType } inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) @@ -1053,7 +1052,7 @@ func (b *builder) spend( out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, backends.ErrUnknownOutputType + return nil, nil, nil, ErrUnknownOutputType } inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) diff --git a/vms/platformvm/txs/backends/context.go b/vms/platformvm/txs/backends/context.go index 0406db65f719..6b7cf5ee78d8 100644 --- a/vms/platformvm/txs/backends/context.go +++ b/vms/platformvm/txs/backends/context.go @@ -3,7 +3,14 @@ package backends -import "github.com/ava-labs/avalanchego/ids" +import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" +) + +const Alias = "P" var _ Context = (*builderCtx)(nil) @@ -98,3 +105,15 @@ func (c *builderCtx) AddSubnetValidatorFee() uint64 { func (c *builderCtx) AddSubnetDelegatorFee() uint64 { return c.addSubnetDelegatorFee } + +func newSnowContext(c Context) (*snow.Context, error) { + lookup := ids.NewAliaser() + return &snow.Context{ + NetworkID: c.NetworkID(), + SubnetID: constants.PrimaryNetworkID, + ChainID: constants.PlatformChainID, + AVAXAssetID: c.AVAXAssetID(), + Log: logging.NoLog{}, + BCLookup: lookup, + }, lookup.Alias(constants.PlatformChainID, Alias) +} diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 16da083ea6a7..43b5a10f60a8 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -64,7 +64,7 @@ func TestBaseTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr), backend) // data to build the transaction outputsToMove = []*avax.TransferableOutput{{ @@ -124,7 +124,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) // data to build the transaction subnetValidator = &txs.SubnetValidator{ @@ -181,7 +181,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) ) // build the transaction @@ -231,7 +231,7 @@ func TestCreateChainTx(t *testing.T) { backend = NewBackend(testCtx, chainUTXOs, subnets) utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) // data to build the transaction genesisBytes = []byte{'a', 'b', 'c'} @@ -291,7 +291,7 @@ func TestCreateSubnetTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) ) // build the transaction @@ -339,7 +339,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) ) // build the transaction @@ -378,7 +378,7 @@ func TestImportTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr), backend) // data to build the transaction importKey = testKeys[0] @@ -424,7 +424,7 @@ func TestExportTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr), backend) // data to build the transaction subnetID = ids.GenerateTestID() @@ -489,7 +489,7 @@ func TestTransformSubnetTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) // data to build the transaction initialSupply = 40 * units.MegaAvax @@ -545,7 +545,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { utxoAddr = utxosKey.Address() rewardKey = testKeys[0] rewardAddr = rewardKey.Address() - builder = NewBuilder(set.Of(utxoAddr, rewardAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, rewardAddr), backend) // data to build the transaction validationRewardsOwner = &secp256k1fx.OutputOwners{ @@ -615,7 +615,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { utxoAddr = utxosKey.Address() rewardKey = testKeys[0] rewardAddr = rewardKey.Address() - builder = NewBuilder(set.Of(utxoAddr, rewardAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, rewardAddr), backend) // data to build the transaction rewardsOwner = &secp256k1fx.OutputOwners{ diff --git a/wallet/chain/p/builder_with_options.go b/wallet/chain/p/builder_with_options.go index a402355b9e01..b99f774a4262 100644 --- a/wallet/chain/p/builder_with_options.go +++ b/wallet/chain/p/builder_with_options.go @@ -10,14 +10,15 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) -var _ Builder = (*builderWithOptions)(nil) +var _ backends.Builder = (*builderWithOptions)(nil) type builderWithOptions struct { - Builder + backends.Builder options []common.Option } @@ -28,7 +29,7 @@ type builderWithOptions struct { // operations. // - [options] will be provided to the builder in addition to the options // provided in the method calls. -func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { +func NewBuilderWithOptions(builder backends.Builder, options ...common.Option) backends.Builder { return &builderWithOptions{ Builder: builder, options: options, diff --git a/wallet/chain/p/context.go b/wallet/chain/p/context.go index 235cf74a57f5..f93513d640ea 100644 --- a/wallet/chain/p/context.go +++ b/wallet/chain/p/context.go @@ -5,18 +5,12 @@ package p import ( "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" - "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/backends" stdcontext "context" ) -const Alias = "P" - func NewContextFromURI(ctx stdcontext.Context, uri string) (backends.Context, error) { infoClient := info.NewClient(uri) xChainClient := avm.NewClient(uri, "X") @@ -56,15 +50,3 @@ func NewContextFromClients( uint64(txFees.AddSubnetDelegatorFee), ), nil } - -func newSnowContext(c backends.Context) (*snow.Context, error) { - lookup := ids.NewAliaser() - return &snow.Context{ - NetworkID: c.NetworkID(), - SubnetID: constants.PrimaryNetworkID, - ChainID: constants.PlatformChainID, - AVAXAssetID: c.AVAXAssetID(), - Log: logging.NoLog{}, - BCLookup: lookup, - }, lookup.Alias(constants.PlatformChainID, Alias) -} diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index d4b7667d6325..842a03f23e34 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -29,7 +29,7 @@ type Wallet interface { backends.Context // Builder returns the builder that will be used to create the transactions. - Builder() Builder + Builder() backends.Builder // Signer returns the signer that will be used to sign the transactions. Signer() backends.Signer @@ -259,7 +259,7 @@ type Wallet interface { } func NewWallet( - builder Builder, + builder backends.Builder, signer backends.Signer, client platformvm.Client, backend Backend, @@ -274,12 +274,12 @@ func NewWallet( type wallet struct { Backend - builder Builder + builder backends.Builder signer backends.Signer client platformvm.Client } -func (w *wallet) Builder() Builder { +func (w *wallet) Builder() backends.Builder { return w.builder } diff --git a/wallet/chain/p/wallet_with_options.go b/wallet/chain/p/wallet_with_options.go index 4982e77f8a51..62e8fb8e0d05 100644 --- a/wallet/chain/p/wallet_with_options.go +++ b/wallet/chain/p/wallet_with_options.go @@ -10,6 +10,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -31,7 +32,7 @@ type walletWithOptions struct { options []common.Option } -func (w *walletWithOptions) Builder() Builder { +func (w *walletWithOptions) Builder() backends.Builder { return NewBuilderWithOptions( w.Wallet.Builder(), w.options..., diff --git a/wallet/subnet/primary/examples/get-p-chain-balance/main.go b/wallet/subnet/primary/examples/get-p-chain-balance/main.go index 08f2cd538c29..f0f4b07c4886 100644 --- a/wallet/subnet/primary/examples/get-p-chain-balance/main.go +++ b/wallet/subnet/primary/examples/get-p-chain-balance/main.go @@ -14,6 +14,8 @@ import ( "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/subnet/primary" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + psigner "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" ) func main() { @@ -38,7 +40,7 @@ func main() { pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, state.UTXOs) pBackend := p.NewBackend(state.PCTX, pUTXOs, nil) - pBuilder := p.NewBuilder(addresses, pBackend) + pBuilder := psigner.NewBuilder(addresses, pBackend) currentBalances, err := pBuilder.GetBalance() if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 6a0fc71ac715..95a0fe82be8b 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -120,7 +120,7 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, avaxState.UTXOs) pBackend := p.NewBackend(avaxState.PCTX, pUTXOs, pChainTxs) - pBuilder := p.NewBuilder(avaxAddrs, pBackend) + pBuilder := psigner.NewBuilder(avaxAddrs, pBackend) pSigner := psigner.New(config.AVAXKeychain, pBackend) xChainID := avaxState.XCTX.BlockchainID() From 20874431b3abd8161c02f2badbe473ba24b3c86a Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 20 Feb 2024 23:20:51 +0100 Subject: [PATCH 035/120] wip: chaining p-chain txbuilder with wallet builder and signer --- vms/platformvm/txs/backends/builder.go | 2 +- vms/platformvm/txs/backends/context.go | 6 +- vms/platformvm/txs/builder/builder.go | 144 ++++++++---------- vms/platformvm/txs/builder/builder_backend.go | 12 +- .../txs/executor/create_chain_test.go | 4 +- vms/platformvm/vm_test.go | 4 + 6 files changed, 78 insertions(+), 94 deletions(-) diff --git a/vms/platformvm/txs/backends/builder.go b/vms/platformvm/txs/backends/builder.go index 86cc3a782bb2..1f625dbc5bd0 100644 --- a/vms/platformvm/txs/backends/builder.go +++ b/vms/platformvm/txs/backends/builder.go @@ -1162,7 +1162,7 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se } func (b *builder) initCtx(tx txs.UnsignedTx) error { - ctx, err := newSnowContext(b.backend) + ctx, err := NewSnowContext(b.backend.NetworkID(), b.backend.AVAXAssetID()) if err != nil { return err } diff --git a/vms/platformvm/txs/backends/context.go b/vms/platformvm/txs/backends/context.go index 6b7cf5ee78d8..788d9fb4bcf5 100644 --- a/vms/platformvm/txs/backends/context.go +++ b/vms/platformvm/txs/backends/context.go @@ -106,13 +106,13 @@ func (c *builderCtx) AddSubnetDelegatorFee() uint64 { return c.addSubnetDelegatorFee } -func newSnowContext(c Context) (*snow.Context, error) { +func NewSnowContext(networkID uint32, avaxAssetID ids.ID) (*snow.Context, error) { lookup := ids.NewAliaser() return &snow.Context{ - NetworkID: c.NetworkID(), + NetworkID: networkID, SubnetID: constants.PrimaryNetworkID, ChainID: constants.PlatformChainID, - AVAXAssetID: c.AVAXAssetID(), + AVAXAssetID: avaxAssetID, Log: logging.NoLog{}, BCLookup: lookup, }, lookup.Alias(constants.PlatformChainID, Alias) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 49b241542b5c..352afe2de064 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -11,10 +11,10 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/config" @@ -25,6 +25,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) // Max number of items allowed in a page @@ -462,40 +463,23 @@ func (b *builder) NewCreateChainTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - timestamp := b.state.GetTimestamp() - createBlockchainTxFee := b.cfg.GetCreateBlockchainTxFee(timestamp) - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: createBlockchainTxFee, - } - toStake := make(map[ids.ID]uint64) - ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state) + pBuilder := backends.NewBuilder(addrs, builderBackend) - subnetAuth, _, err := b.Authorize(b.state, subnetID, keys) + opts := common.UnionOptions( + []common.Option{common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + })}, + []common.Option{common.WithMemo(memo)}, + ) + utx, err := pBuilder.NewCreateChainTx(subnetID, genesisData, vmID, fxIDs, chainName, opts...) if err != nil { - return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) - } - - // Sort the provided fxIDs - utils.Sort(fxIDs) - - // Create the tx - utx := &txs.CreateChainTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, - Memo: memo, - }}, - SubnetID: subnetID, - ChainName: chainName, - VMID: vmID, - FxIDs: fxIDs, - GenesisData: genesisData, - SubnetAuth: subnetAuth, + return nil, fmt.Errorf("failed building create chain tx: %w", err) } s := backends.New( @@ -516,33 +500,28 @@ func (b *builder) NewCreateSubnetTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - timestamp := b.state.GetTimestamp() - createSubnetTxFee := b.cfg.GetCreateSubnetTxFee(timestamp) - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: createSubnetTxFee, - } - toStake := make(map[ids.ID]uint64) - ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state) + pBuilder := backends.NewBuilder(addrs, builderBackend) - // Sort control addresses - utils.Sort(ownerAddrs) + subnetOwner := &secp256k1fx.OutputOwners{ + Threshold: threshold, + Addrs: ownerAddrs, + } - // Create the tx - utx := &txs.CreateSubnetTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, - Memo: memo, - }}, - Owner: &secp256k1fx.OutputOwners{ - Threshold: threshold, - Addrs: ownerAddrs, - }, + opts := common.UnionOptions( + []common.Option{common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + })}, + []common.Option{common.WithMemo(memo)}, + ) + utx, err := pBuilder.NewCreateSubnetTx(subnetOwner, opts...) + if err != nil { + return nil, fmt.Errorf("failed building create subnet tx: %w", err) } s := backends.New( @@ -638,38 +617,35 @@ func (b *builder) NewAddValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: b.cfg.AddPrimaryNetworkValidatorFee, + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } - toStake := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: stakeAmount, + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state) + pBuilder := backends.NewBuilder(addrs, builderBackend) + + vdr := &txs.Validator{ + NodeID: nodeID, + Start: startTime, + End: endTime, + Wght: stakeAmount, } - ins, unstakedOuts, stakedOuts, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + + rewardOwner := &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, } - // Create the tx - utx := &txs.AddValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - Memo: memo, - }}, - Validator: txs.Validator{ - NodeID: nodeID, - Start: startTime, - End: endTime, - Wght: stakeAmount, - }, - StakeOuts: stakedOuts, - RewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, + + opts := common.UnionOptions( + []common.Option{common.WithChangeOwner(&secp256k1fx.OutputOwners{ Threshold: 1, - Addrs: []ids.ShortID{rewardAddress}, - }, - DelegationShares: shares, + Addrs: []ids.ShortID{changeAddr}, + })}, + []common.Option{common.WithMemo(memo)}, + ) + utx, err := pBuilder.NewAddValidatorTx(vdr, rewardOwner, shares, opts...) + if err != nil { + return nil, fmt.Errorf("failed building create subnet tx: %w", err) } s := backends.New( diff --git a/vms/platformvm/txs/builder/builder_backend.go b/vms/platformvm/txs/builder/builder_backend.go index b7fd6abcf836..5ef3dce401dd 100644 --- a/vms/platformvm/txs/builder/builder_backend.go +++ b/vms/platformvm/txs/builder/builder_backend.go @@ -5,10 +5,10 @@ package builder import ( "context" - "errors" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" @@ -21,13 +21,14 @@ var _ backends.BuilderBackend = (*buiderBackend)(nil) func NewBuilderBackend( ctx *snow.Context, cfg *config.Config, + addrs set.Set[ids.ShortID], state state.State, ) backends.BuilderBackend { backendCtx := backends.NewContext( ctx.NetworkID, ctx.AVAXAssetID, cfg.TxFee, - cfg.CreateSubnetTxFee, + cfg.GetCreateSubnetTxFee(state.GetTimestamp()), cfg.TransformSubnetTxFee, cfg.CreateBlockchainTxFee, cfg.AddPrimaryNetworkValidatorFee, @@ -37,6 +38,7 @@ func NewBuilderBackend( ) return &buiderBackend{ Context: backendCtx, + addrs: addrs, state: state, } } @@ -44,11 +46,13 @@ func NewBuilderBackend( type buiderBackend struct { backends.Context + addrs set.Set[ids.ShortID] state state.State } -func (*buiderBackend) UTXOs(_ context.Context /*sourceChainID*/, _ ids.ID) ([]*avax.UTXO, error) { - return nil, errors.New("not yet implemented") +// TODO ABENEGIA: handle non-P-chain UTXOs case +func (b *buiderBackend) UTXOs(_ context.Context /*sourceChainID*/, _ ids.ID) ([]*avax.UTXO, error) { + return avax.GetAllUTXOs(b.state, b.addrs) // The UTXOs controlled by [keys] } func (b *buiderBackend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index b8b2c9deecb8..d53166eafdde 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -45,7 +45,7 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { require.NoError(err) // Remove a signature - tx.Creds[0].(*secp256k1fx.Credential).Sigs = tx.Creds[0].(*secp256k1fx.Credential).Sigs[1:] + tx.Creds[1].(*secp256k1fx.Credential).Sigs = tx.Creds[1].(*secp256k1fx.Credential).Sigs[1:] stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) @@ -85,7 +85,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { // Replace a valid signature with one from another key sig, err := key.SignHash(hashing.ComputeHash256(tx.Unsigned.Bytes())) require.NoError(err) - copy(tx.Creds[0].(*secp256k1fx.Credential).Sigs[0][:], sig) + copy(tx.Creds[1].(*secp256k1fx.Credential).Sigs[0][:], sig) stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 1b16e72bf3c2..7e3378ed045a 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -59,6 +59,7 @@ 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/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" smcon "github.com/ava-labs/avalanchego/snow/consensus/snowman" @@ -2143,6 +2144,9 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { keys[0].PublicKey().Address(), }, } + ctx, err := backends.NewSnowContext(vm.ctx.NetworkID, vm.ctx.AVAXAssetID) + require.NoError(err) + expectedOwner.InitCtx(ctx) require.Equal(expectedOwner, subnetOwner) transferSubnetOwnershipTx, err := vm.txBuilder.NewTransferSubnetOwnershipTx( From 2ef66ea55357cb8bfc5c321be6130a6686e38aa8 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 09:38:26 +0100 Subject: [PATCH 036/120] nit --- vms/platformvm/txs/builder/builder.go | 37 ++++++++++----------------- 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 352afe2de064..92fd87bcf0f5 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -470,14 +470,7 @@ func (b *builder) NewCreateChainTx( builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state) pBuilder := backends.NewBuilder(addrs, builderBackend) - opts := common.UnionOptions( - []common.Option{common.WithChangeOwner(&secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{changeAddr}, - })}, - []common.Option{common.WithMemo(memo)}, - ) - utx, err := pBuilder.NewCreateChainTx(subnetID, genesisData, vmID, fxIDs, chainName, opts...) + utx, err := pBuilder.NewCreateChainTx(subnetID, genesisData, vmID, fxIDs, chainName, options(changeAddr, memo)...) if err != nil { return nil, fmt.Errorf("failed building create chain tx: %w", err) } @@ -512,14 +505,7 @@ func (b *builder) NewCreateSubnetTx( Addrs: ownerAddrs, } - opts := common.UnionOptions( - []common.Option{common.WithChangeOwner(&secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{changeAddr}, - })}, - []common.Option{common.WithMemo(memo)}, - ) - utx, err := pBuilder.NewCreateSubnetTx(subnetOwner, opts...) + utx, err := pBuilder.NewCreateSubnetTx(subnetOwner, options(changeAddr, memo)...) if err != nil { return nil, fmt.Errorf("failed building create subnet tx: %w", err) } @@ -636,14 +622,7 @@ func (b *builder) NewAddValidatorTx( Addrs: []ids.ShortID{rewardAddress}, } - opts := common.UnionOptions( - []common.Option{common.WithChangeOwner(&secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{changeAddr}, - })}, - []common.Option{common.WithMemo(memo)}, - ) - utx, err := pBuilder.NewAddValidatorTx(vdr, rewardOwner, shares, opts...) + utx, err := pBuilder.NewAddValidatorTx(vdr, rewardOwner, shares, options(changeAddr, memo)...) if err != nil { return nil, fmt.Errorf("failed building create subnet tx: %w", err) } @@ -1033,3 +1012,13 @@ func (b *builder) NewBaseTx( } return tx, tx.SyntacticVerify(b.ctx) } + +func options(changeAddr ids.ShortID, memo []byte) []common.Option { + return common.UnionOptions( + []common.Option{common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + })}, + []common.Option{common.WithMemo(memo)}, + ) +} From 95d64cc9f517bc8c4b743853ed644356249d1d5f Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 09:46:13 +0100 Subject: [PATCH 037/120] wip: some more chaining p-chain txbuilder with wallet builder and signer --- vms/platformvm/txs/backends/builder.go | 8 +- vms/platformvm/txs/builder/builder.go | 607 +++++++----------- vms/platformvm/txs/builder/builder_backend.go | 24 +- vms/platformvm/txs/builder/signer_backend.go | 41 +- .../txs/executor/create_chain_test.go | 6 +- .../txs/executor/create_subnet_test.go | 6 +- vms/platformvm/txs/executor/import_test.go | 4 +- .../txs/executor/proposal_tx_executor_test.go | 2 +- .../txs/executor/standard_tx_executor_test.go | 2 +- vms/platformvm/vm_test.go | 6 +- 10 files changed, 290 insertions(+), 416 deletions(-) diff --git a/vms/platformvm/txs/backends/builder.go b/vms/platformvm/txs/backends/builder.go index 1f625dbc5bd0..5d2eb710dae5 100644 --- a/vms/platformvm/txs/backends/builder.go +++ b/vms/platformvm/txs/backends/builder.go @@ -25,7 +25,7 @@ var ( errNoChangeAddress = errors.New("no possible change address") errUnknownOwnerType = errors.New("unknown owner type") errInsufficientAuthorization = errors.New("insufficient authorization") - errInsufficientFunds = errors.New("insufficient funds") + ErrInsufficientFunds = errors.New("insufficient funds") _ Builder = (*builder)(nil) ) @@ -624,7 +624,7 @@ func (b *builder) NewImportTx( if len(importedInputs) == 0 { return nil, fmt.Errorf( "%w: no UTXOs available to import", - errInsufficientFunds, + ErrInsufficientFunds, ) } @@ -1112,7 +1112,7 @@ func (b *builder) spend( if amount != 0 { return nil, nil, nil, fmt.Errorf( "%w: provided UTXOs need %d more units of asset %q to stake", - errInsufficientFunds, + ErrInsufficientFunds, amount, assetID, ) @@ -1122,7 +1122,7 @@ func (b *builder) spend( if amount != 0 { return nil, nil, nil, fmt.Errorf( "%w: provided UTXOs need %d more units of asset %q", - errInsufficientFunds, + ErrInsufficientFunds, amount, assetID, ) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 92fd87bcf0f5..63bf72d38e81 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -5,7 +5,6 @@ package builder import ( "context" - "errors" "fmt" "time" @@ -13,7 +12,6 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -31,11 +29,7 @@ import ( // Max number of items allowed in a page const MaxPageSize = 1024 -var ( - _ Builder = (*builder)(nil) - - ErrNoFunds = errors.New("no spendable funds were found") -) +var _ Builder = (*builder)(nil) type Builder interface { AtomicTxBuilder @@ -297,98 +291,32 @@ func (b *builder) NewImportTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - kc := secp256k1fx.NewKeychain(keys...) - - atomicUTXOs, _, _, err := b.GetAtomicUTXOs(from, kc.Addresses(), ids.ShortEmpty, ids.Empty, MaxPageSize) - if err != nil { - return nil, fmt.Errorf("problem retrieving atomic UTXOs: %w", err) - } - - importedInputs := []*avax.TransferableInput{} - signers := [][]*secp256k1.PrivateKey{} - - importedAmounts := make(map[ids.ID]uint64) - now := b.clk.Unix() - for _, utxo := range atomicUTXOs { - inputIntf, utxoSigners, err := kc.Spend(utxo.Out, now) - if err != nil { - continue - } - input, ok := inputIntf.(avax.TransferableIn) - if !ok { - continue - } - assetID := utxo.AssetID() - importedAmounts[assetID], err = math.Add64(importedAmounts[assetID], input.Amount()) - if err != nil { - return nil, err - } - importedInputs = append(importedInputs, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - In: input, - }) - signers = append(signers, utxoSigners) - } - avax.SortTransferableInputsWithSigners(importedInputs, signers) - - if len(importedAmounts) == 0 { - return nil, ErrNoFunds // No imported UTXOs were spendable - } - - importedAVAX := importedAmounts[b.ctx.AVAXAssetID] - - ins := []*avax.TransferableInput{} - outs := []*avax.TransferableOutput{} - switch { - case importedAVAX < b.cfg.TxFee: // imported amount goes toward paying tx fee - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: b.cfg.TxFee - importedAVAX, - } - toStake := make(map[ids.ID]uint64) - ins, outs, _, err = b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) - } - delete(importedAmounts, b.ctx.AVAXAssetID) - case importedAVAX == b.cfg.TxFee: - delete(importedAmounts, b.ctx.AVAXAssetID) - default: - importedAmounts[b.ctx.AVAXAssetID] -= b.cfg.TxFee + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, builderBackend) - for assetID, amount := range importedAmounts { - outs = append(outs, &avax.TransferableOutput{ - Asset: avax.Asset{ID: assetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: amount, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{to}, - }, - }, - }) + outOwner := &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{to}, } - avax.SortTransferableOutputs(outs, txs.Codec) // sort imported outputs - - // Create the transaction - utx := &txs.ImportTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Outs: outs, - Ins: ins, - Memo: memo, - }}, - SourceChain: from, - ImportedInputs: importedInputs, + utx, err := pBuilder.NewImportTx( + from, + outOwner, + options(changeAddr, memo)..., + ) + if err != nil { + return nil, fmt.Errorf("failed building import tx: %w", err) } + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, from, atomicUTXOs), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -406,45 +334,38 @@ func (b *builder) NewExportTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - amtToBurn, err := math.Add64(amount, b.cfg.TxFee) - if err != nil { - return nil, fmt.Errorf("amount (%d) + tx fee(%d) overflows", amount, b.cfg.TxFee) - } - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: amtToBurn, - } - toStake := make(map[ids.ID]uint64) - ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, builderBackend) - // Create the transaction - utx := &txs.ExportTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, // Non-exported outputs - Memo: memo, - }}, - DestinationChain: chainID, - ExportedOutputs: []*avax.TransferableOutput{{ // Exported to X-Chain - Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: amount, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{to}, - }, + outputs := []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: amount, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{to}, }, - }}, + }, + }} + + utx, err := pBuilder.NewExportTx( + chainID, + outputs, + options(changeAddr, memo)..., + ) + if err != nil { + return nil, fmt.Errorf("failed building export tx: %w", err) } + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -467,7 +388,7 @@ func (b *builder) NewCreateChainTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state) + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) pBuilder := backends.NewBuilder(addrs, builderBackend) utx, err := pBuilder.NewCreateChainTx(subnetID, genesisData, vmID, fxIDs, chainName, options(changeAddr, memo)...) @@ -475,9 +396,10 @@ func (b *builder) NewCreateChainTx( return nil, fmt.Errorf("failed building create chain tx: %w", err) } + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -497,7 +419,7 @@ func (b *builder) NewCreateSubnetTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state) + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) pBuilder := backends.NewBuilder(addrs, builderBackend) subnetOwner := &secp256k1fx.OutputOwners{ @@ -510,9 +432,10 @@ func (b *builder) NewCreateSubnetTx( return nil, fmt.Errorf("failed building create subnet tx: %w", err) } + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -540,50 +463,38 @@ func (b *builder) NewTransformSubnetTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: b.cfg.TransformSubnetTxFee, - } - toStake := make(map[ids.ID]uint64) - ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, builderBackend) - subnetAuth, _, err := b.Authorize(b.state, subnetID, keys) + utx, err := pBuilder.NewTransformSubnetTx( + subnetID, + assetID, + initialSupply, + maxSupply, + minConsumptionRate, + maxConsumptionRate, + minValidatorStake, + maxValidatorStake, + minStakeDuration, + maxStakeDuration, + minDelegationFee, + minDelegatorStake, + maxValidatorWeightFactor, + uptimeRequirement, + options(changeAddr, memo)..., + ) if err != nil { - return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) - } - - utx := &txs.TransformSubnetTx{ - BaseTx: txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, - Memo: memo, - }, - }, - Subnet: subnetID, - AssetID: assetID, - InitialSupply: initialSupply, - MaximumSupply: maxSupply, - MinConsumptionRate: minConsumptionRate, - MaxConsumptionRate: maxConsumptionRate, - MinValidatorStake: minValidatorStake, - MaxValidatorStake: maxValidatorStake, - MinStakeDuration: uint32(minStakeDuration / time.Second), - MaxStakeDuration: uint32(maxStakeDuration / time.Second), - MinDelegationFee: minDelegationFee, - MinDelegatorStake: minDelegatorStake, - MaxValidatorWeightFactor: maxValidatorWeightFactor, - UptimeRequirement: uptimeRequirement, - SubnetAuth: subnetAuth, + return nil, fmt.Errorf("failed building transform subnet tx: %w", err) } + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -607,7 +518,7 @@ func (b *builder) NewAddValidatorTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state) + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) pBuilder := backends.NewBuilder(addrs, builderBackend) vdr := &txs.Validator{ @@ -624,12 +535,13 @@ func (b *builder) NewAddValidatorTx( utx, err := pBuilder.NewAddValidatorTx(vdr, rewardOwner, shares, options(changeAddr, memo)...) if err != nil { - return nil, fmt.Errorf("failed building create subnet tx: %w", err) + return nil, fmt.Errorf("failed building add validator tx: %w", err) } + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -650,50 +562,45 @@ func (b *builder) NewAddPermissionlessValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: b.cfg.AddPrimaryNetworkValidatorFee, - } - toStake := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: stakeAmount, - } - ins, unstakedOuts, stakedOuts, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } - // Create the tx - utx := &txs.AddPermissionlessValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: unstakedOuts, - Memo: memo, - }}, + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, builderBackend) + + vdr := &txs.SubnetValidator{ Validator: txs.Validator{ NodeID: nodeID, Start: startTime, End: endTime, Wght: stakeAmount, }, - Subnet: constants.PrimaryNetworkID, - Signer: pop, - StakeOuts: stakedOuts, - ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{rewardAddress}, - }, - DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{rewardAddress}, - }, - DelegationShares: shares, + Subnet: constants.PrimaryNetworkID, } + rewardOwner := &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, + } + + utx, err := pBuilder.NewAddPermissionlessValidatorTx( + vdr, + pop, + b.ctx.AVAXAssetID, + rewardOwner, // validationRewardsOwner + rewardOwner, // delegationRewardsOwner + shares, + options(changeAddr, memo)..., + ) + if err != nil { + return nil, fmt.Errorf("failed building add permissionless validator tx: %w", err) + } + + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -712,42 +619,38 @@ func (b *builder) NewAddDelegatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: b.cfg.AddPrimaryNetworkDelegatorFee, + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } - toStake := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: stakeAmount, + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, builderBackend) + + vdr := &txs.Validator{ + NodeID: nodeID, + Start: startTime, + End: endTime, + Wght: stakeAmount, } - ins, unlockedOuts, lockedOuts, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + + rewardOwner := &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, } - // Create the tx - utx := &txs.AddDelegatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: unlockedOuts, - Memo: memo, - }}, - Validator: txs.Validator{ - NodeID: nodeID, - Start: startTime, - End: endTime, - Wght: stakeAmount, - }, - StakeOuts: lockedOuts, - DelegationRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{rewardAddress}, - }, + + utx, err := pBuilder.NewAddDelegatorTx( + vdr, + rewardOwner, + options(changeAddr, memo)..., + ) + if err != nil { + return nil, fmt.Errorf("failed building add delegator tx: %w", err) } + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -766,43 +669,42 @@ func (b *builder) NewAddPermissionlessDelegatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: b.cfg.AddPrimaryNetworkDelegatorFee, - } - toStake := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: stakeAmount, - } - ins, unlockedOuts, lockedOuts, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } - // Create the tx - utx := &txs.AddPermissionlessDelegatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: unlockedOuts, - Memo: memo, - }}, + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, builderBackend) + + vdr := &txs.SubnetValidator{ Validator: txs.Validator{ NodeID: nodeID, Start: startTime, End: endTime, Wght: stakeAmount, }, - Subnet: constants.PrimaryNetworkID, - StakeOuts: lockedOuts, - DelegationRewardsOwner: &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{rewardAddress}, - }, + Subnet: constants.PrimaryNetworkID, + } + + rewardOwner := &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, } + utx, err := pBuilder.NewAddPermissionlessDelegatorTx( + vdr, + b.ctx.AVAXAssetID, + rewardOwner, + options(changeAddr, memo)..., + ) + if err != nil { + return nil, fmt.Errorf("failed building add permissionless delegator tx: %w", err) + } + + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -821,44 +723,35 @@ func (b *builder) NewAddSubnetValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: b.cfg.TxFee, - } - toStake := make(map[ids.ID]uint64) - ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, builderBackend) - subnetAuth, _, err := b.Authorize(b.state, subnetID, keys) - if err != nil { - return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) + vdr := &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: startTime, + End: endTime, + Wght: weight, + }, + Subnet: subnetID, } - // Create the tx - utx := &txs.AddSubnetValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, - Memo: memo, - }}, - SubnetValidator: txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - Start: startTime, - End: endTime, - Wght: weight, - }, - Subnet: subnetID, - }, - SubnetAuth: subnetAuth, + utx, err := pBuilder.NewAddSubnetValidatorTx( + vdr, + options(changeAddr, memo)..., + ) + if err != nil { + return nil, fmt.Errorf("failed building add subnet validator tx: %w", err) } + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -874,37 +767,26 @@ func (b *builder) NewRemoveSubnetValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: b.cfg.TxFee, - } - toStake := make(map[ids.ID]uint64) - ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, builderBackend) - subnetAuth, _, err := b.Authorize(b.state, subnetID, keys) + utx, err := pBuilder.NewRemoveSubnetValidatorTx( + nodeID, + subnetID, + options(changeAddr, memo)..., + ) if err != nil { - return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) - } - - // Create the tx - utx := &txs.RemoveSubnetValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, - Memo: memo, - }}, - Subnet: subnetID, - NodeID: nodeID, - SubnetAuth: subnetAuth, + return nil, fmt.Errorf("failed building remove subnet validator tx: %w", err) } + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -921,39 +803,31 @@ func (b *builder) NewTransferSubnetOwnershipTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: b.cfg.TxFee, - } - toStake := make(map[ids.ID]uint64) - ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, builderBackend) - subnetAuth, _, err := b.Authorize(b.state, subnetID, keys) - if err != nil { - return nil, fmt.Errorf("couldn't authorize tx's subnet restrictions: %w", err) + newOwner := &secp256k1fx.OutputOwners{ + Threshold: threshold, + Addrs: ownerAddrs, } - utx := &txs.TransferSubnetOwnershipTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, - Memo: memo, - }}, - Subnet: subnetID, - SubnetAuth: subnetAuth, - Owner: &secp256k1fx.OutputOwners{ - Threshold: threshold, - Addrs: ownerAddrs, - }, + utx, err := pBuilder.NewTransferSubnetOwnershipTx( + subnetID, + newOwner, + options(changeAddr, memo)..., + ) + if err != nil { + return nil, fmt.Errorf("failed building transfer subnet ownership tx: %w", err) } + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { @@ -969,42 +843,33 @@ func (b *builder) NewBaseTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - amtToBurn, err := math.Add64(amount, b.cfg.TxFee) - if err != nil { - return nil, fmt.Errorf("amount (%d) + tx fee(%d) overflows", amount, b.cfg.TxFee) - } - toBurn := map[ids.ID]uint64{ - b.ctx.AVAXAssetID: amtToBurn, - } - toStake := make(map[ids.ID]uint64) - ins, outs, _, err := b.Spend(b.state, keys, toBurn, toStake, changeAddr) - if err != nil { - return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err) + addrs := set.NewSet[ids.ShortID](len(keys)) + for _, key := range keys { + addrs.Add(key.Address()) } + builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, builderBackend) - outs = append(outs, &avax.TransferableOutput{ + out := &avax.TransferableOutput{ Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, Out: &secp256k1fx.TransferOutput{ Amt: amount, OutputOwners: owner, }, - }) - - avax.SortTransferableOutputs(outs, txs.Codec) + } - utx := &txs.BaseTx{ - BaseTx: avax.BaseTx{ - NetworkID: b.ctx.NetworkID, - BlockchainID: b.ctx.ChainID, - Ins: ins, - Outs: outs, - Memo: memo, - }, + utx, err := pBuilder.NewBaseTx( + []*avax.TransferableOutput{out}, + options(changeAddr, memo)..., + ) + if err != nil { + return nil, fmt.Errorf("failed building base tx: %w", err) } + kc := secp256k1fx.NewKeychain(keys...) s := backends.New( - secp256k1fx.NewKeychain(keys...), - NewSignerBackend(b.state, ids.Empty, nil), + kc, + NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { diff --git a/vms/platformvm/txs/builder/builder_backend.go b/vms/platformvm/txs/builder/builder_backend.go index 5ef3dce401dd..ef8325342925 100644 --- a/vms/platformvm/txs/builder/builder_backend.go +++ b/vms/platformvm/txs/builder/builder_backend.go @@ -8,6 +8,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/config" @@ -23,6 +24,7 @@ func NewBuilderBackend( cfg *config.Config, addrs set.Set[ids.ShortID], state state.State, + atomicUTXOsMan avax.AtomicUTXOManager, ) backends.BuilderBackend { backendCtx := backends.NewContext( ctx.NetworkID, @@ -37,22 +39,28 @@ func NewBuilderBackend( cfg.AddSubnetDelegatorFee, ) return &buiderBackend{ - Context: backendCtx, - addrs: addrs, - state: state, + Context: backendCtx, + addrs: addrs, + state: state, + atomicUTXOsMan: atomicUTXOsMan, } } type buiderBackend struct { backends.Context - addrs set.Set[ids.ShortID] - state state.State + addrs set.Set[ids.ShortID] + state state.State + atomicUTXOsMan avax.AtomicUTXOManager } -// TODO ABENEGIA: handle non-P-chain UTXOs case -func (b *buiderBackend) UTXOs(_ context.Context /*sourceChainID*/, _ ids.ID) ([]*avax.UTXO, error) { - return avax.GetAllUTXOs(b.state, b.addrs) // The UTXOs controlled by [keys] +func (b *buiderBackend) UTXOs(_ context.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) { + if sourceChainID == constants.PlatformChainID { + return avax.GetAllUTXOs(b.state, b.addrs) // The UTXOs controlled by [keys] + } + + atomicUTXOs, _, _, err := b.atomicUTXOsMan.GetAtomicUTXOs(sourceChainID, b.addrs, ids.ShortEmpty, ids.Empty, MaxPageSize) + return atomicUTXOs, err } func (b *buiderBackend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { diff --git a/vms/platformvm/txs/builder/signer_backend.go b/vms/platformvm/txs/builder/signer_backend.go index 058b13082641..dfc3b997897c 100644 --- a/vms/platformvm/txs/builder/signer_backend.go +++ b/vms/platformvm/txs/builder/signer_backend.go @@ -10,6 +10,7 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/state" @@ -18,39 +19,35 @@ import ( var _ backends.SignerBackend = (*signerBackend)(nil) -func NewSignerBackend(state state.State, sourceChain ids.ID, atomicUTXOs []*avax.UTXO) backends.SignerBackend { - importedUTXO := make(map[ids.ID]*avax.UTXO, len(atomicUTXOs)) - for _, utxo := range atomicUTXOs { - importedUTXO[utxo.InputID()] = utxo - } - +func NewSignerBackend(state state.State, atomicUTXOManager avax.AtomicUTXOManager, addrs set.Set[ids.ShortID]) backends.SignerBackend { return &signerBackend{ - state: state, - importedChainID: sourceChain, - importedUTXOs: importedUTXO, + state: state, + atomicUTXOManager: atomicUTXOManager, + addrs: addrs, } } type signerBackend struct { - state state.State - - importedChainID ids.ID - importedUTXOs map[ids.ID]*avax.UTXO // utxoID --> utxo + state state.State + atomicUTXOManager avax.AtomicUTXOManager + addrs set.Set[ids.ShortID] } func (s *signerBackend) GetUTXO(_ context.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) { - switch chainID { - case constants.PlatformChainID: + if chainID == constants.PlatformChainID { return s.state.GetUTXO(utxoID) - case s.importedChainID: - utxo, found := s.importedUTXOs[utxoID] - if !found { - return nil, database.ErrNotFound + } + + atomicUTXOs, _, _, err := s.atomicUTXOManager.GetAtomicUTXOs(chainID, s.addrs, ids.ShortEmpty, ids.Empty, MaxPageSize) + if err != nil { + return nil, fmt.Errorf("problem retrieving atomic UTXOs: %w", err) + } + for _, utxo := range atomicUTXOs { + if utxo.InputID() == utxoID { + return utxo, nil } - return utxo, nil - default: - return nil, fmt.Errorf("unexpected chain ID %s", chainID) } + return nil, database.ErrNotFound } func (s *signerBackend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index d53166eafdde..25d5039091e6 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -220,9 +220,11 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { VMID: constants.AVMID, SubnetAuth: subnetAuth, } + + kc := secp256k1fx.NewKeychain(preFundedKeys...) s := backends.New( - secp256k1fx.NewKeychain(preFundedKeys...), - builder.NewSignerBackend(env.state, ids.Empty, nil), + kc, + builder.NewSignerBackend(env.state, env.atomicUTXOs, kc.Addresses()), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) require.NoError(err) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index f9667cd94ceb..6f315e3cf576 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -74,9 +74,11 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { }}, Owner: &secp256k1fx.OutputOwners{}, } + + kc := secp256k1fx.NewKeychain(preFundedKeys...) s := backends.New( - secp256k1fx.NewKeychain(preFundedKeys...), - builder.NewSignerBackend(env.state, ids.Empty, nil), + kc, + builder.NewSignerBackend(env.state, env.atomicUTXOs, kc.Addresses()), ) tx, err := backends.SignUnsigned(context.Background(), s, utx) require.NoError(err) diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index bc52fabc2472..369ee9608871 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -17,7 +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/utxo" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -54,7 +54,7 @@ func TestNewImportTx(t *testing.T) { }, ), sourceKeys: []*secp256k1.PrivateKey{sourceKey}, - expectedErr: utxo.ErrInsufficientFunds, + expectedErr: backends.ErrInsufficientFunds, }, { description: "can barely pay fee", diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index a6ecc21b4059..d90288ac1c95 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -666,7 +666,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // Replace a valid signature with one from keys[3] sig, err := preFundedKeys[3].SignHash(hashing.ComputeHash256(tx.Unsigned.Bytes())) require.NoError(err) - copy(tx.Creds[1].(*secp256k1fx.Credential).Sigs[0][:], sig) + copy(tx.Creds[0].(*secp256k1fx.Credential).Sigs[0][:], sig) onCommitState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 69ad018caa1b..881295675811 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -741,7 +741,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // Replace a valid signature with one from keys[3] sig, err := preFundedKeys[3].SignHash(hashing.ComputeHash256(tx.Unsigned.Bytes())) require.NoError(err) - copy(tx.Creds[1].(*secp256k1fx.Credential).Sigs[0][:], sig) + copy(tx.Creds[0].(*secp256k1fx.Credential).Sigs[0][:], sig) onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 7e3378ed045a..4ec69c9b5ce2 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -68,7 +68,6 @@ import ( timetracker "github.com/ava-labs/avalanchego/snow/networking/tracker" blockbuilder "github.com/ava-labs/avalanchego/vms/platformvm/block/builder" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" - txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" ) @@ -989,7 +988,7 @@ func TestAtomicImport(t *testing.T) { ids.ShortEmpty, // change addr nil, ) - require.ErrorIs(err, txbuilder.ErrNoFunds) + require.ErrorIs(err, backends.ErrInsufficientFunds) // Provide the avm UTXO @@ -2182,6 +2181,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { keys[1].PublicKey().Address(), }, } + expectedOwner.InitCtx(ctx) require.Equal(expectedOwner, subnetOwner) } @@ -2242,7 +2242,7 @@ func TestBaseTx(t *testing.T) { } require.Equal(totalOutputAmt, key0OutputAmt+key1OutputAmt+changeAddrOutputAmt) - require.Equal(vm.TxFee, totalInputAmt-totalOutputAmt) + require.Equal(vm.Config.CreateSubnetTxFee, totalInputAmt-totalOutputAmt) // wallet inflates baseTx fee require.Equal(sendAmt, key1OutputAmt) vm.ctx.Lock.Unlock() From 131c19815835188a206b3dfb1985ba8a3ec41a8d Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 11:45:54 +0100 Subject: [PATCH 038/120] txbuilder constructor cleanup --- vms/platformvm/block/builder/helpers_test.go | 3 --- vms/platformvm/block/executor/helpers_test.go | 6 ------ vms/platformvm/txs/builder/builder.go | 12 ------------ vms/platformvm/txs/executor/helpers_test.go | 3 --- vms/platformvm/vm.go | 3 --- 5 files changed, 27 deletions(-) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 9190f01e2c6b..375735912653 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -156,11 +156,8 @@ func newEnvironment(t *testing.T, f fork) *environment { //nolint:unparam res.txBuilder = txbuilder.New( res.ctx, res.config, - res.clk, - res.fx, res.state, res.atomicUTXOs, - res.utxosHandler, ) genesisID := res.state.GetLastAccepted() diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 825625b7c77e..cf486fd72671 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -160,11 +160,8 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment res.txBuilder = p_tx_builder.New( res.ctx, res.config, - res.clk, - res.fx, res.state, res.atomicUTXOs, - res.utxosHandler, ) } else { genesisBlkID = ids.GenerateTestID() @@ -174,11 +171,8 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment res.txBuilder = p_tx_builder.New( res.ctx, res.config, - res.clk, - res.fx, res.mockedState, res.atomicUTXOs, - res.utxosHandler, ) // setup expectations strictly needed for environment creation diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 63bf72d38e81..34df225ab49d 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -13,15 +13,12 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/config" - "github.com/ava-labs/avalanchego/vms/platformvm/fx" "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/backends" - "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -256,32 +253,23 @@ type ProposalTxBuilder interface { func New( ctx *snow.Context, cfg *config.Config, - clk *mockable.Clock, - fx fx.Fx, state state.State, atomicUTXOManager avax.AtomicUTXOManager, - utxoSpender utxo.Spender, ) Builder { return &builder{ AtomicUTXOManager: atomicUTXOManager, - Spender: utxoSpender, state: state, cfg: cfg, ctx: ctx, - clk: clk, - fx: fx, } } type builder struct { avax.AtomicUTXOManager - utxo.Spender state state.State cfg *config.Config ctx *snow.Context - clk *mockable.Clock - fx fx.Fx } func (b *builder) NewImportTx( diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index f319b19826a2..e6f09f06c366 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -146,11 +146,8 @@ func newEnvironment(t *testing.T, f fork) *environment { txBuilder := builder.New( ctx, config, - clk, - fx, baseState, atomicUTXOs, - utxoHandler, ) backend := Backend{ diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 8c4801e06ea0..db64477e3046 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -165,11 +165,8 @@ func (vm *VM) Initialize( vm.txBuilder = txbuilder.New( vm.ctx, &vm.Config, - &vm.clock, - vm.fx, vm.state, vm.atomicUtxosManager, - utxoHandler, ) txExecutorBackend := &txexecutor.Backend{ From 979e30d698695e1c5ca910d8ffb182d555e69132 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 11:54:44 +0100 Subject: [PATCH 039/120] removed utxos Spend and Authorize --- vms/platformvm/block/builder/helpers_test.go | 4 +- vms/platformvm/block/executor/helpers_test.go | 6 +- .../txs/executor/create_chain_test.go | 37 +- .../txs/executor/create_subnet_test.go | 32 +- vms/platformvm/txs/executor/helpers_test.go | 4 +- vms/platformvm/utxo/handler.go | 327 +----------------- vms/platformvm/utxo/handler_test.go | 2 +- vms/platformvm/vm.go | 2 +- 8 files changed, 47 insertions(+), 367 deletions(-) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 375735912653..eb61e6830c3d 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -116,7 +116,7 @@ type environment struct { state state.State atomicUTXOs avax.AtomicUTXOManager uptimes uptime.Manager - utxosHandler utxo.Handler + utxosHandler utxo.Verifier txBuilder txbuilder.Builder backend txexecutor.Backend } @@ -151,7 +151,7 @@ func newEnvironment(t *testing.T, f fork) *environment { //nolint:unparam res.atomicUTXOs = avax.NewAtomicUTXOManager(res.ctx.SharedMemory, txs.Codec) res.uptimes = uptime.NewManager(res.state, res.clk) - res.utxosHandler = utxo.NewHandler(res.ctx, res.clk, res.fx) + res.utxosHandler = utxo.NewVerifier(res.ctx, res.clk, res.fx) res.txBuilder = txbuilder.New( res.ctx, diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index cf486fd72671..3c3ccf1474e7 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -127,7 +127,7 @@ type environment struct { mockedState *state.MockState atomicUTXOs avax.AtomicUTXOManager uptimes uptime.Manager - utxosHandler utxo.Handler + utxosHandler utxo.Verifier txBuilder p_tx_builder.Builder backend *executor.Backend } @@ -156,7 +156,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment if ctrl == nil { res.state = defaultState(res.config, res.ctx, res.baseDB, rewardsCalc) res.uptimes = uptime.NewManager(res.state, res.clk) - res.utxosHandler = utxo.NewHandler(res.ctx, res.clk, res.fx) + res.utxosHandler = utxo.NewVerifier(res.ctx, res.clk, res.fx) res.txBuilder = p_tx_builder.New( res.ctx, res.config, @@ -167,7 +167,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment genesisBlkID = ids.GenerateTestID() res.mockedState = state.NewMockState(ctrl) res.uptimes = uptime.NewManager(res.mockedState, res.clk) - res.utxosHandler = utxo.NewHandler(res.ctx, res.clk, res.fx) + res.utxosHandler = utxo.NewVerifier(res.ctx, res.clk, res.fx) res.txBuilder = p_tx_builder.New( res.ctx, res.config, diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 25d5039091e6..5abc8e2567f1 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -15,8 +15,8 @@ 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/set" "github.com/ava-labs/avalanchego/utils/units" - "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/backends" @@ -197,30 +197,25 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { env := newEnvironment(t, banff) env.config.ApricotPhase3Time = ap3Time - toBurn := map[ids.ID]uint64{ - env.ctx.AVAXAssetID: test.fee, + addrs := set.NewSet[ids.ShortID](len(preFundedKeys)) + for _, key := range preFundedKeys { + addrs.Add(key.Address()) } - toStake := make(map[ids.ID]uint64) - ins, outs, _, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) - require.NoError(err) - subnetAuth, _, err := env.utxosHandler.Authorize(env.state, testSubnet1.ID(), preFundedKeys) + cfg := *env.config + cfg.CreateBlockchainTxFee = test.fee + builderBackend := builder.NewBuilderBackend(env.ctx, &cfg, addrs, env.state, env.atomicUTXOs) + pBuilder := backends.NewBuilder(addrs, builderBackend) + + utx, err := pBuilder.NewCreateChainTx( + testSubnet1.ID(), + nil, // genesisData + ids.GenerateTestID(), // vmID + nil, // fxIDs + "", // chainName + ) require.NoError(err) - // Create the tx - - utx := &txs.CreateChainTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: outs, - }}, - SubnetID: testSubnet1.ID(), - VMID: constants.AVMID, - SubnetAuth: subnetAuth, - } - kc := secp256k1fx.NewKeychain(preFundedKeys...) s := backends.New( kc, diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 6f315e3cf576..7aae42ff09bb 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -11,10 +11,9 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" - "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/backends" "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" @@ -57,24 +56,23 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - toBurn := map[ids.ID]uint64{ - env.ctx.AVAXAssetID: test.fee, - } - toStake := make(map[ids.ID]uint64) - ins, outs, _, err := env.utxosHandler.Spend(env.state, preFundedKeys, toBurn, toStake, ids.ShortEmpty) - require.NoError(err) + env.state.SetTimestamp(test.time) - // Create the tx - utx := &txs.CreateSubnetTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: env.ctx.NetworkID, - BlockchainID: env.ctx.ChainID, - Ins: ins, - Outs: outs, - }}, - Owner: &secp256k1fx.OutputOwners{}, + addrs := set.NewSet[ids.ShortID](len(preFundedKeys)) + for _, key := range preFundedKeys { + addrs.Add(key.Address()) } + cfg := *env.config + cfg.CreateSubnetTxFee = test.fee + builderBackend := builder.NewBuilderBackend(env.ctx, &cfg, addrs, env.state, env.atomicUTXOs) + pBuilder := backends.NewBuilder(addrs, builderBackend) + + utx, err := pBuilder.NewCreateSubnetTx( + &secp256k1fx.OutputOwners{}, // owner + ) + require.NoError(err) + kc := secp256k1fx.NewKeychain(preFundedKeys...) s := backends.New( kc, diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index e6f09f06c366..71bf4753412c 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -102,7 +102,7 @@ type environment struct { states map[ids.ID]state.Chain atomicUTXOs avax.AtomicUTXOManager uptimes uptime.Manager - utxosHandler utxo.Handler + utxosHandler utxo.Verifier txBuilder builder.Builder backend Backend } @@ -141,7 +141,7 @@ func newEnvironment(t *testing.T, f fork) *environment { atomicUTXOs := avax.NewAtomicUTXOManager(ctx.SharedMemory, txs.Codec) uptimes := uptime.NewManager(baseState, clk) - utxoHandler := utxo.NewHandler(ctx, clk, fx) + utxoHandler := utxo.NewVerifier(ctx, clk, fx) txBuilder := builder.New( ctx, diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index 019c1ca3d3b3..4adde447bad5 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -9,25 +9,18 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/utils/set" "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/fx" "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" - "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) var ( - _ Handler = (*handler)(nil) + _ Verifier = (*verifier)(nil) ErrInsufficientFunds = errors.New("insufficient funds") ErrInsufficientUnlockedFunds = errors.New("insufficient unlocked funds") @@ -36,52 +29,9 @@ var ( errWrongNumberUTXOs = errors.New("wrong number of UTXOs") errAssetIDMismatch = errors.New("input asset ID does not match UTXO asset ID") errLocktimeMismatch = errors.New("input locktime does not match UTXO locktime") - errCantSign = errors.New("can't sign") errLockedFundsNotMarkedAsLocked = errors.New("locked funds not marked as locked") ) -// TODO: Stake and Authorize should be replaced by similar methods in the -// P-chain wallet -type Spender interface { - // Spend the provided amount while deducting the provided fee. - // Arguments: - // - [keys] are the owners of the funds - // - [amount] is the amount of funds that are trying to be staked - // - [fee] is the amount of AVAX that should be burned - // - [changeAddr] is the address that change, if there is any, is sent to - // Returns: - // - [inputs] the inputs that should be consumed to fund the outputs - // - [returnedOutputs] the outputs that should be immediately returned to - // the UTXO set - // - [stakedOutputs] the outputs that should be locked for the duration of - // the staking period - // - [signers] the proof of ownership of the funds being moved - Spend( - utxoReader avax.UTXOReader, - keys []*secp256k1.PrivateKey, - amountsToBurn map[ids.ID]uint64, - amountsToStake map[ids.ID]uint64, - changeAddr ids.ShortID, - ) ( - []*avax.TransferableInput, // inputs - []*avax.TransferableOutput, // returnedOutputs - []*avax.TransferableOutput, // stakedOutputs - error, - ) - - // Authorize an operation on behalf of the named subnet with the provided - // keys. - Authorize( - state state.Chain, - subnetID ids.ID, - keys []*secp256k1.PrivateKey, - ) ( - verify.Verifiable, // Input that names owners - []*secp256k1.PrivateKey, // Keys that prove ownership - error, - ) -} - type Verifier interface { // Verify that [tx] is semantically valid. // [ins] and [outs] are the inputs and outputs of [tx]. @@ -123,288 +73,25 @@ type Verifier interface { ) error } -type Handler interface { - Spender - Verifier -} - -func NewHandler( +func NewVerifier( ctx *snow.Context, clk *mockable.Clock, fx fx.Fx, -) Handler { - return &handler{ +) Verifier { + return &verifier{ ctx: ctx, clk: clk, fx: fx, } } -type handler struct { +type verifier struct { ctx *snow.Context clk *mockable.Clock fx fx.Fx } -func (h *handler) Spend( - utxoReader avax.UTXOReader, - keys []*secp256k1.PrivateKey, - amountsToBurn map[ids.ID]uint64, - amountsToStake map[ids.ID]uint64, - changeAddr ids.ShortID, -) ( - inputs []*avax.TransferableInput, - changeOutputs []*avax.TransferableOutput, - stakeOutputs []*avax.TransferableOutput, - err error, -) { - addrs := set.NewSet[ids.ShortID](len(keys)) // The addresses controlled by [keys] - for _, key := range keys { - addrs.Add(key.PublicKey().Address()) - } - utxos, err := avax.GetAllUTXOs(utxoReader, addrs) // The UTXOs controlled by [keys] - if err != nil { - return nil, nil, nil, fmt.Errorf("couldn't get UTXOs: %w", err) - } - - // Minimum time this transaction will be issued at - minIssuanceTime := uint64(h.clk.Time().Unix()) - - changeOwner := &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{changeAddr}, - } - - // Iterate over the locked UTXOs - for _, utxo := range utxos { - assetID := utxo.AssetID() - remainingAmountToStake := amountsToStake[assetID] - - // If we have staked enough of the asset, then we have no need burn - // more. - if remainingAmountToStake == 0 { - continue - } - - outIntf := utxo.Out - lockedOut, ok := outIntf.(*stakeable.LockOut) - if !ok { - // This output isn't locked, so it will be handled during the next - // iteration of the UTXO set - continue - } - if minIssuanceTime >= lockedOut.Locktime { - // This output isn't locked, so it will be handled during the next - // iteration of the UTXO set - continue - } - - out, ok := lockedOut.TransferableOut.(*secp256k1fx.TransferOutput) - if !ok { - return nil, nil, nil, backends.ErrUnknownOutputType - } - - inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) - if !ok { - // We couldn't spend this UTXO, so we skip to the next one - continue - } - - inputs = append(inputs, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - In: &stakeable.LockIn{ - Locktime: lockedOut.Locktime, - TransferableIn: &secp256k1fx.TransferInput{ - Amt: out.Amt, - Input: secp256k1fx.Input{ - SigIndices: inputSigIndices, - }, - }, - }, - }) - - // Stake any value that should be staked - amountToStake := min( - remainingAmountToStake, // Amount we still need to stake - out.Amt, // Amount available to stake - ) - - // Add the output to the staked outputs - stakeOutputs = append(stakeOutputs, &avax.TransferableOutput{ - Asset: utxo.Asset, - Out: &stakeable.LockOut{ - Locktime: lockedOut.Locktime, - TransferableOut: &secp256k1fx.TransferOutput{ - Amt: amountToStake, - OutputOwners: out.OutputOwners, - }, - }, - }) - - amountsToStake[assetID] -= amountToStake - if remainingAmount := out.Amt - amountToStake; remainingAmount > 0 { - // This input had extra value, so some of it must be returned - changeOutputs = append(changeOutputs, &avax.TransferableOutput{ - Asset: utxo.Asset, - Out: &stakeable.LockOut{ - Locktime: lockedOut.Locktime, - TransferableOut: &secp256k1fx.TransferOutput{ - Amt: remainingAmount, - OutputOwners: out.OutputOwners, - }, - }, - }) - } - } - - // Iterate over the unlocked UTXOs - for _, utxo := range utxos { - assetID := utxo.AssetID() - remainingAmountToStake := amountsToStake[assetID] - remainingAmountToBurn := amountsToBurn[assetID] - - // If we have consumed enough of the asset, then we have no need burn - // more. - if remainingAmountToStake == 0 && remainingAmountToBurn == 0 { - continue - } - - outIntf := utxo.Out - if lockedOut, ok := outIntf.(*stakeable.LockOut); ok { - if lockedOut.Locktime > minIssuanceTime { - // This output is currently locked, so this output can't be - // burned. - continue - } - outIntf = lockedOut.TransferableOut - } - - out, ok := outIntf.(*secp256k1fx.TransferOutput) - if !ok { - return nil, nil, nil, backends.ErrUnknownOutputType - } - - inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) - if !ok { - // We couldn't spend this UTXO, so we skip to the next one - continue - } - - inputs = append(inputs, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - In: &secp256k1fx.TransferInput{ - Amt: out.Amt, - Input: secp256k1fx.Input{ - SigIndices: inputSigIndices, - }, - }, - }) - - // Burn any value that should be burned - amountToBurn := min( - remainingAmountToBurn, // Amount we still need to burn - out.Amt, // Amount available to burn - ) - amountsToBurn[assetID] -= amountToBurn - - amountAvalibleToStake := out.Amt - amountToBurn - // Burn any value that should be burned - amountToStake := min( - remainingAmountToStake, // Amount we still need to stake - amountAvalibleToStake, // Amount available to stake - ) - amountsToStake[assetID] -= amountToStake - if amountToStake > 0 { - // Some of this input was put for staking - stakeOutputs = append(stakeOutputs, &avax.TransferableOutput{ - Asset: utxo.Asset, - Out: &secp256k1fx.TransferOutput{ - Amt: amountToStake, - OutputOwners: *changeOwner, - }, - }) - } - if remainingAmount := amountAvalibleToStake - amountToStake; remainingAmount > 0 { - // This input had extra value, so some of it must be returned - changeOutputs = append(changeOutputs, &avax.TransferableOutput{ - Asset: utxo.Asset, - Out: &secp256k1fx.TransferOutput{ - Amt: remainingAmount, - OutputOwners: *changeOwner, - }, - }) - } - } - - for assetID, amount := range amountsToStake { - if amount != 0 { - return nil, nil, nil, fmt.Errorf( - "%w: provided UTXOs need %d more units of asset %q to stake", - ErrInsufficientFunds, - amount, - assetID, - ) - } - } - for assetID, amount := range amountsToBurn { - if amount != 0 { - return nil, nil, nil, fmt.Errorf( - "%w: provided UTXOs need %d more units of asset %q", - ErrInsufficientFunds, - amount, - assetID, - ) - } - } - - utils.Sort(inputs) // sort inputs - avax.SortTransferableOutputs(changeOutputs, txs.Codec) // sort the change outputs - avax.SortTransferableOutputs(stakeOutputs, txs.Codec) // sort stake outputs - return inputs, changeOutputs, stakeOutputs, nil -} - -func (h *handler) Authorize( - state state.Chain, - subnetID ids.ID, - keys []*secp256k1.PrivateKey, -) ( - verify.Verifiable, // Input that names owners - []*secp256k1.PrivateKey, // Keys that prove ownership - error, -) { - subnetOwner, err := state.GetSubnetOwner(subnetID) - if err != nil { - return nil, nil, fmt.Errorf( - "failed to fetch subnet owner for %s: %w", - subnetID, - err, - ) - } - - // Make sure the owners of the subnet match the provided keys - owner, ok := subnetOwner.(*secp256k1fx.OutputOwners) - if !ok { - return nil, nil, fmt.Errorf("expected *secp256k1fx.OutputOwners but got %T", subnetOwner) - } - - // Add the keys to a keychain - kc := secp256k1fx.NewKeychain(keys...) - - // Make sure that the operation is valid after a minimum time - now := uint64(h.clk.Time().Unix()) - - // Attempt to prove ownership of the subnet - indices, signers, matches := kc.Match(owner, now) - if !matches { - return nil, nil, errCantSign - } - - return &secp256k1fx.Input{SigIndices: indices}, signers, nil -} - -func (h *handler) VerifySpend( +func (h *verifier) VerifySpend( tx txs.UnsignedTx, utxoDB avax.UTXOGetter, ins []*avax.TransferableInput, @@ -428,7 +115,7 @@ func (h *handler) VerifySpend( return h.VerifySpendUTXOs(tx, utxos, ins, outs, creds, unlockedProduced) } -func (h *handler) VerifySpendUTXOs( +func (h *verifier) VerifySpendUTXOs( tx txs.UnsignedTx, utxos []*avax.UTXO, ins []*avax.TransferableInput, diff --git a/vms/platformvm/utxo/handler_test.go b/vms/platformvm/utxo/handler_test.go index d0224ed4666a..24bb95e024d0 100644 --- a/vms/platformvm/utxo/handler_test.go +++ b/vms/platformvm/utxo/handler_test.go @@ -41,7 +41,7 @@ func TestVerifySpendUTXOs(t *testing.T) { ctx := snowtest.Context(t, snowtest.PChainID) - h := &handler{ + h := &verifier{ ctx: ctx, clk: &mockable.Clock{}, fx: fx, diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index db64477e3046..deb2785f21f3 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -158,7 +158,7 @@ func (vm *VM) Initialize( validatorManager := pvalidators.NewManager(chainCtx.Log, vm.Config, vm.state, vm.metrics, &vm.clock) vm.State = validatorManager vm.atomicUtxosManager = avax.NewAtomicUTXOManager(chainCtx.SharedMemory, txs.Codec) - utxoHandler := utxo.NewHandler(vm.ctx, &vm.clock, vm.fx) + utxoHandler := utxo.NewVerifier(vm.ctx, &vm.clock, vm.fx) vm.uptimeManager = uptime.NewManager(vm.state, &vm.clock) vm.UptimeLockedCalculator.SetCalculator(&vm.bootstrapped, &chainCtx.Lock, vm.uptimeManager) From 566b09b69fc88ac5031aa7998222f10f144f2a95 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 13:09:43 +0100 Subject: [PATCH 040/120] moved backends package to wallet --- vms/platformvm/txs/builder/builder.go | 2 +- vms/platformvm/txs/builder/builder_backend.go | 2 +- vms/platformvm/txs/builder/signer_backend.go | 2 +- vms/platformvm/txs/executor/create_chain_test.go | 2 +- vms/platformvm/txs/executor/create_subnet_test.go | 2 +- vms/platformvm/txs/executor/import_test.go | 2 +- vms/platformvm/vm_test.go | 2 +- wallet/chain/p/backend.go | 2 +- wallet/chain/p/backend_visitor.go | 2 +- {vms/platformvm/txs => wallet/chain/p}/backends/backends.go | 0 {vms/platformvm/txs => wallet/chain/p}/backends/builder.go | 0 {vms/platformvm/txs => wallet/chain/p}/backends/context.go | 0 {vms/platformvm/txs => wallet/chain/p}/backends/signer.go | 0 .../txs => wallet/chain/p}/backends/signer_visitor.go | 0 wallet/chain/p/builder_test.go | 2 +- wallet/chain/p/builder_with_options.go | 2 +- wallet/chain/p/context.go | 2 +- wallet/chain/p/wallet.go | 2 +- wallet/chain/p/wallet_with_options.go | 2 +- wallet/subnet/primary/api.go | 2 +- wallet/subnet/primary/examples/get-p-chain-balance/main.go | 4 ++-- wallet/subnet/primary/wallet.go | 6 +++--- 22 files changed, 20 insertions(+), 20 deletions(-) rename {vms/platformvm/txs => wallet/chain/p}/backends/backends.go (100%) rename {vms/platformvm/txs => wallet/chain/p}/backends/builder.go (100%) rename {vms/platformvm/txs => wallet/chain/p}/backends/context.go (100%) rename {vms/platformvm/txs => wallet/chain/p}/backends/signer.go (100%) rename {vms/platformvm/txs => wallet/chain/p}/backends/signer_visitor.go (100%) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 34df225ab49d..ad8fcc4e090b 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -18,8 +18,8 @@ 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/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) diff --git a/vms/platformvm/txs/builder/builder_backend.go b/vms/platformvm/txs/builder/builder_backend.go index ef8325342925..14ecd83d4d4f 100644 --- a/vms/platformvm/txs/builder/builder_backend.go +++ b/vms/platformvm/txs/builder/builder_backend.go @@ -14,7 +14,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/state" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) var _ backends.BuilderBackend = (*buiderBackend)(nil) diff --git a/vms/platformvm/txs/builder/signer_backend.go b/vms/platformvm/txs/builder/signer_backend.go index dfc3b997897c..79d396c5bb25 100644 --- a/vms/platformvm/txs/builder/signer_backend.go +++ b/vms/platformvm/txs/builder/signer_backend.go @@ -14,7 +14,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/state" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) var _ backends.SignerBackend = (*signerBackend)(nil) diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 5abc8e2567f1..5e51cc51ce95 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -19,10 +19,10 @@ 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/backends" "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) // Ensure Execute fails when there are not enough control sigs diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 7aae42ff09bb..c4172f16e91c 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -14,10 +14,10 @@ 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/backends" "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) func TestCreateSubnetTxAP3FeeChange(t *testing.T) { diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index 369ee9608871..40ef33852fc6 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -17,8 +17,8 @@ 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/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) var fundedSharedMemoryCalls byte diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 4ec69c9b5ce2..f7bb612bb65d 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -59,8 +59,8 @@ 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/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" smcon "github.com/ava-labs/avalanchego/snow/consensus/snowman" smeng "github.com/ava-labs/avalanchego/snow/engine/snowman" diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index 08c8c83737fc..a241fde2225a 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -13,7 +13,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" stdcontext "context" diff --git a/wallet/chain/p/backend_visitor.go b/wallet/chain/p/backend_visitor.go index d3668cac9f1d..afbaad3a09a8 100644 --- a/wallet/chain/p/backend_visitor.go +++ b/wallet/chain/p/backend_visitor.go @@ -8,7 +8,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" stdcontext "context" ) diff --git a/vms/platformvm/txs/backends/backends.go b/wallet/chain/p/backends/backends.go similarity index 100% rename from vms/platformvm/txs/backends/backends.go rename to wallet/chain/p/backends/backends.go diff --git a/vms/platformvm/txs/backends/builder.go b/wallet/chain/p/backends/builder.go similarity index 100% rename from vms/platformvm/txs/backends/builder.go rename to wallet/chain/p/backends/builder.go diff --git a/vms/platformvm/txs/backends/context.go b/wallet/chain/p/backends/context.go similarity index 100% rename from vms/platformvm/txs/backends/context.go rename to wallet/chain/p/backends/context.go diff --git a/vms/platformvm/txs/backends/signer.go b/wallet/chain/p/backends/signer.go similarity index 100% rename from vms/platformvm/txs/backends/signer.go rename to wallet/chain/p/backends/signer.go diff --git a/vms/platformvm/txs/backends/signer_visitor.go b/wallet/chain/p/backends/signer_visitor.go similarity index 100% rename from vms/platformvm/txs/backends/signer_visitor.go rename to wallet/chain/p/backends/signer_visitor.go diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 43b5a10f60a8..6f31a0af12bf 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -20,8 +20,8 @@ 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/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) diff --git a/wallet/chain/p/builder_with_options.go b/wallet/chain/p/builder_with_options.go index b99f774a4262..7bfaf0046308 100644 --- a/wallet/chain/p/builder_with_options.go +++ b/wallet/chain/p/builder_with_options.go @@ -10,8 +10,8 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) diff --git a/wallet/chain/p/context.go b/wallet/chain/p/context.go index f93513d640ea..862e2364525a 100644 --- a/wallet/chain/p/context.go +++ b/wallet/chain/p/context.go @@ -6,7 +6,7 @@ package p import ( "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/vms/avm" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" stdcontext "context" ) diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 842a03f23e34..1fd85e8cabe1 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -14,8 +14,8 @@ 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/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) diff --git a/wallet/chain/p/wallet_with_options.go b/wallet/chain/p/wallet_with_options.go index 62e8fb8e0d05..53067332dc4d 100644 --- a/wallet/chain/p/wallet_with_options.go +++ b/wallet/chain/p/wallet_with_options.go @@ -10,8 +10,8 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 2b5ef8c155ce..0e559affc45e 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -20,9 +20,9 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/chain/x" walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" diff --git a/wallet/subnet/primary/examples/get-p-chain-balance/main.go b/wallet/subnet/primary/examples/get-p-chain-balance/main.go index f0f4b07c4886..df8d0bdf62d1 100644 --- a/wallet/subnet/primary/examples/get-p-chain-balance/main.go +++ b/wallet/subnet/primary/examples/get-p-chain-balance/main.go @@ -15,7 +15,7 @@ import ( "github.com/ava-labs/avalanchego/wallet/subnet/primary" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - psigner "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" + pbackends "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) func main() { @@ -40,7 +40,7 @@ func main() { pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, state.UTXOs) pBackend := p.NewBackend(state.PCTX, pUTXOs, nil) - pBuilder := psigner.NewBuilder(addresses, pBackend) + pBuilder := pbackends.NewBuilder(addresses, pBackend) currentBalances, err := pBuilder.GetBalance() if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 95a0fe82be8b..084f1bdff01c 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -16,7 +16,7 @@ import ( "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - psigner "github.com/ava-labs/avalanchego/vms/platformvm/txs/backends" + pbackends "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) var _ Wallet = (*wallet)(nil) @@ -120,8 +120,8 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, avaxState.UTXOs) pBackend := p.NewBackend(avaxState.PCTX, pUTXOs, pChainTxs) - pBuilder := psigner.NewBuilder(avaxAddrs, pBackend) - pSigner := psigner.New(config.AVAXKeychain, pBackend) + pBuilder := pbackends.NewBuilder(avaxAddrs, pBackend) + pSigner := pbackends.New(config.AVAXKeychain, pBackend) xChainID := avaxState.XCTX.BlockchainID() xUTXOs := common.NewChainUTXOs(xChainID, avaxState.UTXOs) From 1b22091447cb70b96c157ea5b7808179727390d9 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 13:21:49 +0100 Subject: [PATCH 041/120] nit --- wallet/chain/p/backend.go | 2 +- wallet/chain/p/backends/backends.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index a241fde2225a..3cdafcef9d3e 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -23,7 +23,7 @@ var _ Backend = (*backend)(nil) // Backend defines the full interface required to support a P-chain wallet. type Backend interface { - backends.WalletBackend + backends.Backend AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error } diff --git a/wallet/chain/p/backends/backends.go b/wallet/chain/p/backends/backends.go index cce25523dfc1..77caac1a94ab 100644 --- a/wallet/chain/p/backends/backends.go +++ b/wallet/chain/p/backends/backends.go @@ -12,11 +12,11 @@ import ( ) var ( - _ BuilderBackend = WalletBackend(nil) - _ SignerBackend = WalletBackend(nil) + _ BuilderBackend = Backend(nil) + _ SignerBackend = Backend(nil) ) -type WalletBackend interface { +type Backend interface { Context UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) From f7d288cfb2739bed6f9d2711e7b3a54f7c71d7e4 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 13:40:34 +0100 Subject: [PATCH 042/120] nits --- wallet/chain/p/backends/signer.go | 6 ++-- wallet/chain/p/backends/signer_visitor.go | 40 +++++++++++------------ 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/wallet/chain/p/backends/signer.go b/wallet/chain/p/backends/signer.go index 976442c8ee7b..ec5f70befe14 100644 --- a/wallet/chain/p/backends/signer.go +++ b/wallet/chain/p/backends/signer.go @@ -37,7 +37,7 @@ func New(kc keychain.Keychain, backend SignerBackend) Signer { } func (s *txSigner) Sign(ctx stdcontext.Context, tx *txs.Tx) error { - return tx.Unsigned.Visit(&Visitor{ + return tx.Unsigned.Visit(&signerVisitor{ kc: s.kc, backend: s.backend, ctx: ctx, @@ -47,9 +47,9 @@ func (s *txSigner) Sign(ctx stdcontext.Context, tx *txs.Tx) error { func SignUnsigned( ctx stdcontext.Context, - s Signer, + signer Signer, utx txs.UnsignedTx, ) (*txs.Tx, error) { tx := &txs.Tx{Unsigned: utx} - return tx, s.Sign(ctx, tx) + return tx, signer.Sign(ctx, tx) } diff --git a/wallet/chain/p/backends/signer_visitor.go b/wallet/chain/p/backends/signer_visitor.go index 5ae15131570c..5a237cfc499c 100644 --- a/wallet/chain/p/backends/signer_visitor.go +++ b/wallet/chain/p/backends/signer_visitor.go @@ -22,7 +22,7 @@ import ( ) var ( - _ txs.Visitor = (*Visitor)(nil) + _ txs.Visitor = (*signerVisitor)(nil) ErrUnknownOwnerType = errors.New("unknown owner type") ErrUnknownOutputType = errors.New("unknown output type") @@ -35,23 +35,23 @@ var ( emptySig [secp256k1.SignatureLen]byte ) -// Visitor handles signing transactions for the signer -type Visitor struct { +// signerVisitor handles signing transactions for the signer +type signerVisitor struct { kc keychain.Keychain backend SignerBackend ctx context.Context tx *txs.Tx } -func (*Visitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { +func (*signerVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { return ErrUnsupportedTxType } -func (*Visitor) RewardValidatorTx(*txs.RewardValidatorTx) error { +func (*signerVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { return ErrUnsupportedTxType } -func (s *Visitor) BaseTx(tx *txs.BaseTx) error { +func (s *signerVisitor) BaseTx(tx *txs.BaseTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -59,7 +59,7 @@ func (s *Visitor) BaseTx(tx *txs.BaseTx) error { return sign(s.tx, false, txSigners) } -func (s *Visitor) AddValidatorTx(tx *txs.AddValidatorTx) error { +func (s *signerVisitor) AddValidatorTx(tx *txs.AddValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -67,7 +67,7 @@ func (s *Visitor) AddValidatorTx(tx *txs.AddValidatorTx) error { return sign(s.tx, false, txSigners) } -func (s *Visitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { +func (s *signerVisitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -80,7 +80,7 @@ func (s *Visitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { return sign(s.tx, false, txSigners) } -func (s *Visitor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { +func (s *signerVisitor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -88,7 +88,7 @@ func (s *Visitor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { return sign(s.tx, false, txSigners) } -func (s *Visitor) CreateChainTx(tx *txs.CreateChainTx) error { +func (s *signerVisitor) CreateChainTx(tx *txs.CreateChainTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -101,7 +101,7 @@ func (s *Visitor) CreateChainTx(tx *txs.CreateChainTx) error { return sign(s.tx, false, txSigners) } -func (s *Visitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { +func (s *signerVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -109,7 +109,7 @@ func (s *Visitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { return sign(s.tx, false, txSigners) } -func (s *Visitor) ImportTx(tx *txs.ImportTx) error { +func (s *signerVisitor) ImportTx(tx *txs.ImportTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -122,7 +122,7 @@ func (s *Visitor) ImportTx(tx *txs.ImportTx) error { return sign(s.tx, false, txSigners) } -func (s *Visitor) ExportTx(tx *txs.ExportTx) error { +func (s *signerVisitor) ExportTx(tx *txs.ExportTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -130,7 +130,7 @@ func (s *Visitor) ExportTx(tx *txs.ExportTx) error { return sign(s.tx, false, txSigners) } -func (s *Visitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { +func (s *signerVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -143,7 +143,7 @@ func (s *Visitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error return sign(s.tx, true, txSigners) } -func (s *Visitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { +func (s *signerVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -156,7 +156,7 @@ func (s *Visitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) e return sign(s.tx, true, txSigners) } -func (s *Visitor) TransformSubnetTx(tx *txs.TransformSubnetTx) error { +func (s *signerVisitor) TransformSubnetTx(tx *txs.TransformSubnetTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -169,7 +169,7 @@ func (s *Visitor) TransformSubnetTx(tx *txs.TransformSubnetTx) error { return sign(s.tx, true, txSigners) } -func (s *Visitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { +func (s *signerVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -177,7 +177,7 @@ func (s *Visitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidato return sign(s.tx, true, txSigners) } -func (s *Visitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { +func (s *signerVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -185,7 +185,7 @@ func (s *Visitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegato return sign(s.tx, true, txSigners) } -func (s *Visitor) getSigners(sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { +func (s *signerVisitor) getSigners(sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { txSigners := make([][]keychain.Signer, len(ins)) for credIndex, transferInput := range ins { inIntf := transferInput.In @@ -240,7 +240,7 @@ func (s *Visitor) getSigners(sourceChainID ids.ID, ins []*avax.TransferableInput return txSigners, nil } -func (s *Visitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Verifiable) ([]keychain.Signer, error) { +func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Verifiable) ([]keychain.Signer, error) { subnetInput, ok := subnetAuth.(*secp256k1fx.Input) if !ok { return nil, errUnknownSubnetAuthType From fa0eb5a7001697c7de06b21d6f8eb658f7ed3cc6 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 13:32:39 +0100 Subject: [PATCH 043/120] repackaged wallet backend for P-chain --- wallet/chain/p/backend.go | 9 +- wallet/chain/p/backend_visitor.go | 5 +- wallet/chain/p/backends/backends.go | 35 ++++++ wallet/chain/p/{ => backends}/builder.go | 29 ++--- wallet/chain/p/backends/context.go | 119 ++++++++++++++++++ wallet/chain/p/{ => backends}/signer.go | 10 +- .../chain/p/{ => backends}/signer_visitor.go | 20 +-- wallet/chain/p/builder_test.go | 25 ++-- wallet/chain/p/builder_with_options.go | 7 +- wallet/chain/p/context.go | 119 +----------------- wallet/chain/p/wallet.go | 21 ++-- wallet/chain/p/wallet_with_options.go | 3 +- wallet/subnet/primary/api.go | 3 +- .../examples/get-p-chain-balance/main.go | 4 +- wallet/subnet/primary/wallet.go | 6 +- 15 files changed, 224 insertions(+), 191 deletions(-) create mode 100644 wallet/chain/p/backends/backends.go rename wallet/chain/p/{ => backends}/builder.go (98%) create mode 100644 wallet/chain/p/backends/context.go rename wallet/chain/p/{ => backends}/signer.go (78%) rename wallet/chain/p/{ => backends}/signer_visitor.go (96%) diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index 5b8001808ceb..3cdafcef9d3e 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -13,6 +13,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" stdcontext "context" @@ -22,22 +23,20 @@ var _ Backend = (*backend)(nil) // Backend defines the full interface required to support a P-chain wallet. type Backend interface { - common.ChainUTXOs - BuilderBackend - SignerBackend + backends.Backend AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error } type backend struct { - Context + backends.Context common.ChainUTXOs subnetOwnerLock sync.RWMutex subnetOwner map[ids.ID]fx.Owner // subnetID -> owner } -func NewBackend(ctx Context, utxos common.ChainUTXOs, subnetTxs map[ids.ID]*txs.Tx) Backend { +func NewBackend(ctx backends.Context, utxos common.ChainUTXOs, subnetTxs map[ids.ID]*txs.Tx) Backend { subnetOwner := make(map[ids.ID]fx.Owner) for txID, tx := range subnetTxs { // first get owners from the CreateSubnetTx createSubnetTx, ok := tx.Unsigned.(*txs.CreateSubnetTx) diff --git a/wallet/chain/p/backend_visitor.go b/wallet/chain/p/backend_visitor.go index d8b118fa21b7..afbaad3a09a8 100644 --- a/wallet/chain/p/backend_visitor.go +++ b/wallet/chain/p/backend_visitor.go @@ -8,6 +8,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" stdcontext "context" ) @@ -22,11 +23,11 @@ type backendVisitor struct { } func (*backendVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - return errUnsupportedTxType + return backends.ErrUnsupportedTxType } func (*backendVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { - return errUnsupportedTxType + return backends.ErrUnsupportedTxType } func (b *backendVisitor) AddValidatorTx(tx *txs.AddValidatorTx) error { diff --git a/wallet/chain/p/backends/backends.go b/wallet/chain/p/backends/backends.go new file mode 100644 index 000000000000..77caac1a94ab --- /dev/null +++ b/wallet/chain/p/backends/backends.go @@ -0,0 +1,35 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package backends + +import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" + + stdcontext "context" +) + +var ( + _ BuilderBackend = Backend(nil) + _ SignerBackend = Backend(nil) +) + +type Backend interface { + Context + UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) + GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) + GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +} + +type SignerBackend interface { + GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) + GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) +} + +type BuilderBackend interface { + Context + UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) + GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) +} diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/backends/builder.go similarity index 98% rename from wallet/chain/p/builder.go rename to wallet/chain/p/backends/builder.go index 85f9b6111010..b82a91cc4bf3 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/backends/builder.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package p +package backends import ( "errors" @@ -14,21 +14,18 @@ import ( "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" - "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" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - - stdcontext "context" ) var ( errNoChangeAddress = errors.New("no possible change address") errUnknownOwnerType = errors.New("unknown owner type") errInsufficientAuthorization = errors.New("insufficient authorization") - errInsufficientFunds = errors.New("insufficient funds") + ErrInsufficientFunds = errors.New("insufficient funds") _ Builder = (*builder)(nil) ) @@ -256,14 +253,6 @@ type Builder interface { ) (*txs.AddPermissionlessDelegatorTx, error) } -// BuilderBackend specifies the required information needed to build unsigned -// P-chain transactions. -type BuilderBackend interface { - Context - UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) - GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) -} - type builder struct { addrs set.Set[ids.ShortID] backend BuilderBackend @@ -635,7 +624,7 @@ func (b *builder) NewImportTx( if len(importedInputs) == 0 { return nil, fmt.Errorf( "%w: no UTXOs available to import", - errInsufficientFunds, + ErrInsufficientFunds, ) } @@ -900,7 +889,7 @@ func (b *builder) getBalance( out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, errUnknownOutputType + return nil, ErrUnknownOutputType } _, ok = common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) @@ -982,7 +971,7 @@ func (b *builder) spend( out, ok := lockedOut.TransferableOut.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, errUnknownOutputType + return nil, nil, nil, ErrUnknownOutputType } inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) @@ -1063,7 +1052,7 @@ func (b *builder) spend( out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, nil, nil, errUnknownOutputType + return nil, nil, nil, ErrUnknownOutputType } inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) @@ -1123,7 +1112,7 @@ func (b *builder) spend( if amount != 0 { return nil, nil, nil, fmt.Errorf( "%w: provided UTXOs need %d more units of asset %q to stake", - errInsufficientFunds, + ErrInsufficientFunds, amount, assetID, ) @@ -1133,7 +1122,7 @@ func (b *builder) spend( if amount != 0 { return nil, nil, nil, fmt.Errorf( "%w: provided UTXOs need %d more units of asset %q", - errInsufficientFunds, + ErrInsufficientFunds, amount, assetID, ) @@ -1173,7 +1162,7 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se } func (b *builder) initCtx(tx txs.UnsignedTx) error { - ctx, err := newSnowContext(b.backend) + ctx, err := NewSnowContext(b.backend.NetworkID(), b.backend.AVAXAssetID()) if err != nil { return err } diff --git a/wallet/chain/p/backends/context.go b/wallet/chain/p/backends/context.go new file mode 100644 index 000000000000..788d9fb4bcf5 --- /dev/null +++ b/wallet/chain/p/backends/context.go @@ -0,0 +1,119 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package backends + +import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" +) + +const Alias = "P" + +var _ Context = (*builderCtx)(nil) + +type Context interface { + NetworkID() uint32 + AVAXAssetID() ids.ID + BaseTxFee() uint64 + CreateSubnetTxFee() uint64 + TransformSubnetTxFee() uint64 + CreateBlockchainTxFee() uint64 + AddPrimaryNetworkValidatorFee() uint64 + AddPrimaryNetworkDelegatorFee() uint64 + AddSubnetValidatorFee() uint64 + AddSubnetDelegatorFee() uint64 +} + +type builderCtx struct { + networkID uint32 + avaxAssetID ids.ID + baseTxFee uint64 + createSubnetTxFee uint64 + transformSubnetTxFee uint64 + createBlockchainTxFee uint64 + addPrimaryNetworkValidatorFee uint64 + addPrimaryNetworkDelegatorFee uint64 + addSubnetValidatorFee uint64 + addSubnetDelegatorFee uint64 +} + +func NewContext( + networkID uint32, + avaxAssetID ids.ID, + baseTxFee uint64, + createSubnetTxFee uint64, + transformSubnetTxFee uint64, + createBlockchainTxFee uint64, + addPrimaryNetworkValidatorFee uint64, + addPrimaryNetworkDelegatorFee uint64, + addSubnetValidatorFee uint64, + addSubnetDelegatorFee uint64, +) Context { + return &builderCtx{ + networkID: networkID, + avaxAssetID: avaxAssetID, + baseTxFee: baseTxFee, + createSubnetTxFee: createSubnetTxFee, + transformSubnetTxFee: transformSubnetTxFee, + createBlockchainTxFee: createBlockchainTxFee, + addPrimaryNetworkValidatorFee: addPrimaryNetworkValidatorFee, + addPrimaryNetworkDelegatorFee: addPrimaryNetworkDelegatorFee, + addSubnetValidatorFee: addSubnetValidatorFee, + addSubnetDelegatorFee: addSubnetDelegatorFee, + } +} + +func (c *builderCtx) NetworkID() uint32 { + return c.networkID +} + +func (c *builderCtx) AVAXAssetID() ids.ID { + return c.avaxAssetID +} + +func (c *builderCtx) BaseTxFee() uint64 { + return c.baseTxFee +} + +func (c *builderCtx) CreateSubnetTxFee() uint64 { + return c.createSubnetTxFee +} + +func (c *builderCtx) TransformSubnetTxFee() uint64 { + return c.transformSubnetTxFee +} + +func (c *builderCtx) CreateBlockchainTxFee() uint64 { + return c.createBlockchainTxFee +} + +func (c *builderCtx) AddPrimaryNetworkValidatorFee() uint64 { + return c.addPrimaryNetworkValidatorFee +} + +func (c *builderCtx) AddPrimaryNetworkDelegatorFee() uint64 { + return c.addPrimaryNetworkDelegatorFee +} + +func (c *builderCtx) AddSubnetValidatorFee() uint64 { + return c.addSubnetValidatorFee +} + +func (c *builderCtx) AddSubnetDelegatorFee() uint64 { + return c.addSubnetDelegatorFee +} + +func NewSnowContext(networkID uint32, avaxAssetID ids.ID) (*snow.Context, error) { + lookup := ids.NewAliaser() + return &snow.Context{ + NetworkID: networkID, + SubnetID: constants.PrimaryNetworkID, + ChainID: constants.PlatformChainID, + AVAXAssetID: avaxAssetID, + Log: logging.NoLog{}, + BCLookup: lookup, + }, lookup.Alias(constants.PlatformChainID, Alias) +} diff --git a/wallet/chain/p/signer.go b/wallet/chain/p/backends/signer.go similarity index 78% rename from wallet/chain/p/signer.go rename to wallet/chain/p/backends/signer.go index bedbbdbf562a..6b99cba60cf5 100644 --- a/wallet/chain/p/signer.go +++ b/wallet/chain/p/backends/signer.go @@ -1,13 +1,10 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package p +package backends import ( - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/keychain" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/txs" stdcontext "context" @@ -27,11 +24,6 @@ type Signer interface { Sign(ctx stdcontext.Context, tx *txs.Tx) error } -type SignerBackend interface { - GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) - GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) -} - type txSigner struct { kc keychain.Keychain backend SignerBackend diff --git a/wallet/chain/p/signer_visitor.go b/wallet/chain/p/backends/signer_visitor.go similarity index 96% rename from wallet/chain/p/signer_visitor.go rename to wallet/chain/p/backends/signer_visitor.go index 7c9dd4cb95ca..5a237cfc499c 100644 --- a/wallet/chain/p/signer_visitor.go +++ b/wallet/chain/p/backends/signer_visitor.go @@ -1,9 +1,10 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package p +package backends import ( + "context" "errors" "fmt" @@ -18,17 +19,16 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - - stdcontext "context" ) var ( _ txs.Visitor = (*signerVisitor)(nil) - errUnsupportedTxType = errors.New("unsupported tx type") + ErrUnknownOwnerType = errors.New("unknown owner type") + ErrUnknownOutputType = errors.New("unknown output type") + ErrUnsupportedTxType = errors.New("unsupported tx type") errUnknownInputType = errors.New("unknown input type") errUnknownCredentialType = errors.New("unknown credential type") - errUnknownOutputType = errors.New("unknown output type") errUnknownSubnetAuthType = errors.New("unknown subnet auth type") errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") @@ -39,16 +39,16 @@ var ( type signerVisitor struct { kc keychain.Keychain backend SignerBackend - ctx stdcontext.Context + ctx context.Context tx *txs.Tx } func (*signerVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - return errUnsupportedTxType + return ErrUnsupportedTxType } func (*signerVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { - return errUnsupportedTxType + return ErrUnsupportedTxType } func (s *signerVisitor) BaseTx(tx *txs.BaseTx) error { @@ -219,7 +219,7 @@ func (s *signerVisitor) getSigners(sourceChainID ids.ID, ins []*avax.Transferabl out, ok := outIntf.(*secp256k1fx.TransferOutput) if !ok { - return nil, errUnknownOutputType + return nil, ErrUnknownOutputType } for sigIndex, addrIndex := range input.SigIndices { @@ -256,7 +256,7 @@ func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Veri } owner, ok := ownerIntf.(*secp256k1fx.OutputOwners) if !ok { - return nil, errUnknownOwnerType + return nil, ErrUnknownOwnerType } authSigners := make([]keychain.Signer, len(subnetInput.SigIndices)) diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 473103147549..6f31a0af12bf 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -32,7 +33,7 @@ var ( avaxAssetID = ids.Empty.Prefix(1789) subnetAssetID = ids.Empty.Prefix(2024) - testCtx = NewContext( + testCtx = backends.NewContext( constants.UnitTestID, avaxAssetID, units.MicroAvax, // BaseTxFee @@ -63,7 +64,7 @@ func TestBaseTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr), backend) // data to build the transaction outputsToMove = []*avax.TransferableOutput{{ @@ -123,7 +124,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) // data to build the transaction subnetValidator = &txs.SubnetValidator{ @@ -180,7 +181,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) ) // build the transaction @@ -230,7 +231,7 @@ func TestCreateChainTx(t *testing.T) { backend = NewBackend(testCtx, chainUTXOs, subnets) utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) // data to build the transaction genesisBytes = []byte{'a', 'b', 'c'} @@ -290,7 +291,7 @@ func TestCreateSubnetTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) ) // build the transaction @@ -338,7 +339,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) ) // build the transaction @@ -377,7 +378,7 @@ func TestImportTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr), backend) // data to build the transaction importKey = testKeys[0] @@ -423,7 +424,7 @@ func TestExportTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr), backend) // data to build the transaction subnetID = ids.GenerateTestID() @@ -488,7 +489,7 @@ func TestTransformSubnetTx(t *testing.T) { // builder utxoAddr = utxosKey.Address() - builder = NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) // data to build the transaction initialSupply = 40 * units.MegaAvax @@ -544,7 +545,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { utxoAddr = utxosKey.Address() rewardKey = testKeys[0] rewardAddr = rewardKey.Address() - builder = NewBuilder(set.Of(utxoAddr, rewardAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, rewardAddr), backend) // data to build the transaction validationRewardsOwner = &secp256k1fx.OutputOwners{ @@ -614,7 +615,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { utxoAddr = utxosKey.Address() rewardKey = testKeys[0] rewardAddr = rewardKey.Address() - builder = NewBuilder(set.Of(utxoAddr, rewardAddr), backend) + builder = backends.NewBuilder(set.Of(utxoAddr, rewardAddr), backend) // data to build the transaction rewardsOwner = &secp256k1fx.OutputOwners{ diff --git a/wallet/chain/p/builder_with_options.go b/wallet/chain/p/builder_with_options.go index a402355b9e01..7bfaf0046308 100644 --- a/wallet/chain/p/builder_with_options.go +++ b/wallet/chain/p/builder_with_options.go @@ -11,13 +11,14 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) -var _ Builder = (*builderWithOptions)(nil) +var _ backends.Builder = (*builderWithOptions)(nil) type builderWithOptions struct { - Builder + backends.Builder options []common.Option } @@ -28,7 +29,7 @@ type builderWithOptions struct { // operations. // - [options] will be provided to the builder in addition to the options // provided in the method calls. -func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { +func NewBuilderWithOptions(builder backends.Builder, options ...common.Option) backends.Builder { return &builderWithOptions{ Builder: builder, options: options, diff --git a/wallet/chain/p/context.go b/wallet/chain/p/context.go index 2511a19a9dbf..862e2364525a 100644 --- a/wallet/chain/p/context.go +++ b/wallet/chain/p/context.go @@ -5,46 +5,13 @@ package p import ( "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" - "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/wallet/chain/p/backends" stdcontext "context" ) -const Alias = "P" - -var _ Context = (*context)(nil) - -type Context interface { - NetworkID() uint32 - AVAXAssetID() ids.ID - BaseTxFee() uint64 - CreateSubnetTxFee() uint64 - TransformSubnetTxFee() uint64 - CreateBlockchainTxFee() uint64 - AddPrimaryNetworkValidatorFee() uint64 - AddPrimaryNetworkDelegatorFee() uint64 - AddSubnetValidatorFee() uint64 - AddSubnetDelegatorFee() uint64 -} - -type context struct { - networkID uint32 - avaxAssetID ids.ID - baseTxFee uint64 - createSubnetTxFee uint64 - transformSubnetTxFee uint64 - createBlockchainTxFee uint64 - addPrimaryNetworkValidatorFee uint64 - addPrimaryNetworkDelegatorFee uint64 - addSubnetValidatorFee uint64 - addSubnetDelegatorFee uint64 -} - -func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { +func NewContextFromURI(ctx stdcontext.Context, uri string) (backends.Context, error) { infoClient := info.NewClient(uri) xChainClient := avm.NewClient(uri, "X") return NewContextFromClients(ctx, infoClient, xChainClient) @@ -54,7 +21,7 @@ func NewContextFromClients( ctx stdcontext.Context, infoClient info.Client, xChainClient avm.Client, -) (Context, error) { +) (backends.Context, error) { networkID, err := infoClient.GetNetworkID(ctx) if err != nil { return nil, err @@ -70,7 +37,7 @@ func NewContextFromClients( return nil, err } - return NewContext( + return backends.NewContext( networkID, asset.AssetID, uint64(txFees.TxFee), @@ -83,81 +50,3 @@ func NewContextFromClients( uint64(txFees.AddSubnetDelegatorFee), ), nil } - -func NewContext( - networkID uint32, - avaxAssetID ids.ID, - baseTxFee uint64, - createSubnetTxFee uint64, - transformSubnetTxFee uint64, - createBlockchainTxFee uint64, - addPrimaryNetworkValidatorFee uint64, - addPrimaryNetworkDelegatorFee uint64, - addSubnetValidatorFee uint64, - addSubnetDelegatorFee uint64, -) Context { - return &context{ - networkID: networkID, - avaxAssetID: avaxAssetID, - baseTxFee: baseTxFee, - createSubnetTxFee: createSubnetTxFee, - transformSubnetTxFee: transformSubnetTxFee, - createBlockchainTxFee: createBlockchainTxFee, - addPrimaryNetworkValidatorFee: addPrimaryNetworkValidatorFee, - addPrimaryNetworkDelegatorFee: addPrimaryNetworkDelegatorFee, - addSubnetValidatorFee: addSubnetValidatorFee, - addSubnetDelegatorFee: addSubnetDelegatorFee, - } -} - -func (c *context) NetworkID() uint32 { - return c.networkID -} - -func (c *context) AVAXAssetID() ids.ID { - return c.avaxAssetID -} - -func (c *context) BaseTxFee() uint64 { - return c.baseTxFee -} - -func (c *context) CreateSubnetTxFee() uint64 { - return c.createSubnetTxFee -} - -func (c *context) TransformSubnetTxFee() uint64 { - return c.transformSubnetTxFee -} - -func (c *context) CreateBlockchainTxFee() uint64 { - return c.createBlockchainTxFee -} - -func (c *context) AddPrimaryNetworkValidatorFee() uint64 { - return c.addPrimaryNetworkValidatorFee -} - -func (c *context) AddPrimaryNetworkDelegatorFee() uint64 { - return c.addPrimaryNetworkDelegatorFee -} - -func (c *context) AddSubnetValidatorFee() uint64 { - return c.addSubnetValidatorFee -} - -func (c *context) AddSubnetDelegatorFee() uint64 { - return c.addSubnetDelegatorFee -} - -func newSnowContext(c Context) (*snow.Context, error) { - lookup := ids.NewAliaser() - return &snow.Context{ - NetworkID: c.NetworkID(), - SubnetID: constants.PrimaryNetworkID, - ChainID: constants.PlatformChainID, - AVAXAssetID: c.AVAXAssetID(), - Log: logging.NoLog{}, - BCLookup: lookup, - }, lookup.Alias(constants.PlatformChainID, Alias) -} diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 44cc7e2a4da4..1fd85e8cabe1 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.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/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -25,13 +26,13 @@ var ( ) type Wallet interface { - Context + backends.Context // Builder returns the builder that will be used to create the transactions. - Builder() Builder + Builder() backends.Builder // Signer returns the signer that will be used to sign the transactions. - Signer() Signer + Signer() backends.Signer // IssueBaseTx creates, signs, and issues a new simple value transfer. // Because the P-chain doesn't intend for balance transfers to occur, this @@ -258,8 +259,8 @@ type Wallet interface { } func NewWallet( - builder Builder, - signer Signer, + builder backends.Builder, + signer backends.Signer, client platformvm.Client, backend Backend, ) Wallet { @@ -273,16 +274,16 @@ func NewWallet( type wallet struct { Backend - builder Builder - signer Signer + builder backends.Builder + signer backends.Signer client platformvm.Client } -func (w *wallet) Builder() Builder { +func (w *wallet) Builder() backends.Builder { return w.builder } -func (w *wallet) Signer() Signer { +func (w *wallet) Signer() backends.Signer { return w.signer } @@ -495,7 +496,7 @@ func (w *wallet) IssueUnsignedTx( ) (*txs.Tx, error) { ops := common.NewOptions(options) ctx := ops.Context() - tx, err := SignUnsigned(ctx, w.signer, utx) + tx, err := backends.SignUnsigned(ctx, w.signer, utx) if err != nil { return nil, err } diff --git a/wallet/chain/p/wallet_with_options.go b/wallet/chain/p/wallet_with_options.go index 4982e77f8a51..53067332dc4d 100644 --- a/wallet/chain/p/wallet_with_options.go +++ b/wallet/chain/p/wallet_with_options.go @@ -11,6 +11,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -31,7 +32,7 @@ type walletWithOptions struct { options []common.Option } -func (w *walletWithOptions) Builder() Builder { +func (w *walletWithOptions) Builder() backends.Builder { return NewBuilderWithOptions( w.Wallet.Builder(), w.options..., diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 3c30b60d81c2..0e559affc45e 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -22,6 +22,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" + "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/chain/x" walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -57,7 +58,7 @@ type UTXOClient interface { type AVAXState struct { PClient platformvm.Client - PCTX p.Context + PCTX backends.Context XClient avm.Client XCTX x.Context CClient evm.Client diff --git a/wallet/subnet/primary/examples/get-p-chain-balance/main.go b/wallet/subnet/primary/examples/get-p-chain-balance/main.go index 08f2cd538c29..df8d0bdf62d1 100644 --- a/wallet/subnet/primary/examples/get-p-chain-balance/main.go +++ b/wallet/subnet/primary/examples/get-p-chain-balance/main.go @@ -14,6 +14,8 @@ import ( "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/subnet/primary" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + pbackends "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) func main() { @@ -38,7 +40,7 @@ func main() { pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, state.UTXOs) pBackend := p.NewBackend(state.PCTX, pUTXOs, nil) - pBuilder := p.NewBuilder(addresses, pBackend) + pBuilder := pbackends.NewBuilder(addresses, pBackend) currentBalances, err := pBuilder.GetBalance() if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 9aabf651cff7..47777eb25d1b 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -15,6 +15,8 @@ import ( "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + pbackends "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) var _ Wallet = (*wallet)(nil) @@ -118,8 +120,8 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, avaxState.UTXOs) pBackend := p.NewBackend(avaxState.PCTX, pUTXOs, pChainTxs) - pBuilder := p.NewBuilder(avaxAddrs, pBackend) - pSigner := p.NewSigner(config.AVAXKeychain, pBackend) + pBuilder := pbackends.NewBuilder(avaxAddrs, pBackend) + pSigner := pbackends.NewSigner(config.AVAXKeychain, pBackend) xChainID := avaxState.XCTX.BlockchainID() xUTXOs := common.NewChainUTXOs(xChainID, avaxState.UTXOs) From 480fb45f72483c13b4e2b5f0121c415956e8987e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 14:05:48 +0100 Subject: [PATCH 044/120] consolidated backend implementation --- .../{builder_backend.go => backend.go} | 33 +++-- vms/platformvm/txs/builder/builder.go | 117 ++++++------------ vms/platformvm/txs/builder/signer_backend.go | 55 -------- .../txs/executor/create_chain_test.go | 9 +- .../txs/executor/create_subnet_test.go | 9 +- 5 files changed, 71 insertions(+), 152 deletions(-) rename vms/platformvm/txs/builder/{builder_backend.go => backend.go} (65%) delete mode 100644 vms/platformvm/txs/builder/signer_backend.go diff --git a/vms/platformvm/txs/builder/builder_backend.go b/vms/platformvm/txs/builder/backend.go similarity index 65% rename from vms/platformvm/txs/builder/builder_backend.go rename to vms/platformvm/txs/builder/backend.go index 14ecd83d4d4f..b21952543c9e 100644 --- a/vms/platformvm/txs/builder/builder_backend.go +++ b/vms/platformvm/txs/builder/backend.go @@ -5,7 +5,9 @@ package builder import ( "context" + "fmt" + "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/constants" @@ -17,15 +19,15 @@ import ( "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) -var _ backends.BuilderBackend = (*buiderBackend)(nil) +var _ backends.Backend = (*backend)(nil) -func NewBuilderBackend( +func NewBackend( ctx *snow.Context, cfg *config.Config, addrs set.Set[ids.ShortID], state state.State, atomicUTXOsMan avax.AtomicUTXOManager, -) backends.BuilderBackend { +) backends.Backend { backendCtx := backends.NewContext( ctx.NetworkID, ctx.AVAXAssetID, @@ -38,7 +40,7 @@ func NewBuilderBackend( cfg.AddSubnetValidatorFee, cfg.AddSubnetDelegatorFee, ) - return &buiderBackend{ + return &backend{ Context: backendCtx, addrs: addrs, state: state, @@ -46,7 +48,7 @@ func NewBuilderBackend( } } -type buiderBackend struct { +type backend struct { backends.Context addrs set.Set[ids.ShortID] @@ -54,7 +56,7 @@ type buiderBackend struct { atomicUTXOsMan avax.AtomicUTXOManager } -func (b *buiderBackend) UTXOs(_ context.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) { +func (b *backend) UTXOs(_ context.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) { if sourceChainID == constants.PlatformChainID { return avax.GetAllUTXOs(b.state, b.addrs) // The UTXOs controlled by [keys] } @@ -63,6 +65,23 @@ func (b *buiderBackend) UTXOs(_ context.Context, sourceChainID ids.ID) ([]*avax. return atomicUTXOs, err } -func (b *buiderBackend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { +func (b *backend) GetUTXO(_ context.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) { + if chainID == constants.PlatformChainID { + return b.state.GetUTXO(utxoID) + } + + atomicUTXOs, _, _, err := b.atomicUTXOsMan.GetAtomicUTXOs(chainID, b.addrs, ids.ShortEmpty, ids.Empty, MaxPageSize) + if err != nil { + return nil, fmt.Errorf("problem retrieving atomic UTXOs: %w", err) + } + for _, utxo := range atomicUTXOs { + if utxo.InputID() == utxoID { + return utxo, nil + } + } + return nil, database.ErrNotFound +} + +func (b *backend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { return b.state.GetSubnetOwner(subnetID) } diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index d105ce4ebf8a..9a7e6b5dea1a 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -283,8 +283,8 @@ func (b *builder) NewImportTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) outOwner := &secp256k1fx.OutputOwners{ Locktime: 0, @@ -302,10 +302,7 @@ func (b *builder) NewImportTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -326,8 +323,8 @@ func (b *builder) NewExportTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) outputs := []*avax.TransferableOutput{{ Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, @@ -351,10 +348,7 @@ func (b *builder) NewExportTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -376,8 +370,8 @@ func (b *builder) NewCreateChainTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) utx, err := pBuilder.NewCreateChainTx(subnetID, genesisData, vmID, fxIDs, chainName, options(changeAddr, memo)...) if err != nil { @@ -385,10 +379,7 @@ func (b *builder) NewCreateChainTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -407,8 +398,8 @@ func (b *builder) NewCreateSubnetTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) subnetOwner := &secp256k1fx.OutputOwners{ Threshold: threshold, @@ -421,10 +412,7 @@ func (b *builder) NewCreateSubnetTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -455,8 +443,8 @@ func (b *builder) NewTransformSubnetTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) utx, err := pBuilder.NewTransformSubnetTx( subnetID, @@ -480,10 +468,7 @@ func (b *builder) NewTransformSubnetTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -506,8 +491,8 @@ func (b *builder) NewAddValidatorTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) vdr := &txs.Validator{ NodeID: nodeID, @@ -527,10 +512,7 @@ func (b *builder) NewAddValidatorTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -554,8 +536,8 @@ func (b *builder) NewAddPermissionlessValidatorTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) vdr := &txs.SubnetValidator{ Validator: txs.Validator{ @@ -586,10 +568,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -611,8 +590,8 @@ func (b *builder) NewAddDelegatorTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) vdr := &txs.Validator{ NodeID: nodeID, @@ -636,10 +615,7 @@ func (b *builder) NewAddDelegatorTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -661,8 +637,8 @@ func (b *builder) NewAddPermissionlessDelegatorTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) vdr := &txs.SubnetValidator{ Validator: txs.Validator{ @@ -690,10 +666,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -715,8 +688,8 @@ func (b *builder) NewAddSubnetValidatorTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) vdr := &txs.SubnetValidator{ Validator: txs.Validator{ @@ -737,10 +710,7 @@ func (b *builder) NewAddSubnetValidatorTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -759,8 +729,8 @@ func (b *builder) NewRemoveSubnetValidatorTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) utx, err := pBuilder.NewRemoveSubnetValidatorTx( nodeID, @@ -772,10 +742,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -795,8 +762,8 @@ func (b *builder) NewTransferSubnetOwnershipTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) newOwner := &secp256k1fx.OutputOwners{ Threshold: threshold, @@ -813,10 +780,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -835,8 +799,8 @@ func (b *builder) NewBaseTx( for _, key := range keys { addrs.Add(key.Address()) } - builderBackend := NewBuilderBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) + pBuilder := backends.NewBuilder(addrs, backend) out := &avax.TransferableOutput{ Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, @@ -855,10 +819,7 @@ func (b *builder) NewBaseTx( } kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner( - kc, - NewSignerBackend(b.state, b.AtomicUTXOManager, addrs), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err diff --git a/vms/platformvm/txs/builder/signer_backend.go b/vms/platformvm/txs/builder/signer_backend.go deleted file mode 100644 index 79d396c5bb25..000000000000 --- a/vms/platformvm/txs/builder/signer_backend.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package builder - -import ( - "context" - "fmt" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/fx" - "github.com/ava-labs/avalanchego/vms/platformvm/state" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" -) - -var _ backends.SignerBackend = (*signerBackend)(nil) - -func NewSignerBackend(state state.State, atomicUTXOManager avax.AtomicUTXOManager, addrs set.Set[ids.ShortID]) backends.SignerBackend { - return &signerBackend{ - state: state, - atomicUTXOManager: atomicUTXOManager, - addrs: addrs, - } -} - -type signerBackend struct { - state state.State - atomicUTXOManager avax.AtomicUTXOManager - addrs set.Set[ids.ShortID] -} - -func (s *signerBackend) GetUTXO(_ context.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) { - if chainID == constants.PlatformChainID { - return s.state.GetUTXO(utxoID) - } - - atomicUTXOs, _, _, err := s.atomicUTXOManager.GetAtomicUTXOs(chainID, s.addrs, ids.ShortEmpty, ids.Empty, MaxPageSize) - if err != nil { - return nil, fmt.Errorf("problem retrieving atomic UTXOs: %w", err) - } - for _, utxo := range atomicUTXOs { - if utxo.InputID() == utxoID { - return utxo, nil - } - } - return nil, database.ErrNotFound -} - -func (s *signerBackend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { - return s.state.GetSubnetOwner(subnetID) -} diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 9d611e69e052..2c918477f354 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -204,8 +204,8 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateBlockchainTxFee = test.fee - builderBackend := builder.NewBuilderBackend(env.ctx, &cfg, addrs, env.state, env.atomicUTXOs) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := builder.NewBackend(env.ctx, &cfg, addrs, env.state, env.atomicUTXOs) + pBuilder := backends.NewBuilder(addrs, backend) utx, err := pBuilder.NewCreateChainTx( testSubnet1.ID(), @@ -217,10 +217,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { require.NoError(err) kc := secp256k1fx.NewKeychain(preFundedKeys...) - s := backends.NewSigner( - kc, - builder.NewSignerBackend(env.state, env.atomicUTXOs, kc.Addresses()), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) require.NoError(err) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index d9b7a3f2964e..57595cda23e5 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -65,8 +65,8 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateSubnetTxFee = test.fee - builderBackend := builder.NewBuilderBackend(env.ctx, &cfg, addrs, env.state, env.atomicUTXOs) - pBuilder := backends.NewBuilder(addrs, builderBackend) + backend := builder.NewBackend(env.ctx, &cfg, addrs, env.state, env.atomicUTXOs) + pBuilder := backends.NewBuilder(addrs, backend) utx, err := pBuilder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{}, // owner @@ -74,10 +74,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { require.NoError(err) kc := secp256k1fx.NewKeychain(preFundedKeys...) - s := backends.NewSigner( - kc, - builder.NewSignerBackend(env.state, env.atomicUTXOs, kc.Addresses()), - ) + s := backends.NewSigner(kc, backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) require.NoError(err) From 30498e7e2cca7ab45b13a1956cf8fa1d5ab7c48b Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 14:57:01 +0100 Subject: [PATCH 045/120] some more cleanup --- vms/platformvm/block/executor/helpers_test.go | 2 + vms/platformvm/txs/builder/backend.go | 29 ++- vms/platformvm/txs/builder/builder.go | 209 ++++++++---------- .../txs/executor/create_chain_test.go | 3 +- .../txs/executor/create_subnet_test.go | 3 +- 5 files changed, 120 insertions(+), 126 deletions(-) diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 3c3ccf1474e7..a1f44504a33d 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -168,6 +168,8 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment res.mockedState = state.NewMockState(ctrl) res.uptimes = uptime.NewManager(res.mockedState, res.clk) res.utxosHandler = utxo.NewVerifier(res.ctx, res.clk, res.fx) + + res.mockedState.EXPECT().GetTimestamp().Return(time.Time{}).Times(1) // to initialize createSubnetTx fee res.txBuilder = p_tx_builder.New( res.ctx, res.config, diff --git a/vms/platformvm/txs/builder/backend.go b/vms/platformvm/txs/builder/backend.go index b21952543c9e..bb7c36b5ab4a 100644 --- a/vms/platformvm/txs/builder/backend.go +++ b/vms/platformvm/txs/builder/backend.go @@ -19,15 +19,14 @@ import ( "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) -var _ backends.Backend = (*backend)(nil) +var _ backends.Backend = (*Backend)(nil) func NewBackend( ctx *snow.Context, cfg *config.Config, - addrs set.Set[ids.ShortID], state state.State, atomicUTXOsMan avax.AtomicUTXOManager, -) backends.Backend { +) *Backend { backendCtx := backends.NewContext( ctx.NetworkID, ctx.AVAXAssetID, @@ -40,32 +39,42 @@ func NewBackend( cfg.AddSubnetValidatorFee, cfg.AddSubnetDelegatorFee, ) - return &backend{ + return &Backend{ Context: backendCtx, - addrs: addrs, + cfg: cfg, state: state, atomicUTXOsMan: atomicUTXOsMan, } } -type backend struct { +type Backend struct { backends.Context + cfg *config.Config addrs set.Set[ids.ShortID] state state.State atomicUTXOsMan avax.AtomicUTXOManager } -func (b *backend) UTXOs(_ context.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) { +// Override [backend.Context.CreateSubnetTxFee] to refresh fee +func (b *Backend) CreateSubnetTxFee() uint64 { + return b.cfg.GetCreateSubnetTxFee(b.state.GetTimestamp()) +} + +func (b *Backend) ResetAddresses(addrs set.Set[ids.ShortID]) { + b.addrs = addrs +} + +func (b *Backend) UTXOs(_ context.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) { if sourceChainID == constants.PlatformChainID { - return avax.GetAllUTXOs(b.state, b.addrs) // The UTXOs controlled by [keys] + return avax.GetAllUTXOs(b.state, b.addrs) } atomicUTXOs, _, _, err := b.atomicUTXOsMan.GetAtomicUTXOs(sourceChainID, b.addrs, ids.ShortEmpty, ids.Empty, MaxPageSize) return atomicUTXOs, err } -func (b *backend) GetUTXO(_ context.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) { +func (b *Backend) GetUTXO(_ context.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) { if chainID == constants.PlatformChainID { return b.state.GetUTXO(utxoID) } @@ -82,6 +91,6 @@ func (b *backend) GetUTXO(_ context.Context, chainID, utxoID ids.ID) (*avax.UTXO return nil, database.ErrNotFound } -func (b *backend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { +func (b *Backend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { return b.state.GetSubnetOwner(subnetID) } diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 9a7e6b5dea1a..e0b7dd1b19b2 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -12,7 +12,6 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/signer" @@ -257,19 +256,14 @@ func New( atomicUTXOManager avax.AtomicUTXOManager, ) Builder { return &builder{ - AtomicUTXOManager: atomicUTXOManager, - state: state, - cfg: cfg, - ctx: ctx, + ctx: ctx, + backend: NewBackend(ctx, cfg, state, atomicUTXOManager), } } type builder struct { - avax.AtomicUTXOManager - state state.State - - cfg *config.Config - ctx *snow.Context + ctx *snow.Context + backend *Backend } func (b *builder) NewImportTx( @@ -279,12 +273,12 @@ func (b *builder) NewImportTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) outOwner := &secp256k1fx.OutputOwners{ Locktime: 0, @@ -301,8 +295,7 @@ func (b *builder) NewImportTx( return nil, fmt.Errorf("failed building import tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -319,12 +312,12 @@ func (b *builder) NewExportTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) outputs := []*avax.TransferableOutput{{ Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, @@ -347,8 +340,7 @@ func (b *builder) NewExportTx( return nil, fmt.Errorf("failed building export tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -366,20 +358,19 @@ func (b *builder) NewCreateChainTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) utx, err := pBuilder.NewCreateChainTx(subnetID, genesisData, vmID, fxIDs, chainName, options(changeAddr, memo)...) if err != nil { return nil, fmt.Errorf("failed building create chain tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -394,12 +385,12 @@ func (b *builder) NewCreateSubnetTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) subnetOwner := &secp256k1fx.OutputOwners{ Threshold: threshold, @@ -411,8 +402,7 @@ func (b *builder) NewCreateSubnetTx( return nil, fmt.Errorf("failed building create subnet tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -439,12 +429,12 @@ func (b *builder) NewTransformSubnetTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) utx, err := pBuilder.NewTransformSubnetTx( subnetID, @@ -467,8 +457,7 @@ func (b *builder) NewTransformSubnetTx( return nil, fmt.Errorf("failed building transform subnet tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -487,12 +476,12 @@ func (b *builder) NewAddValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) vdr := &txs.Validator{ NodeID: nodeID, @@ -511,8 +500,7 @@ func (b *builder) NewAddValidatorTx( return nil, fmt.Errorf("failed building add validator tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -532,12 +520,12 @@ func (b *builder) NewAddPermissionlessValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) vdr := &txs.SubnetValidator{ Validator: txs.Validator{ @@ -567,8 +555,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( return nil, fmt.Errorf("failed building add permissionless validator tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -586,12 +573,12 @@ func (b *builder) NewAddDelegatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) vdr := &txs.Validator{ NodeID: nodeID, @@ -614,8 +601,7 @@ func (b *builder) NewAddDelegatorTx( return nil, fmt.Errorf("failed building add delegator tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -633,12 +619,12 @@ func (b *builder) NewAddPermissionlessDelegatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) vdr := &txs.SubnetValidator{ Validator: txs.Validator{ @@ -665,8 +651,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( return nil, fmt.Errorf("failed building add permissionless delegator tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -684,12 +669,12 @@ func (b *builder) NewAddSubnetValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) vdr := &txs.SubnetValidator{ Validator: txs.Validator{ @@ -709,8 +694,7 @@ func (b *builder) NewAddSubnetValidatorTx( return nil, fmt.Errorf("failed building add subnet validator tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -725,12 +709,12 @@ func (b *builder) NewRemoveSubnetValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) utx, err := pBuilder.NewRemoveSubnetValidatorTx( nodeID, @@ -741,8 +725,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( return nil, fmt.Errorf("failed building remove subnet validator tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -758,12 +741,12 @@ func (b *builder) NewTransferSubnetOwnershipTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) newOwner := &secp256k1fx.OutputOwners{ Threshold: threshold, @@ -779,8 +762,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( return nil, fmt.Errorf("failed building transfer subnet ownership tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err @@ -795,12 +777,12 @@ func (b *builder) NewBaseTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - addrs := set.NewSet[ids.ShortID](len(keys)) - for _, key := range keys { - addrs.Add(key.Address()) - } - backend := NewBackend(b.ctx, b.cfg, addrs, b.state, b.AtomicUTXOManager) - pBuilder := backends.NewBuilder(addrs, backend) + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + pBuilder = backends.NewBuilder(addrs, b.backend) + ) + b.backend.ResetAddresses(addrs) out := &avax.TransferableOutput{ Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, @@ -818,8 +800,7 @@ func (b *builder) NewBaseTx( return nil, fmt.Errorf("failed building base tx: %w", err) } - kc := secp256k1fx.NewKeychain(keys...) - s := backends.NewSigner(kc, backend) + s := backends.NewSigner(kc, b.backend) tx, err := backends.SignUnsigned(context.Background(), s, utx) if err != nil { return nil, err diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 2c918477f354..f04516faf7b5 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -204,7 +204,8 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateBlockchainTxFee = test.fee - backend := builder.NewBackend(env.ctx, &cfg, addrs, env.state, env.atomicUTXOs) + backend := builder.NewBackend(env.ctx, &cfg, env.state, env.atomicUTXOs) + backend.ResetAddresses(addrs) pBuilder := backends.NewBuilder(addrs, backend) utx, err := pBuilder.NewCreateChainTx( diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 57595cda23e5..2b5396f432a7 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -65,7 +65,8 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateSubnetTxFee = test.fee - backend := builder.NewBackend(env.ctx, &cfg, addrs, env.state, env.atomicUTXOs) + backend := builder.NewBackend(env.ctx, &cfg, env.state, env.atomicUTXOs) + backend.ResetAddresses(addrs) pBuilder := backends.NewBuilder(addrs, backend) utx, err := pBuilder.NewCreateSubnetTx( From 18812828bad9fb0063aa8867c5f1b8fa65823e02 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 15:02:44 +0100 Subject: [PATCH 046/120] nits --- vms/platformvm/txs/builder/builder.go | 142 +++++++------------------- 1 file changed, 38 insertions(+), 104 deletions(-) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index e0b7dd1b19b2..ea63e8f302ee 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -273,12 +273,7 @@ func (b *builder) NewImportTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) outOwner := &secp256k1fx.OutputOwners{ Locktime: 0, @@ -295,8 +290,7 @@ func (b *builder) NewImportTx( return nil, fmt.Errorf("failed building import tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -312,12 +306,7 @@ func (b *builder) NewExportTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) outputs := []*avax.TransferableOutput{{ Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, @@ -340,8 +329,7 @@ func (b *builder) NewExportTx( return nil, fmt.Errorf("failed building export tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -358,20 +346,14 @@ func (b *builder) NewCreateChainTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewCreateChainTx(subnetID, genesisData, vmID, fxIDs, chainName, options(changeAddr, memo)...) if err != nil { return nil, fmt.Errorf("failed building create chain tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -385,12 +367,7 @@ func (b *builder) NewCreateSubnetTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) subnetOwner := &secp256k1fx.OutputOwners{ Threshold: threshold, @@ -402,8 +379,7 @@ func (b *builder) NewCreateSubnetTx( return nil, fmt.Errorf("failed building create subnet tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -429,12 +405,7 @@ func (b *builder) NewTransformSubnetTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewTransformSubnetTx( subnetID, @@ -457,8 +428,7 @@ func (b *builder) NewTransformSubnetTx( return nil, fmt.Errorf("failed building transform subnet tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -476,12 +446,7 @@ func (b *builder) NewAddValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) vdr := &txs.Validator{ NodeID: nodeID, @@ -500,8 +465,7 @@ func (b *builder) NewAddValidatorTx( return nil, fmt.Errorf("failed building add validator tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -520,12 +484,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) vdr := &txs.SubnetValidator{ Validator: txs.Validator{ @@ -555,8 +514,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( return nil, fmt.Errorf("failed building add permissionless validator tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -573,12 +531,7 @@ func (b *builder) NewAddDelegatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) vdr := &txs.Validator{ NodeID: nodeID, @@ -601,8 +554,7 @@ func (b *builder) NewAddDelegatorTx( return nil, fmt.Errorf("failed building add delegator tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -619,12 +571,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) vdr := &txs.SubnetValidator{ Validator: txs.Validator{ @@ -651,8 +598,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( return nil, fmt.Errorf("failed building add permissionless delegator tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -669,12 +615,7 @@ func (b *builder) NewAddSubnetValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) vdr := &txs.SubnetValidator{ Validator: txs.Validator{ @@ -694,8 +635,7 @@ func (b *builder) NewAddSubnetValidatorTx( return nil, fmt.Errorf("failed building add subnet validator tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -709,12 +649,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewRemoveSubnetValidatorTx( nodeID, @@ -725,8 +660,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( return nil, fmt.Errorf("failed building remove subnet validator tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -741,12 +675,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) newOwner := &secp256k1fx.OutputOwners{ Threshold: threshold, @@ -762,8 +691,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( return nil, fmt.Errorf("failed building transfer subnet ownership tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -777,12 +705,7 @@ func (b *builder) NewBaseTx( changeAddr ids.ShortID, memo []byte, ) (*txs.Tx, error) { - var ( - kc = secp256k1fx.NewKeychain(keys...) - addrs = kc.Addresses() - pBuilder = backends.NewBuilder(addrs, b.backend) - ) - b.backend.ResetAddresses(addrs) + pBuilder, pSigner := b.builders(keys) out := &avax.TransferableOutput{ Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, @@ -800,14 +723,25 @@ func (b *builder) NewBaseTx( return nil, fmt.Errorf("failed building base tx: %w", err) } - s := backends.NewSigner(kc, b.backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } return tx, tx.SyntacticVerify(b.ctx) } +func (b *builder) builders(keys []*secp256k1.PrivateKey) (backends.Builder, backends.Signer) { + var ( + kc = secp256k1fx.NewKeychain(keys...) + addrs = kc.Addresses() + builder = backends.NewBuilder(addrs, b.backend) + signer = backends.NewSigner(kc, b.backend) + ) + b.backend.ResetAddresses(addrs) + + return builder, signer +} + func options(changeAddr ids.ShortID, memo []byte) []common.Option { return common.UnionOptions( []common.Option{common.WithChangeOwner(&secp256k1fx.OutputOwners{ From fca9d289082cadad9fb049e2bdd22556dfaa6dd1 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 15:21:38 +0100 Subject: [PATCH 047/120] fixed create chain tx fee --- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/txs/builder/backend.go | 9 ++++++++- vms/platformvm/txs/executor/create_chain_test.go | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index a1f44504a33d..e5674bc7cb39 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -169,7 +169,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment res.uptimes = uptime.NewManager(res.mockedState, res.clk) res.utxosHandler = utxo.NewVerifier(res.ctx, res.clk, res.fx) - res.mockedState.EXPECT().GetTimestamp().Return(time.Time{}).Times(1) // to initialize createSubnetTx fee + res.mockedState.EXPECT().GetTimestamp().Return(time.Time{}).Times(2) // to initialize createSubnet/BlockchainTx fee res.txBuilder = p_tx_builder.New( res.ctx, res.config, diff --git a/vms/platformvm/txs/builder/backend.go b/vms/platformvm/txs/builder/backend.go index bb7c36b5ab4a..be416b38de3e 100644 --- a/vms/platformvm/txs/builder/backend.go +++ b/vms/platformvm/txs/builder/backend.go @@ -33,7 +33,7 @@ func NewBackend( cfg.TxFee, cfg.GetCreateSubnetTxFee(state.GetTimestamp()), cfg.TransformSubnetTxFee, - cfg.CreateBlockchainTxFee, + cfg.GetCreateBlockchainTxFee(state.GetTimestamp()), cfg.AddPrimaryNetworkValidatorFee, cfg.AddPrimaryNetworkDelegatorFee, cfg.AddSubnetValidatorFee, @@ -57,10 +57,17 @@ type Backend struct { } // Override [backend.Context.CreateSubnetTxFee] to refresh fee +// relevant in unit tests only func (b *Backend) CreateSubnetTxFee() uint64 { return b.cfg.GetCreateSubnetTxFee(b.state.GetTimestamp()) } +// Override [backend.Context.GetCreateBlockchainTxFee] to refresh fee +// relevant in unit tests only +func (b *Backend) GetCreateBlockchainTxFee() uint64 { + return b.cfg.GetCreateBlockchainTxFee(b.state.GetTimestamp()) +} + func (b *Backend) ResetAddresses(addrs set.Set[ids.ShortID]) { b.addrs = addrs } diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index f04516faf7b5..81552b074f43 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -202,6 +202,8 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { addrs.Add(key.Address()) } + env.state.SetTimestamp(test.time) // to duly set fee + cfg := *env.config cfg.CreateBlockchainTxFee = test.fee backend := builder.NewBackend(env.ctx, &cfg, env.state, env.atomicUTXOs) From 0f24a1af9a4b1e7e4bbac13229eacdcd5d4e8dfa Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 21 Feb 2024 16:05:08 +0100 Subject: [PATCH 048/120] fixed UTs --- vms/platformvm/txs/builder/backend.go | 4 ++-- vms/platformvm/txs/executor/create_chain_test.go | 4 ++-- vms/platformvm/txs/executor/create_subnet_test.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vms/platformvm/txs/builder/backend.go b/vms/platformvm/txs/builder/backend.go index be416b38de3e..06477cfd5553 100644 --- a/vms/platformvm/txs/builder/backend.go +++ b/vms/platformvm/txs/builder/backend.go @@ -62,9 +62,9 @@ func (b *Backend) CreateSubnetTxFee() uint64 { return b.cfg.GetCreateSubnetTxFee(b.state.GetTimestamp()) } -// Override [backend.Context.GetCreateBlockchainTxFee] to refresh fee +// Override [backend.Context.CreateBlockchainTxFee] to refresh fee // relevant in unit tests only -func (b *Backend) GetCreateBlockchainTxFee() uint64 { +func (b *Backend) CreateBlockchainTxFee() uint64 { return b.cfg.GetCreateBlockchainTxFee(b.state.GetTimestamp()) } diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 81552b074f43..8b51e098b7e3 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -45,7 +45,7 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { require.NoError(err) // Remove a signature - tx.Creds[1].(*secp256k1fx.Credential).Sigs = tx.Creds[1].(*secp256k1fx.Credential).Sigs[1:] + tx.Creds[0].(*secp256k1fx.Credential).Sigs = tx.Creds[0].(*secp256k1fx.Credential).Sigs[1:] stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) @@ -85,7 +85,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { // Replace a valid signature with one from another key sig, err := key.SignHash(hashing.ComputeHash256(tx.Unsigned.Bytes())) require.NoError(err) - copy(tx.Creds[1].(*secp256k1fx.Credential).Sigs[0][:], sig) + copy(tx.Creds[0].(*secp256k1fx.Credential).Sigs[0][:], sig) stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 2b5396f432a7..e8d88a541a48 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -56,7 +56,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - env.state.SetTimestamp(test.time) + env.state.SetTimestamp(test.time) // to duly set fee addrs := set.NewSet[ids.ShortID](len(preFundedKeys)) for _, key := range preFundedKeys { From 5aa5932e111d1fb957428a1c29340b7247cdc0fb Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 22 Feb 2024 14:54:15 +0100 Subject: [PATCH 049/120] some more fixes --- vms/platformvm/txs/builder/builder.go | 3 +++ wallet/chain/p/backends/builder.go | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index ea63e8f302ee..8daacafefad0 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -10,6 +10,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -369,6 +370,7 @@ func (b *builder) NewCreateSubnetTx( ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) + utils.Sort(ownerAddrs) // sort control addresses subnetOwner := &secp256k1fx.OutputOwners{ Threshold: threshold, Addrs: ownerAddrs, @@ -677,6 +679,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) + utils.Sort(ownerAddrs) // sort control addresses newOwner := &secp256k1fx.OutputOwners{ Threshold: threshold, Addrs: ownerAddrs, diff --git a/wallet/chain/p/backends/builder.go b/wallet/chain/p/backends/builder.go index b82a91cc4bf3..a3fb355749d8 100644 --- a/wallet/chain/p/backends/builder.go +++ b/wallet/chain/p/backends/builder.go @@ -945,6 +945,13 @@ func (b *builder) spend( Addrs: []ids.ShortID{addr}, }) + // we initialize the return values with empty slices + // to preserv backward compatibility of json representation + // for transactions with no inputs/outputs + inputs = make([]*avax.TransferableInput, 0) + changeOutputs = make([]*avax.TransferableOutput, 0) + stakeOutputs = make([]*avax.TransferableOutput, 0) + // Iterate over the locked UTXOs for _, utxo := range utxos { assetID := utxo.AssetID() From 32ce3e0e0fdbce8705c589b29f55acf06fa72f52 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 26 Feb 2024 13:12:02 +0100 Subject: [PATCH 050/120] added block complexity metrics+ --- vms/components/fees/dimensions.go | 23 ++++++++++ vms/platformvm/block/executor/acceptor.go | 10 +++++ vms/platformvm/block/executor/block_state.go | 9 ++-- vms/platformvm/block/executor/verifier.go | 45 +++++++++++++------- vms/platformvm/metrics/metrics.go | 41 ++++++++++++++++++ vms/platformvm/metrics/no_op.go | 4 ++ 6 files changed, 113 insertions(+), 19 deletions(-) diff --git a/vms/components/fees/dimensions.go b/vms/components/fees/dimensions.go index da8e4c8e31a3..8184c242768f 100644 --- a/vms/components/fees/dimensions.go +++ b/vms/components/fees/dimensions.go @@ -4,6 +4,7 @@ package fees import ( + "errors" "math" safemath "github.com/ava-labs/avalanchego/utils/math" @@ -15,10 +16,17 @@ const ( UTXOWrite Dimension = 2 // includes delete Compute Dimension = 3 // signatures checks, tx-specific + bandwidthString string = "Bandwidth" + utxosReadString string = "UTXOsRead" + utxosWriteString string = "UTXOsWrite" + computeString string = "Compute" + FeeDimensions = 4 ) var ( + errUnknownDimension = errors.New("unknown dimension") + Empty = Dimensions{} Max = Dimensions{ math.MaxUint64, @@ -26,6 +34,13 @@ var ( math.MaxUint64, math.MaxUint64, } + + DimensionStrings = []string{ + bandwidthString, + utxosReadString, + utxosWriteString, + computeString, + } ) type ( @@ -33,6 +48,14 @@ type ( Dimensions [FeeDimensions]uint64 ) +func (d Dimension) String() (string, error) { + if d < 0 || d >= FeeDimensions { + return "", errUnknownDimension + } + + return DimensionStrings[d], nil +} + func Add(lhs, rhs Dimensions) (Dimensions, error) { var res Dimensions for i := 0; i < FeeDimensions; i++ { diff --git a/vms/platformvm/block/executor/acceptor.go b/vms/platformvm/block/executor/acceptor.go index cc2bcef0521f..0cca4435f257 100644 --- a/vms/platformvm/block/executor/acceptor.go +++ b/vms/platformvm/block/executor/acceptor.go @@ -79,6 +79,8 @@ func (a *acceptor) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { return fmt.Errorf("%w %s", errMissingBlockState, blkID) } + a.metrics.SetBlockComplexity(blkState.blockComplexity) + // Update the state to reflect the changes made in [onAcceptState]. if err := blkState.onAcceptState.Apply(a.state); err != nil { return err @@ -136,6 +138,8 @@ func (a *acceptor) optionBlock(b block.Block, blockType string) error { return err } + a.metrics.SetBlockComplexity(parentState.blockComplexity) + if err := a.commonAccept(b); err != nil { return err } @@ -150,6 +154,10 @@ func (a *acceptor) optionBlock(b block.Block, blockType string) error { if !ok { return fmt.Errorf("%w %s", errMissingBlockState, blkID) } + + // we set option complexity at its parent block's one. + a.metrics.SetBlockComplexity(parentState.blockComplexity) + if err := blkState.onAcceptState.Apply(a.state); err != nil { return err } @@ -228,6 +236,8 @@ func (a *acceptor) standardBlock(b block.Block, blockType string) error { return fmt.Errorf("%w %s", errMissingBlockState, blkID) } + a.metrics.SetBlockComplexity(blkState.blockComplexity) + // Update the state to reflect the changes made in [onAcceptState]. if err := blkState.onAcceptState.Apply(a.state); err != nil { return err diff --git a/vms/platformvm/block/executor/block_state.go b/vms/platformvm/block/executor/block_state.go index 9d6b377c2644..f0e3989a7856 100644 --- a/vms/platformvm/block/executor/block_state.go +++ b/vms/platformvm/block/executor/block_state.go @@ -11,6 +11,8 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/state" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) type proposalBlockState struct { @@ -28,7 +30,8 @@ type blockState struct { onAcceptState state.Diff onAcceptFunc func() - inputs set.Set[ids.ID] - timestamp time.Time - atomicRequests map[ids.ID]*atomic.Requests + inputs set.Set[ids.ID] + timestamp time.Time + blockComplexity commonfees.Dimensions + atomicRequests map[ids.ID]*atomic.Requests } diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index afd2a74a2a0d..95b4809fd96c 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -72,7 +72,7 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { return err } - inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, onDecisionState, b.Parent()) + inputs, feesMan, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, onDecisionState, b.Parent()) if err != nil { return err } @@ -92,6 +92,7 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { onDecisionState, onCommitState, onAbortState, + feesMan.GetCumulatedUnits(), inputs, atomicRequests, onAcceptFunc, @@ -157,7 +158,7 @@ func (v *verifier) ApricotProposalBlock(b *block.ApricotProposalBlock) error { return err } - return v.proposalBlock(b, nil, onCommitState, onAbortState, nil, nil, nil) + return v.proposalBlock(b, nil, onCommitState, onAbortState, fees.Empty, nil, nil, nil) } func (v *verifier) ApricotStandardBlock(b *block.ApricotStandardBlock) error { @@ -220,9 +221,10 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { onAcceptState: atomicExecutor.OnAccept, - inputs: atomicExecutor.Inputs, - timestamp: atomicExecutor.OnAccept.GetTimestamp(), - atomicRequests: atomicExecutor.AtomicRequests, + inputs: atomicExecutor.Inputs, + timestamp: atomicExecutor.OnAccept.GetTimestamp(), + blockComplexity: fees.Empty, + atomicRequests: atomicExecutor.AtomicRequests, } return nil } @@ -335,6 +337,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 } @@ -352,6 +357,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 } @@ -362,6 +370,7 @@ func (v *verifier) proposalBlock( onDecisionState state.Diff, onCommitState state.Diff, onAbortState state.Diff, + blockComplexity fees.Dimensions, inputs set.Set[ids.ID], atomicRequests map[ids.ID]*atomic.Requests, onAcceptFunc func(), @@ -400,8 +409,9 @@ func (v *verifier) proposalBlock( // It is safe to use [b.onAbortState] here because the timestamp will // never be modified by an Apricot Abort block and the timestamp will // always be the same as the Banff Proposal Block. - timestamp: onAbortState.GetTimestamp(), - atomicRequests: atomicRequests, + timestamp: onAbortState.GetTimestamp(), + blockComplexity: blockComplexity, + atomicRequests: atomicRequests, } return nil } @@ -411,7 +421,7 @@ func (v *verifier) standardBlock( b *block.ApricotStandardBlock, onAcceptState state.Diff, ) error { - inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, onAcceptState, b.Parent()) + inputs, feeMan, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, onAcceptState, b.Parent()) if err != nil { return err } @@ -425,21 +435,24 @@ func (v *verifier) standardBlock( onAcceptState: onAcceptState, onAcceptFunc: onAcceptFunc, - timestamp: onAcceptState.GetTimestamp(), - inputs: inputs, - atomicRequests: atomicRequests, + timestamp: onAcceptState.GetTimestamp(), + blockComplexity: feeMan.GetCumulatedUnits(), + inputs: inputs, + atomicRequests: atomicRequests, } return nil } func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID ids.ID) ( set.Set[ids.ID], + *fees.Manager, map[ids.ID]*atomic.Requests, func(), error, ) { var ( feesCfg = v.txExecutorBackend.Config.GetDynamicFeesConfig(state.GetTimestamp()) + feesMan = fees.NewManager(feesCfg.UnitFees) onAcceptFunc func() inputs set.Set[ids.ID] @@ -449,7 +462,7 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID for _, tx := range txs { txExecutor := executor.StandardTxExecutor{ Backend: v.txExecutorBackend, - BlkFeeManager: fees.NewManager(feesCfg.UnitFees), + BlkFeeManager: feesMan, UnitCaps: feesCfg.BlockUnitsCap, State: state, Tx: tx, @@ -457,11 +470,11 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID if err := tx.Unsigned.Visit(&txExecutor); err != nil { txID := tx.ID() v.MarkDropped(txID, err) // cache tx as dropped - return nil, nil, nil, err + return nil, nil, nil, nil, err } // ensure it doesn't overlap with current input batch if inputs.Overlaps(txExecutor.Inputs) { - return nil, nil, nil, ErrConflictingBlockTxs + return nil, nil, nil, nil, ErrConflictingBlockTxs } // Add UTXOs to batch inputs.Union(txExecutor.Inputs) @@ -485,7 +498,7 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID } if err := v.verifyUniqueInputs(parentID, inputs); err != nil { - return nil, nil, nil, err + return nil, nil, nil, nil, err } if numFuncs := len(funcs); numFuncs == 1 { @@ -498,5 +511,5 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID } } - return inputs, atomicRequests, onAcceptFunc, nil + return inputs, feesMan, atomicRequests, onAcceptFunc, nil } diff --git a/vms/platformvm/metrics/metrics.go b/vms/platformvm/metrics/metrics.go index 98b611a017ed..45d3b45b1b74 100644 --- a/vms/platformvm/metrics/metrics.go +++ b/vms/platformvm/metrics/metrics.go @@ -12,6 +12,8 @@ import ( "github.com/ava-labs/avalanchego/utils/metric" "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/avalanchego/vms/platformvm/block" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var _ Metrics = (*metrics)(nil) @@ -38,6 +40,9 @@ type Metrics interface { SetTimeUntilUnstake(time.Duration) // Mark when this node will unstake from a subnet. SetTimeUntilSubnetUnstake(subnetID ids.ID, timeUntilUnstake time.Duration) + + // Mark cumulated complexity of the latest accepted block + SetBlockComplexity(commonfees.Dimensions) } func New( @@ -91,6 +96,26 @@ func New( Name: "validator_sets_duration_sum", Help: "Total amount of time generating validator sets in nanoseconds", }), + blockBandwitdhComplexity: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "block_bandwidth_complexity", + Help: "Cumulated bandwidth complexity over last accepted block", + }), + blockUTXOsReadComplexity: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "block_utxos_read_complexity", + Help: "Cumulated utxos read complexity over last accepted block", + }), + blockUTXOsWriteComplexity: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "block_utxos_write_complexity", + Help: "Cumulated utxos write complexity over last accepted block", + }), + blockComputeComplexity: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "block_compute_complexity", + Help: "Cumulated compute complexity over last accepted block", + }), } errs := wrappers.Errs{Err: err} @@ -107,6 +132,10 @@ func New( registerer.Register(m.validatorSetsCached), registerer.Register(m.validatorSetsHeightDiff), registerer.Register(m.validatorSetsDuration), + registerer.Register(m.blockBandwitdhComplexity), + registerer.Register(m.blockUTXOsReadComplexity), + registerer.Register(m.blockUTXOsWriteComplexity), + registerer.Register(m.blockComputeComplexity), ) return m, errs.Err @@ -126,6 +155,11 @@ type metrics struct { validatorSetsCreated prometheus.Counter validatorSetsHeightDiff prometheus.Gauge validatorSetsDuration prometheus.Gauge + + blockBandwitdhComplexity prometheus.Gauge + blockUTXOsReadComplexity prometheus.Gauge + blockUTXOsWriteComplexity prometheus.Gauge + blockComputeComplexity prometheus.Gauge } func (m *metrics) MarkAccepted(b block.Block) error { @@ -163,3 +197,10 @@ func (m *metrics) SetTimeUntilUnstake(timeUntilUnstake time.Duration) { func (m *metrics) SetTimeUntilSubnetUnstake(subnetID ids.ID, timeUntilUnstake time.Duration) { m.timeUntilSubnetUnstake.WithLabelValues(subnetID.String()).Set(float64(timeUntilUnstake)) } + +func (m *metrics) SetBlockComplexity(units commonfees.Dimensions) { + m.blockBandwitdhComplexity.Set(float64(units[commonfees.Bandwidth])) + m.blockUTXOsReadComplexity.Set(float64(units[commonfees.UTXORead])) + m.blockUTXOsWriteComplexity.Set(float64(units[commonfees.UTXOWrite])) + m.blockComputeComplexity.Set(float64(units[commonfees.Compute])) +} diff --git a/vms/platformvm/metrics/no_op.go b/vms/platformvm/metrics/no_op.go index 770e30c961a1..22cc5defc8ad 100644 --- a/vms/platformvm/metrics/no_op.go +++ b/vms/platformvm/metrics/no_op.go @@ -11,6 +11,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/vms/platformvm/block" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var Noop Metrics = noopMetrics{} @@ -50,3 +52,5 @@ func (noopMetrics) SetTimeUntilSubnetUnstake(ids.ID, time.Duration) {} func (noopMetrics) SetSubnetPercentConnected(ids.ID, float64) {} func (noopMetrics) SetPercentConnected(float64) {} + +func (noopMetrics) SetBlockComplexity(commonfees.Dimensions) {} From ebc1b505db295625c336bb9d3bd71d7de1a4da42 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 26 Feb 2024 14:02:28 +0100 Subject: [PATCH 051/120] minor renaming --- vms/platformvm/block/builder/helpers_test.go | 6 +++--- vms/platformvm/block/executor/helpers_test.go | 8 ++++---- vms/platformvm/txs/executor/helpers_test.go | 6 +++--- vms/platformvm/utxo/{handler.go => verifier.go} | 0 vms/platformvm/utxo/{handler_test.go => verifier_test.go} | 0 vms/platformvm/vm.go | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) rename vms/platformvm/utxo/{handler.go => verifier.go} (100%) rename vms/platformvm/utxo/{handler_test.go => verifier_test.go} (100%) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index eb61e6830c3d..bada93b97a09 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -116,7 +116,7 @@ type environment struct { state state.State atomicUTXOs avax.AtomicUTXOManager uptimes uptime.Manager - utxosHandler utxo.Verifier + utxosVerifier utxo.Verifier txBuilder txbuilder.Builder backend txexecutor.Backend } @@ -151,7 +151,7 @@ func newEnvironment(t *testing.T, f fork) *environment { //nolint:unparam res.atomicUTXOs = avax.NewAtomicUTXOManager(res.ctx.SharedMemory, txs.Codec) res.uptimes = uptime.NewManager(res.state, res.clk) - res.utxosHandler = utxo.NewVerifier(res.ctx, res.clk, res.fx) + res.utxosVerifier = utxo.NewVerifier(res.ctx, res.clk, res.fx) res.txBuilder = txbuilder.New( res.ctx, @@ -167,7 +167,7 @@ func newEnvironment(t *testing.T, f fork) *environment { //nolint:unparam Clk: res.clk, Bootstrapped: res.isBootstrapped, Fx: res.fx, - FlowChecker: res.utxosHandler, + FlowChecker: res.utxosVerifier, Uptimes: res.uptimes, Rewards: rewardsCalc, } diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index e5674bc7cb39..6a774a3ade29 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -127,7 +127,7 @@ type environment struct { mockedState *state.MockState atomicUTXOs avax.AtomicUTXOManager uptimes uptime.Manager - utxosHandler utxo.Verifier + utxosVerifier utxo.Verifier txBuilder p_tx_builder.Builder backend *executor.Backend } @@ -156,7 +156,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment if ctrl == nil { res.state = defaultState(res.config, res.ctx, res.baseDB, rewardsCalc) res.uptimes = uptime.NewManager(res.state, res.clk) - res.utxosHandler = utxo.NewVerifier(res.ctx, res.clk, res.fx) + res.utxosVerifier = utxo.NewVerifier(res.ctx, res.clk, res.fx) res.txBuilder = p_tx_builder.New( res.ctx, res.config, @@ -167,7 +167,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment genesisBlkID = ids.GenerateTestID() res.mockedState = state.NewMockState(ctrl) res.uptimes = uptime.NewManager(res.mockedState, res.clk) - res.utxosHandler = utxo.NewVerifier(res.ctx, res.clk, res.fx) + res.utxosVerifier = utxo.NewVerifier(res.ctx, res.clk, res.fx) res.mockedState.EXPECT().GetTimestamp().Return(time.Time{}).Times(2) // to initialize createSubnet/BlockchainTx fee res.txBuilder = p_tx_builder.New( @@ -187,7 +187,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment Clk: res.clk, Bootstrapped: res.isBootstrapped, Fx: res.fx, - FlowChecker: res.utxosHandler, + FlowChecker: res.utxosVerifier, Uptimes: res.uptimes, Rewards: rewardsCalc, } diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 71bf4753412c..5574751c9514 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -141,7 +141,7 @@ func newEnvironment(t *testing.T, f fork) *environment { atomicUTXOs := avax.NewAtomicUTXOManager(ctx.SharedMemory, txs.Codec) uptimes := uptime.NewManager(baseState, clk) - utxoHandler := utxo.NewVerifier(ctx, clk, fx) + utxosVerifier := utxo.NewVerifier(ctx, clk, fx) txBuilder := builder.New( ctx, @@ -156,7 +156,7 @@ func newEnvironment(t *testing.T, f fork) *environment { Clk: clk, Bootstrapped: &isBootstrapped, Fx: fx, - FlowChecker: utxoHandler, + FlowChecker: utxosVerifier, Uptimes: uptimes, Rewards: rewards, } @@ -173,7 +173,7 @@ func newEnvironment(t *testing.T, f fork) *environment { states: make(map[ids.ID]state.Chain), atomicUTXOs: atomicUTXOs, uptimes: uptimes, - utxosHandler: utxoHandler, + utxosHandler: utxosVerifier, txBuilder: txBuilder, backend: backend, } diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/verifier.go similarity index 100% rename from vms/platformvm/utxo/handler.go rename to vms/platformvm/utxo/verifier.go diff --git a/vms/platformvm/utxo/handler_test.go b/vms/platformvm/utxo/verifier_test.go similarity index 100% rename from vms/platformvm/utxo/handler_test.go rename to vms/platformvm/utxo/verifier_test.go diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index deb2785f21f3..70f0f01ff4c0 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -158,7 +158,7 @@ func (vm *VM) Initialize( validatorManager := pvalidators.NewManager(chainCtx.Log, vm.Config, vm.state, vm.metrics, &vm.clock) vm.State = validatorManager vm.atomicUtxosManager = avax.NewAtomicUTXOManager(chainCtx.SharedMemory, txs.Codec) - utxoHandler := utxo.NewVerifier(vm.ctx, &vm.clock, vm.fx) + utxoVerifier := utxo.NewVerifier(vm.ctx, &vm.clock, vm.fx) vm.uptimeManager = uptime.NewManager(vm.state, &vm.clock) vm.UptimeLockedCalculator.SetCalculator(&vm.bootstrapped, &chainCtx.Lock, vm.uptimeManager) @@ -174,7 +174,7 @@ func (vm *VM) Initialize( Ctx: vm.ctx, Clk: &vm.clock, Fx: vm.fx, - FlowChecker: utxoHandler, + FlowChecker: utxoVerifier, Uptimes: vm.uptimeManager, Rewards: rewards, Bootstrapped: &vm.bootstrapped, From 2661016a122ce1207b2b5f44cc0eb565b7adde35 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 11 Mar 2024 21:32:29 +0100 Subject: [PATCH 052/120] wip: refactored feeConfig getter --- tests/e2e/p/workflow.go | 2 +- vms/platformvm/block/builder/builder.go | 6 +- vms/platformvm/block/builder/helpers_test.go | 3 +- vms/platformvm/block/executor/helpers_test.go | 3 +- vms/platformvm/block/executor/manager.go | 4 +- vms/platformvm/block/executor/verifier.go | 6 +- vms/platformvm/config/config.go | 8 -- vms/platformvm/config/dynamic_fees_config.go | 14 ++- vms/platformvm/service_test.go | 3 +- vms/platformvm/txs/builder/builder.go | 26 +++--- .../txs/executor/atomic_tx_executor.go | 2 +- .../txs/executor/create_chain_test.go | 25 +++-- .../txs/executor/create_subnet_test.go | 13 ++- vms/platformvm/txs/executor/helpers_test.go | 3 +- .../txs/executor/standard_tx_executor_test.go | 93 ++++++++++++------- vms/platformvm/vm_test.go | 4 +- wallet/chain/p/wallet.go | 11 +-- 17 files changed, 134 insertions(+), 92 deletions(-) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 8e0236a12550..29328eebc595 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -152,7 +152,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { require.NoError(err) // retrieve fees paid for the tx - feeCfg := config.EUpgradeDynamicFeesConfig + feeCfg := config.GetDynamicFeesConfig(true /*isEActive*/) feeCalc := fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(feeCfg.UnitFees), diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index f5663769db28..880ba1b6c870 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -20,6 +20,7 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -333,8 +334,9 @@ func packBlockTxs( } var ( - feeCfg = backend.Config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) - feeMan = fees.NewManager(feeCfg.UnitFees) + isEActivated = backend.Config.IsEActivated(timestamp) + feeCfg = config.GetDynamicFeesConfig(isEActivated) + feeMan = fees.NewManager(feeCfg.UnitFees) 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 27311dc874c0..a0bdefc42406 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -263,7 +263,8 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(genesisID, env.blkManager) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := txexecutor.StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index d189d85d631a..42eb66fd902d 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) } - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := executor.StandardTxExecutor{ Backend: env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index 6363ee19d3ee..84fb7f69ce4f 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -11,6 +11,7 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -143,7 +144,8 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - feesCfg := m.txExecutorBackend.Config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) + isEActivated := m.txExecutorBackend.Config.IsEActivated(stateDiff.GetTimestamp()) + feesCfg := config.GetDynamicFeesConfig(isEActivated) return tx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: m.txExecutorBackend, BlkFeeManager: fees.NewManager(feesCfg.UnitFees), diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index fc78ae650224..c140e3ecff6d 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -12,6 +12,7 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -446,8 +447,9 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID error, ) { var ( - feesCfg = v.txExecutorBackend.Config.GetDynamicFeesConfig(state.GetTimestamp()) - feesMan = fees.NewManager(feesCfg.UnitFees) + isEActivated = v.txExecutorBackend.Config.IsEActivated(state.GetTimestamp()) + feesCfg = config.GetDynamicFeesConfig(isEActivated) + feesMan = fees.NewManager(feesCfg.UnitFees) onAcceptFunc func() inputs set.Set[ids.ID] diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index e2c9a12a1179..0c5fcf15a475 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -144,14 +144,6 @@ func (c *Config) IsEActivated(timestamp time.Time) bool { return !timestamp.Before(c.EUpgradeTime) } -func (c *Config) GetDynamicFeesConfig(timestamp time.Time) DynamicFeesConfig { - if !c.IsEActivated(timestamp) { - return PreEUpgradeDynamicFeesConfig - } - - return EUpgradeDynamicFeesConfig -} - func (c *Config) GetCreateBlockchainTxFee(timestamp time.Time) uint64 { if c.IsApricotPhase3Activated(timestamp) { return c.CreateBlockchainTxFee diff --git a/vms/platformvm/config/dynamic_fees_config.go b/vms/platformvm/config/dynamic_fees_config.go index 963d59b2ccd3..40ca071742b2 100644 --- a/vms/platformvm/config/dynamic_fees_config.go +++ b/vms/platformvm/config/dynamic_fees_config.go @@ -16,9 +16,9 @@ import ( // I am setting them in a separate config object, but will access it via Config // so to have fork control over which dynamic fees is picked -// EUpgradeDynamicFeesConfig to be tuned TODO ABENEGIA +// eUpgradeDynamicFeesConfig to be tuned TODO ABENEGIA var ( - EUpgradeDynamicFeesConfig = DynamicFeesConfig{ + eUpgradeDynamicFeesConfig = DynamicFeesConfig{ UnitFees: commonfees.Dimensions{ 1 * units.NanoAvax, 2 * units.NanoAvax, @@ -29,12 +29,20 @@ var ( BlockUnitsCap: commonfees.Max, } - PreEUpgradeDynamicFeesConfig = DynamicFeesConfig{ + preEUpgradeDynamicFeesConfig = DynamicFeesConfig{ UnitFees: commonfees.Empty, BlockUnitsCap: commonfees.Max, } ) +func GetDynamicFeesConfig(isEActive bool) DynamicFeesConfig { + if !isEActive { + return preEUpgradeDynamicFeesConfig + } + + return eUpgradeDynamicFeesConfig +} + type DynamicFeesConfig struct { // UnitFees contains, per each fee dimension, the // unit fees valid as soon as fork introducing dynamic fees diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 66f6d1a1c441..7c8c5a7bd763 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -35,6 +35,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/block/builder" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" @@ -354,7 +355,7 @@ func TestGetBalance(t *testing.T) { // As such we need to account for the subnet creation fee var ( chainTime = service.vm.state.GetTimestamp() - feeCfg = service.vm.Config.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(service.vm.Config.IsEActivated(chainTime)) feeMan = commonfees.NewManager(feeCfg.UnitFees) feeCalc = &fees.Calculator{ IsEUpgradeActive: service.vm.IsEActivated(chainTime), diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index f4503dd5c733..3352e91d3a8d 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -284,7 +284,7 @@ func (b *builder) NewImportTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -331,7 +331,7 @@ func (b *builder) NewExportTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -385,7 +385,7 @@ func (b *builder) NewCreateChainTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -427,7 +427,7 @@ func (b *builder) NewCreateSubnetTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -483,7 +483,7 @@ func (b *builder) NewTransformSubnetTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -538,7 +538,7 @@ func (b *builder) NewAddValidatorTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -595,7 +595,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -656,7 +656,7 @@ func (b *builder) NewAddDelegatorTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -710,7 +710,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -768,7 +768,7 @@ func (b *builder) NewAddSubnetValidatorTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -816,7 +816,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -856,7 +856,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ @@ -901,7 +901,7 @@ func (b *builder) NewBaseTx( var ( pBuilder, pSigner = b.builders(keys) chainTime = b.state.GetTimestamp() - feeCfg = b.cfg.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ diff --git a/vms/platformvm/txs/executor/atomic_tx_executor.go b/vms/platformvm/txs/executor/atomic_tx_executor.go index 3a6ddcf0662a..6dfec80f345e 100644 --- a/vms/platformvm/txs/executor/atomic_tx_executor.go +++ b/vms/platformvm/txs/executor/atomic_tx_executor.go @@ -101,7 +101,7 @@ func (e *AtomicTxExecutor) atomicTx(tx txs.UnsignedTx) error { } e.OnAccept = onAccept - feesCfg := config.PreEUpgradeDynamicFeesConfig + feesCfg := config.GetDynamicFeesConfig(false /*isEActive*/) executor := StandardTxExecutor{ Backend: e.Backend, BlkFeeManager: commonfees.NewManager(feesCfg.UnitFees), diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 1a393479ed74..52d0ecc08836 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" + "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/builder" @@ -53,7 +54,8 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), @@ -96,7 +98,8 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) + chainTime := stateDiff.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), @@ -133,7 +136,8 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) + currentTime := stateDiff.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), @@ -167,7 +171,8 @@ func TestCreateChainTxValid(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) + currentTime := stateDiff.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), @@ -223,10 +228,11 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { cfg.CreateBlockchainTxFee = test.fee var ( - backend = builder.NewBackend(env.ctx, &cfg, env.state, env.atomicUTXOs) - pBuilder = backends.NewBuilder(addrs, backend) - feeCfg = cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) - feeCalc = &fees.Calculator{ + backend = builder.NewBackend(env.ctx, &cfg, env.state, env.atomicUTXOs) + pBuilder = backends.NewBuilder(addrs, backend) + chainTime = env.state.GetTimestamp() + feeCfg = config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) + feeCalc = &fees.Calculator{ IsEUpgradeActive: false, Config: &cfg, ChainTime: test.time, @@ -256,7 +262,8 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCfg = env.config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) + currentTime := stateDiff.GetTimestamp() + feeCfg = config.GetDynamicFeesConfig(env.config.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 3bf41368e768..32208d74c77d 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/ids" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" @@ -69,10 +70,11 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateSubnetTxFee = test.fee var ( - backend = builder.NewBackend(env.ctx, &cfg, env.state, env.atomicUTXOs) - pBuilder = backends.NewBuilder(addrs, backend) - feeCfg = cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) - feeCalc = &fees.Calculator{ + backend = builder.NewBackend(env.ctx, &cfg, env.state, env.atomicUTXOs) + pBuilder = backends.NewBuilder(addrs, backend) + chainTime = env.state.GetTimestamp() + feeCfg = config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) + feeCalc = &fees.Calculator{ IsEUpgradeActive: false, Config: &cfg, ChainTime: test.time, @@ -100,7 +102,8 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCfg = env.config.GetDynamicFeesConfig(stateDiff.GetTimestamp()) + chainTime = stateDiff.GetTimestamp() + feeCfg = config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index c5930b3e070f..56b0028c73f6 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -236,7 +236,8 @@ func addSubnet( stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 1d2aa040f43f..f44ece3e0e7d 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -89,7 +89,8 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -339,7 +340,8 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { freshTH.config.BanffTime = onAcceptState.GetTimestamp() - feeCfg := freshTH.config.GetDynamicFeesConfig(freshTH.state.GetTimestamp()) + chainTime := freshTH.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(freshTH.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &freshTH.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -381,7 +383,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -413,7 +416,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -460,7 +464,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -507,7 +512,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -537,7 +543,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -567,7 +574,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -599,7 +607,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -660,7 +669,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -701,7 +711,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -738,7 +749,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -773,7 +785,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -818,7 +831,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -857,7 +871,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -900,7 +915,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutCurrentValidator(staker) onAcceptState.AddTx(tx, status.Committed) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -940,7 +956,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutPendingValidator(staker) onAcceptState.AddTx(tx, status.Committed) - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -979,7 +996,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.DeleteUTXO(utxoID) } - feeCfg := env.config.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.UnitFees), @@ -1559,7 +1577,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1586,8 +1605,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.tx.Unsigned.(*txs.RemoveSubnetValidatorTx).Subnet = constants.PrimaryNetworkID env.state = state.NewMockDiff(ctrl) - cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCfg := cfg.GetDynamicFeesConfig(time.Time{}) // pre E upgrade + feeCfg := config.GetDynamicFeesConfig(false /*isEActive*/) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1616,7 +1634,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetPendingValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1648,7 +1667,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(&staker, nil).Times(1) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1678,7 +1698,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1707,7 +1728,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1738,7 +1760,8 @@ 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) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1772,7 +1795,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { ).Return(errTest) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1929,8 +1953,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.tx.Unsigned = (*txs.TransformSubnetTx)(nil) env.state = state.NewMockDiff(ctrl) - cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCfg := cfg.GetDynamicFeesConfig(time.Time{}) // pre E-upgrade + feeCfg := config.GetDynamicFeesConfig(false /*isEActive*/) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1958,7 +1981,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() - feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1988,7 +2012,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() - feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2023,7 +2048,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2063,7 +2089,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCfg := cfg.GetDynamicFeesConfig(env.state.GetTimestamp()) + chainTime := env.state.GetTimestamp() + feeCfg := config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 469289d533b7..7a20b4695810 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -377,7 +377,7 @@ func TestGenesis(t *testing.T) { // As such we need to account for the subnet creation fee var ( chainTime = vm.state.GetTimestamp() - feeCfg = vm.Config.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(vm.Config.IsEActivated(chainTime)) feeMan = commonfees.NewManager(feeCfg.UnitFees) feeCalc = &fees.Calculator{ IsEUpgradeActive: vm.IsEActivated(chainTime), @@ -2271,7 +2271,7 @@ func TestBaseTx(t *testing.T) { var ( chainTime = vm.state.GetTimestamp() - feeCfg = vm.Config.GetDynamicFeesConfig(chainTime) + feeCfg = config.GetDynamicFeesConfig(vm.Config.IsEActivated(chainTime)) feeMan = commonfees.NewManager(feeCfg.UnitFees) feeCalc = &fees.Calculator{ IsEUpgradeActive: vm.IsEActivated(chainTime), diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 08e07c10b3e4..f95287786753 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -754,13 +754,8 @@ func (w *wallet) refreshFork(options ...common.Option) error { } w.isEForkActive = !chainTime.Before(eForkTime) - if w.isEForkActive { - w.unitFees = config.EUpgradeDynamicFeesConfig.UnitFees - w.unitCaps = config.EUpgradeDynamicFeesConfig.BlockUnitsCap - } else { - w.unitFees = config.PreEUpgradeDynamicFeesConfig.UnitFees - w.unitCaps = config.PreEUpgradeDynamicFeesConfig.BlockUnitsCap - } - + feeCfg := config.GetDynamicFeesConfig(w.isEForkActive) + w.unitFees = feeCfg.UnitFees + w.unitCaps = feeCfg.BlockUnitsCap return nil } From 153e0ea8e3d2a4a4fea8f3fb703e1040b6e37a41 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 11 Mar 2024 22:28:26 +0100 Subject: [PATCH 053/120] wip: added custom dynamic fees config --- vms/platformvm/config/dynamic_fees_config.go | 21 ++++++++++++++++++++ vms/platformvm/config/execution_config.go | 2 ++ vms/platformvm/vm.go | 6 +++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/vms/platformvm/config/dynamic_fees_config.go b/vms/platformvm/config/dynamic_fees_config.go index 40ca071742b2..117b82767917 100644 --- a/vms/platformvm/config/dynamic_fees_config.go +++ b/vms/platformvm/config/dynamic_fees_config.go @@ -4,6 +4,10 @@ package config import ( + "fmt" + + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/units" commonfees "github.com/ava-labs/avalanchego/vms/components/fees" @@ -33,6 +37,8 @@ var ( UnitFees: commonfees.Empty, BlockUnitsCap: commonfees.Max, } + + customDynamicFeesConfig *DynamicFeesConfig ) func GetDynamicFeesConfig(isEActive bool) DynamicFeesConfig { @@ -40,9 +46,24 @@ func GetDynamicFeesConfig(isEActive bool) DynamicFeesConfig { return preEUpgradeDynamicFeesConfig } + if customDynamicFeesConfig != nil { + return *customDynamicFeesConfig + } return eUpgradeDynamicFeesConfig } +func ResetDynamicFeesConfig(ctx *snow.Context, customFeesConfig *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 unit fees config for network %s", constants.NetworkName(ctx.NetworkID)) + } + + customDynamicFeesConfig = customFeesConfig + return nil +} + type DynamicFeesConfig struct { // UnitFees contains, per each fee dimension, the // unit fees valid as soon as fork introducing dynamic fees diff --git a/vms/platformvm/config/execution_config.go b/vms/platformvm/config/execution_config.go index e182758e0c50..4e4e8f8f0ccb 100644 --- a/vms/platformvm/config/execution_config.go +++ b/vms/platformvm/config/execution_config.go @@ -38,6 +38,8 @@ type ExecutionConfig struct { FxOwnerCacheSize int `json:"fx-owner-cache-size"` ChecksumsEnabled bool `json:"checksums-enabled"` MempoolPruneFrequency time.Duration `json:"mempool-prune-frequency"` + + DynamicFeesConfig *DynamicFeesConfig `json:"dynamic-fees-config"` } // GetExecutionConfig returns an ExecutionConfig diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index cd414ca3330b..69819fd8a91a 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -113,7 +113,11 @@ func (vm *VM) Initialize( if err != nil { return err } - chainCtx.Log.Info("using VM execution config", zap.Reflect("config", execConfig)) + chainCtx.Log.Info("retrieved VM execution config", zap.Reflect("config", execConfig)) + + if err := config.ResetDynamicFeesConfig(chainCtx, execConfig.DynamicFeesConfig); err != nil { + return fmt.Errorf("failed resetting dynamic fees config: %w", err) + } registerer := prometheus.NewRegistry() if err := chainCtx.Metrics.Register(registerer); err != nil { From 5ad836585338d6972ad423ef92e7d201f85f511c Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 18 Mar 2024 13:00:01 +0100 Subject: [PATCH 054/120] moved dynamic fees config to common components --- vms/components/fees/config.go | 15 +++++++++++ vms/platformvm/config/dynamic_fees_config.go | 28 ++++---------------- vms/platformvm/config/execution_config.go | 5 +++- 3 files changed, 24 insertions(+), 24 deletions(-) create mode 100644 vms/components/fees/config.go diff --git a/vms/components/fees/config.go b/vms/components/fees/config.go new file mode 100644 index 000000000000..2d7fffac114c --- /dev/null +++ b/vms/components/fees/config.go @@ -0,0 +1,15 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package fees + +type DynamicFeesConfig struct { + // UnitFees contains, per each fee dimension, the + // unit fees valid as soon as fork introducing dynamic fees + // activates. Unit fees are not currently updated by any dynamic fees algo. + UnitFees Dimensions `json:"initial-unit-fees"` + + // BlockUnitsCap contains, per each fee dimension, the + // maximal complexity a valid block can host + BlockUnitsCap Dimensions `json:"block-unit-caps"` +} diff --git a/vms/platformvm/config/dynamic_fees_config.go b/vms/platformvm/config/dynamic_fees_config.go index 117b82767917..a7925f4147e9 100644 --- a/vms/platformvm/config/dynamic_fees_config.go +++ b/vms/platformvm/config/dynamic_fees_config.go @@ -13,16 +13,9 @@ import ( commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) -// Dynamic fees configs become relevant with dynamic fees introduction in E-fork -// We cannot easily include then in Config since they do not come from genesis -// They don't feel like an execution config either, since we need a fork upgrade -// to update them (testing is a different story). -// I am setting them in a separate config object, but will access it via Config -// so to have fork control over which dynamic fees is picked - // eUpgradeDynamicFeesConfig to be tuned TODO ABENEGIA var ( - eUpgradeDynamicFeesConfig = DynamicFeesConfig{ + eUpgradeDynamicFeesConfig = commonfees.DynamicFeesConfig{ UnitFees: commonfees.Dimensions{ 1 * units.NanoAvax, 2 * units.NanoAvax, @@ -33,15 +26,15 @@ var ( BlockUnitsCap: commonfees.Max, } - preEUpgradeDynamicFeesConfig = DynamicFeesConfig{ + preEUpgradeDynamicFeesConfig = commonfees.DynamicFeesConfig{ UnitFees: commonfees.Empty, BlockUnitsCap: commonfees.Max, } - customDynamicFeesConfig *DynamicFeesConfig + customDynamicFeesConfig *commonfees.DynamicFeesConfig ) -func GetDynamicFeesConfig(isEActive bool) DynamicFeesConfig { +func GetDynamicFeesConfig(isEActive bool) commonfees.DynamicFeesConfig { if !isEActive { return preEUpgradeDynamicFeesConfig } @@ -52,7 +45,7 @@ func GetDynamicFeesConfig(isEActive bool) DynamicFeesConfig { return eUpgradeDynamicFeesConfig } -func ResetDynamicFeesConfig(ctx *snow.Context, customFeesConfig *DynamicFeesConfig) error { +func ResetDynamicFeesConfig(ctx *snow.Context, customFeesConfig *commonfees.DynamicFeesConfig) error { if customFeesConfig == nil { return nil // nothing to do } @@ -63,14 +56,3 @@ func ResetDynamicFeesConfig(ctx *snow.Context, customFeesConfig *DynamicFeesConf customDynamicFeesConfig = customFeesConfig return nil } - -type DynamicFeesConfig struct { - // UnitFees contains, per each fee dimension, the - // unit fees valid as soon as fork introducing dynamic fees - // activates. Unit fees will be then updated by the dynamic fees algo. - UnitFees commonfees.Dimensions - - // BlockUnitsCap contains, per each fee dimension, the - // maximal complexity a valid P-chain block can host - BlockUnitsCap commonfees.Dimensions -} diff --git a/vms/platformvm/config/execution_config.go b/vms/platformvm/config/execution_config.go index 4e4e8f8f0ccb..4ceaa7992887 100644 --- a/vms/platformvm/config/execution_config.go +++ b/vms/platformvm/config/execution_config.go @@ -9,6 +9,8 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/network" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var DefaultExecutionConfig = ExecutionConfig{ @@ -39,7 +41,8 @@ type ExecutionConfig struct { ChecksumsEnabled bool `json:"checksums-enabled"` MempoolPruneFrequency time.Duration `json:"mempool-prune-frequency"` - DynamicFeesConfig *DynamicFeesConfig `json:"dynamic-fees-config"` + // test nets are allow to configure ad-hoc dynamic fees configuration + DynamicFeesConfig *commonfees.DynamicFeesConfig `json:"dynamic-fees-config"` } // GetExecutionConfig returns an ExecutionConfig From 16cf7c4c05145f87d04fd8a98d533508ca7b9096 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 18:10:14 -0400 Subject: [PATCH 055/120] cleanup --- tests/antithesis/main.go | 9 +- tests/e2e/p/interchain_workflow.go | 7 +- tests/e2e/p/staking_rewards.go | 13 +- tests/e2e/p/validator_sets.go | 5 +- tests/e2e/p/workflow.go | 4 +- wallet/chain/p/backend.go | 26 ++-- wallet/chain/p/backend_visitor.go | 18 +-- wallet/chain/p/backends/backends.go | 35 ------ wallet/chain/p/backends/context.go | 119 ------------------ .../chain/p/{backends => builder}/builder.go | 106 +++++++++------- .../p/{ => builder}/builder_with_options.go | 59 +++++---- wallet/chain/p/builder/context.go | 38 ++++++ wallet/chain/p/builder_test.go | 96 +++++++------- wallet/chain/p/context.go | 36 +++--- wallet/chain/p/{backends => signer}/signer.go | 16 ++- .../signer_visitor.go => signer/visitor.go} | 44 +++---- wallet/chain/p/wallet.go | 30 ++--- wallet/chain/p/wallet_with_options.go | 52 ++++---- wallet/subnet/primary/api.go | 4 +- .../examples/add-primary-validator/main.go | 2 +- .../examples/create-locked-stakeable/main.go | 2 +- .../examples/get-p-chain-balance/main.go | 7 +- wallet/subnet/primary/wallet.go | 7 +- 23 files changed, 344 insertions(+), 391 deletions(-) delete mode 100644 wallet/chain/p/backends/backends.go delete mode 100644 wallet/chain/p/backends/context.go rename wallet/chain/p/{backends => builder}/builder.go (93%) rename wallet/chain/p/{ => builder}/builder_with_options.go (80%) create mode 100644 wallet/chain/p/builder/context.go rename wallet/chain/p/{backends => signer}/signer.go (71%) rename wallet/chain/p/{backends/signer_visitor.go => signer/visitor.go} (85%) diff --git a/tests/antithesis/main.go b/tests/antithesis/main.go index 24f766133309..d33a8808e0f4 100644 --- a/tests/antithesis/main.go +++ b/tests/antithesis/main.go @@ -408,7 +408,9 @@ func (w *workload) issueXToPTransfer(ctx context.Context) { avaxAssetID = xWallet.AVAXAssetID() avaxBalance = balances[avaxAssetID] xBaseTxFee = xWallet.BaseTxFee() - pBaseTxFee = pWallet.BaseTxFee() + pBuilder = pWallet.Builder() + pContext = pBuilder.Context() + pBaseTxFee = pContext.BaseTxFee txFees = xBaseTxFee + pBaseTxFee neededBalance = txFees + units.Avax ) @@ -471,9 +473,10 @@ func (w *workload) issuePToXTransfer(ctx context.Context) { } var ( - avaxAssetID = pWallet.AVAXAssetID() + pContext = pBuilder.Context() + avaxAssetID = pContext.AVAXAssetID avaxBalance = balances[avaxAssetID] - pBaseTxFee = pWallet.BaseTxFee() + pBaseTxFee = pContext.BaseTxFee xBaseTxFee = xWallet.BaseTxFee() txFees = pBaseTxFee + xBaseTxFee neededBalance = txFees + units.Schmeckle diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index a9c70beacbf0..f45a1f8c6669 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -56,6 +56,9 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL cWallet := baseWallet.C() pWallet := baseWallet.P() + pBuilder := pWallet.Builder() + pContext := pBuilder.Context() + ginkgo.By("defining common configuration") recipientEthAddress := evm.GetEthAddress(recipientKey) avaxAssetID := xWallet.AVAXAssetID() @@ -114,7 +117,7 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL Subnet: constants.PrimaryNetworkID, }, nodePOP, - pWallet.AVAXAssetID(), + pContext.AVAXAssetID, &secp256k1fx.OutputOwners{ Threshold: 1, Addrs: []ids.ShortID{rewardKey.Address()}, @@ -143,7 +146,7 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL }, Subnet: constants.PrimaryNetworkID, }, - pWallet.AVAXAssetID(), + pContext.AVAXAssetID, &secp256k1fx.OutputOwners{ Threshold: 1, Addrs: []ids.ShortID{rewardKey.Address()}, diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index 436d89675bc5..e988cf43c2c4 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -104,6 +104,9 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { baseWallet := e2e.NewWallet(keychain, nodeURI) pWallet := baseWallet.P() + pBuilder := pWallet.Builder() + pContext := pBuilder.Context() + const ( delegationPercent = 0.10 // 10% delegationShare = reward.PercentDenominator * delegationPercent @@ -130,7 +133,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { Subnet: constants.PrimaryNetworkID, }, alphaPOP, - pWallet.AVAXAssetID(), + pContext.AVAXAssetID, &secp256k1fx.OutputOwners{ Threshold: 1, Addrs: []ids.ShortID{alphaValidationRewardKey.Address()}, @@ -159,7 +162,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { Subnet: constants.PrimaryNetworkID, }, betaPOP, - pWallet.AVAXAssetID(), + pContext.AVAXAssetID, &secp256k1fx.OutputOwners{ Threshold: 1, Addrs: []ids.ShortID{betaValidationRewardKey.Address()}, @@ -191,7 +194,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { }, Subnet: constants.PrimaryNetworkID, }, - pWallet.AVAXAssetID(), + pContext.AVAXAssetID, &secp256k1fx.OutputOwners{ Threshold: 1, Addrs: []ids.ShortID{gammaDelegationRewardKey.Address()}, @@ -214,7 +217,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { }, Subnet: constants.PrimaryNetworkID, }, - pWallet.AVAXAssetID(), + pContext.AVAXAssetID, &secp256k1fx.OutputOwners{ Threshold: 1, Addrs: []ids.ShortID{deltaDelegationRewardKey.Address()}, @@ -276,7 +279,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { pWallet := baseWallet.P() balances, err := pWallet.Builder().GetBalance() require.NoError(err) - rewardBalances[rewardKey.Address()] = balances[pWallet.AVAXAssetID()] + rewardBalances[rewardKey.Address()] = balances[pContext.AVAXAssetID] } require.Len(rewardBalances, len(rewardKeys)) diff --git a/tests/e2e/p/validator_sets.go b/tests/e2e/p/validator_sets.go index 36072e327a21..a3f3e1e9f075 100644 --- a/tests/e2e/p/validator_sets.go +++ b/tests/e2e/p/validator_sets.go @@ -36,11 +36,14 @@ var _ = e2e.DescribePChain("[Validator Sets]", func() { baseWallet := e2e.NewWallet(keychain, nodeURI) pWallet := baseWallet.P() + pBuilder := pWallet.Builder() + pContext := pBuilder.Context() + const delegatorCount = 15 ginkgo.By(fmt.Sprintf("adding %d delegators", delegatorCount), func() { rewardKey, err := secp256k1.NewPrivateKey() require.NoError(err) - avaxAssetID := pWallet.AVAXAssetID() + avaxAssetID := pContext.AVAXAssetID startTime := time.Now().Add(tmpnet.DefaultValidatorStartTimeDiff) endTime := startTime.Add(time.Second * 360) // This is the default flag value for MinDelegatorStake. diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 1819df448568..7b9e213acaa5 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -41,7 +41,9 @@ var _ = e2e.DescribePChain("[Workflow]", func() { baseWallet := e2e.NewWallet(keychain, nodeURI) pWallet := baseWallet.P() - avaxAssetID := baseWallet.P().AVAXAssetID() + pBuilder := pWallet.Builder() + pContext := pBuilder.Context() + avaxAssetID := pContext.AVAXAssetID xWallet := baseWallet.X() pChainClient := platformvm.NewClient(nodeURI.URI) diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index 3cdafcef9d3e..ed8e6a4f8830 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -4,6 +4,7 @@ package p import ( + "context" "sync" "github.com/ava-labs/avalanchego/database" @@ -13,30 +14,31 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/builder" + "github.com/ava-labs/avalanchego/wallet/chain/p/signer" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - - stdcontext "context" ) var _ Backend = (*backend)(nil) // Backend defines the full interface required to support a P-chain wallet. type Backend interface { - backends.Backend + builder.Backend + signer.Backend - AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error + AcceptTx(ctx context.Context, tx *txs.Tx) error } type backend struct { - backends.Context common.ChainUTXOs + context *builder.Context + subnetOwnerLock sync.RWMutex subnetOwner map[ids.ID]fx.Owner // subnetID -> owner } -func NewBackend(ctx backends.Context, utxos common.ChainUTXOs, subnetTxs map[ids.ID]*txs.Tx) Backend { +func NewBackend(context *builder.Context, utxos common.ChainUTXOs, subnetTxs map[ids.ID]*txs.Tx) Backend { subnetOwner := make(map[ids.ID]fx.Owner) for txID, tx := range subnetTxs { // first get owners from the CreateSubnetTx createSubnetTx, ok := tx.Unsigned.(*txs.CreateSubnetTx) @@ -53,13 +55,13 @@ func NewBackend(ctx backends.Context, utxos common.ChainUTXOs, subnetTxs map[ids subnetOwner[transferSubnetOwnershipTx.Subnet] = transferSubnetOwnershipTx.Owner } return &backend{ - Context: ctx, ChainUTXOs: utxos, + context: context, subnetOwner: subnetOwner, } } -func (b *backend) AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error { +func (b *backend) AcceptTx(ctx context.Context, tx *txs.Tx) error { txID := tx.ID() err := tx.Unsigned.Visit(&backendVisitor{ b: b, @@ -74,7 +76,7 @@ func (b *backend) AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error { return b.addUTXOs(ctx, constants.PlatformChainID, producedUTXOSlice) } -func (b *backend) addUTXOs(ctx stdcontext.Context, destinationChainID ids.ID, utxos []*avax.UTXO) error { +func (b *backend) addUTXOs(ctx context.Context, destinationChainID ids.ID, utxos []*avax.UTXO) error { for _, utxo := range utxos { if err := b.AddUTXO(ctx, destinationChainID, utxo); err != nil { return err @@ -83,7 +85,7 @@ func (b *backend) addUTXOs(ctx stdcontext.Context, destinationChainID ids.ID, ut return nil } -func (b *backend) removeUTXOs(ctx stdcontext.Context, sourceChain ids.ID, utxoIDs set.Set[ids.ID]) error { +func (b *backend) removeUTXOs(ctx context.Context, sourceChain ids.ID, utxoIDs set.Set[ids.ID]) error { for utxoID := range utxoIDs { if err := b.RemoveUTXO(ctx, sourceChain, utxoID); err != nil { return err @@ -92,7 +94,7 @@ func (b *backend) removeUTXOs(ctx stdcontext.Context, sourceChain ids.ID, utxoID return nil } -func (b *backend) GetSubnetOwner(_ stdcontext.Context, subnetID ids.ID) (fx.Owner, error) { +func (b *backend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { b.subnetOwnerLock.RLock() defer b.subnetOwnerLock.RUnlock() diff --git a/wallet/chain/p/backend_visitor.go b/wallet/chain/p/backend_visitor.go index afbaad3a09a8..c7cec9544da1 100644 --- a/wallet/chain/p/backend_visitor.go +++ b/wallet/chain/p/backend_visitor.go @@ -4,30 +4,34 @@ package p import ( + "context" + "errors" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" - - stdcontext "context" ) -var _ txs.Visitor = (*backendVisitor)(nil) +var ( + _ txs.Visitor = (*backendVisitor)(nil) + + ErrUnsupportedTxType = errors.New("unsupported tx type") +) // backendVisitor handles accepting of transactions for the backend type backendVisitor struct { b *backend - ctx stdcontext.Context + ctx context.Context txID ids.ID } func (*backendVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - return backends.ErrUnsupportedTxType + return ErrUnsupportedTxType } func (*backendVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { - return backends.ErrUnsupportedTxType + return ErrUnsupportedTxType } func (b *backendVisitor) AddValidatorTx(tx *txs.AddValidatorTx) error { diff --git a/wallet/chain/p/backends/backends.go b/wallet/chain/p/backends/backends.go deleted file mode 100644 index 77caac1a94ab..000000000000 --- a/wallet/chain/p/backends/backends.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package backends - -import ( - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/fx" - - stdcontext "context" -) - -var ( - _ BuilderBackend = Backend(nil) - _ SignerBackend = Backend(nil) -) - -type Backend interface { - Context - UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) - GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) - GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) -} - -type SignerBackend interface { - GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) - GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) -} - -type BuilderBackend interface { - Context - UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) - GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) -} diff --git a/wallet/chain/p/backends/context.go b/wallet/chain/p/backends/context.go deleted file mode 100644 index 788d9fb4bcf5..000000000000 --- a/wallet/chain/p/backends/context.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package backends - -import ( - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/logging" -) - -const Alias = "P" - -var _ Context = (*builderCtx)(nil) - -type Context interface { - NetworkID() uint32 - AVAXAssetID() ids.ID - BaseTxFee() uint64 - CreateSubnetTxFee() uint64 - TransformSubnetTxFee() uint64 - CreateBlockchainTxFee() uint64 - AddPrimaryNetworkValidatorFee() uint64 - AddPrimaryNetworkDelegatorFee() uint64 - AddSubnetValidatorFee() uint64 - AddSubnetDelegatorFee() uint64 -} - -type builderCtx struct { - networkID uint32 - avaxAssetID ids.ID - baseTxFee uint64 - createSubnetTxFee uint64 - transformSubnetTxFee uint64 - createBlockchainTxFee uint64 - addPrimaryNetworkValidatorFee uint64 - addPrimaryNetworkDelegatorFee uint64 - addSubnetValidatorFee uint64 - addSubnetDelegatorFee uint64 -} - -func NewContext( - networkID uint32, - avaxAssetID ids.ID, - baseTxFee uint64, - createSubnetTxFee uint64, - transformSubnetTxFee uint64, - createBlockchainTxFee uint64, - addPrimaryNetworkValidatorFee uint64, - addPrimaryNetworkDelegatorFee uint64, - addSubnetValidatorFee uint64, - addSubnetDelegatorFee uint64, -) Context { - return &builderCtx{ - networkID: networkID, - avaxAssetID: avaxAssetID, - baseTxFee: baseTxFee, - createSubnetTxFee: createSubnetTxFee, - transformSubnetTxFee: transformSubnetTxFee, - createBlockchainTxFee: createBlockchainTxFee, - addPrimaryNetworkValidatorFee: addPrimaryNetworkValidatorFee, - addPrimaryNetworkDelegatorFee: addPrimaryNetworkDelegatorFee, - addSubnetValidatorFee: addSubnetValidatorFee, - addSubnetDelegatorFee: addSubnetDelegatorFee, - } -} - -func (c *builderCtx) NetworkID() uint32 { - return c.networkID -} - -func (c *builderCtx) AVAXAssetID() ids.ID { - return c.avaxAssetID -} - -func (c *builderCtx) BaseTxFee() uint64 { - return c.baseTxFee -} - -func (c *builderCtx) CreateSubnetTxFee() uint64 { - return c.createSubnetTxFee -} - -func (c *builderCtx) TransformSubnetTxFee() uint64 { - return c.transformSubnetTxFee -} - -func (c *builderCtx) CreateBlockchainTxFee() uint64 { - return c.createBlockchainTxFee -} - -func (c *builderCtx) AddPrimaryNetworkValidatorFee() uint64 { - return c.addPrimaryNetworkValidatorFee -} - -func (c *builderCtx) AddPrimaryNetworkDelegatorFee() uint64 { - return c.addPrimaryNetworkDelegatorFee -} - -func (c *builderCtx) AddSubnetValidatorFee() uint64 { - return c.addSubnetValidatorFee -} - -func (c *builderCtx) AddSubnetDelegatorFee() uint64 { - return c.addSubnetDelegatorFee -} - -func NewSnowContext(networkID uint32, avaxAssetID ids.ID) (*snow.Context, error) { - lookup := ids.NewAliaser() - return &snow.Context{ - NetworkID: networkID, - SubnetID: constants.PrimaryNetworkID, - ChainID: constants.PlatformChainID, - AVAXAssetID: avaxAssetID, - Log: logging.NoLog{}, - BCLookup: lookup, - }, lookup.Alias(constants.PlatformChainID, Alias) -} diff --git a/wallet/chain/p/backends/builder.go b/wallet/chain/p/builder/builder.go similarity index 93% rename from wallet/chain/p/backends/builder.go rename to wallet/chain/p/builder/builder.go index 6c041f1fa607..70433b11dac8 100644 --- a/wallet/chain/p/backends/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -1,9 +1,10 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package backends +package builder import ( + "context" "errors" "fmt" "time" @@ -14,6 +15,7 @@ import ( "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" + "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" @@ -23,6 +25,7 @@ import ( var ( errNoChangeAddress = errors.New("no possible change address") + ErrUnknownOutputType = errors.New("unknown output type") errUnknownOwnerType = errors.New("unknown owner type") errInsufficientAuthorization = errors.New("insufficient authorization") ErrInsufficientFunds = errors.New("insufficient funds") @@ -33,6 +36,10 @@ var ( // Builder provides a convenient interface for building unsigned P-chain // transactions. type Builder interface { + // Context returns the configuration of the chain that this builder uses to + // create transactions. + Context() *Context + // GetBalance calculates the amount of each asset that this builder has // control over. GetBalance( @@ -251,24 +258,39 @@ type Builder interface { ) (*txs.AddPermissionlessDelegatorTx, error) } +type Backend interface { + UTXOs(ctx context.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) + GetSubnetOwner(ctx context.Context, subnetID ids.ID) (fx.Owner, error) +} + type builder struct { addrs set.Set[ids.ShortID] - backend BuilderBackend + context *Context + backend Backend } -// NewBuilder returns a new transaction builder. +// New returns a new transaction builder. // // - [addrs] is the set of addresses that the builder assumes can be used when // signing the transactions in the future. -// - [backend] provides the required access to the chain's context and state -// to build out the transactions. -func NewBuilder(addrs set.Set[ids.ShortID], backend BuilderBackend) Builder { +// - [context] provides the chain's configuration. +// - [backend] provides the chain's state. +func New( + addrs set.Set[ids.ShortID], + context *Context, + backend Backend, +) Builder { return &builder{ addrs: addrs, + context: context, backend: backend, } } +func (b *builder) Context() *Context { + return b.context +} + func (b *builder) GetBalance( options ...common.Option, ) (map[ids.ID]uint64, error) { @@ -289,7 +311,7 @@ func (b *builder) NewBaseTx( options ...common.Option, ) (*txs.BaseTx, error) { toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.BaseTxFee(), + b.context.AVAXAssetID: b.context.BaseTxFee, } for _, out := range outputs { assetID := out.AssetID() @@ -310,7 +332,7 @@ func (b *builder) NewBaseTx( avax.SortTransferableOutputs(outputs, txs.Codec) // sort the outputs tx := &txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: outputs, @@ -325,9 +347,9 @@ func (b *builder) NewAddValidatorTx( shares uint32, options ...common.Option, ) (*txs.AddValidatorTx, error) { - avaxAssetID := b.backend.AVAXAssetID() + avaxAssetID := b.context.AVAXAssetID toBurn := map[ids.ID]uint64{ - avaxAssetID: b.backend.AddPrimaryNetworkValidatorFee(), + avaxAssetID: b.context.AddPrimaryNetworkValidatorFee, } toStake := map[ids.ID]uint64{ avaxAssetID: vdr.Wght, @@ -341,7 +363,7 @@ func (b *builder) NewAddValidatorTx( utils.Sort(rewardsOwner.Addrs) tx := &txs.AddValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: baseOutputs, @@ -360,7 +382,7 @@ func (b *builder) NewAddSubnetValidatorTx( options ...common.Option, ) (*txs.AddSubnetValidatorTx, error) { toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.AddSubnetValidatorFee(), + b.context.AVAXAssetID: b.context.AddSubnetValidatorFee, } toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) @@ -376,7 +398,7 @@ func (b *builder) NewAddSubnetValidatorTx( tx := &txs.AddSubnetValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: outputs, @@ -394,7 +416,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( options ...common.Option, ) (*txs.RemoveSubnetValidatorTx, error) { toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.BaseTxFee(), + b.context.AVAXAssetID: b.context.BaseTxFee, } toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) @@ -410,7 +432,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( tx := &txs.RemoveSubnetValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: outputs, @@ -428,12 +450,12 @@ func (b *builder) NewAddDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.AddDelegatorTx, error) { - avaxAssetID := b.backend.AVAXAssetID() + avaxAssetID := b.context.AVAXAssetID toBurn := map[ids.ID]uint64{ - avaxAssetID: b.backend.AddPrimaryNetworkDelegatorFee(), + avaxAssetID: b.context.AddPrimaryNetworkDelegatorFee, } toStake := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): vdr.Wght, + avaxAssetID: vdr.Wght, } ops := common.NewOptions(options) inputs, baseOutputs, stakeOutputs, err := b.spend(toBurn, toStake, ops) @@ -444,7 +466,7 @@ func (b *builder) NewAddDelegatorTx( utils.Sort(rewardsOwner.Addrs) tx := &txs.AddDelegatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: baseOutputs, @@ -466,7 +488,7 @@ func (b *builder) NewCreateChainTx( options ...common.Option, ) (*txs.CreateChainTx, error) { toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.CreateBlockchainTxFee(), + b.context.AVAXAssetID: b.context.CreateBlockchainTxFee, } toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) @@ -483,7 +505,7 @@ func (b *builder) NewCreateChainTx( utils.Sort(fxIDs) tx := &txs.CreateChainTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: outputs, @@ -504,7 +526,7 @@ func (b *builder) NewCreateSubnetTx( options ...common.Option, ) (*txs.CreateSubnetTx, error) { toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.CreateSubnetTxFee(), + b.context.AVAXAssetID: b.context.CreateSubnetTxFee, } toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) @@ -516,7 +538,7 @@ func (b *builder) NewCreateSubnetTx( utils.Sort(owner.Addrs) tx := &txs.CreateSubnetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: outputs, @@ -533,7 +555,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( options ...common.Option, ) (*txs.TransferSubnetOwnershipTx, error) { toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.BaseTxFee(), + b.context.AVAXAssetID: b.context.BaseTxFee, } toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) @@ -550,7 +572,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( utils.Sort(owner.Addrs) tx := &txs.TransferSubnetOwnershipTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: outputs, @@ -577,8 +599,8 @@ func (b *builder) NewImportTx( var ( addrs = ops.Addresses(b.addrs) minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - txFee = b.backend.BaseTxFee() + avaxAssetID = b.context.AVAXAssetID + txFee = b.context.BaseTxFee importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) importedAmounts = make(map[ids.ID]uint64) @@ -658,7 +680,7 @@ func (b *builder) NewImportTx( avax.SortTransferableOutputs(outputs, txs.Codec) // sort imported outputs tx := &txs.ImportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: outputs, @@ -676,7 +698,7 @@ func (b *builder) NewExportTx( options ...common.Option, ) (*txs.ExportTx, error) { toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.BaseTxFee(), + b.context.AVAXAssetID: b.context.BaseTxFee, } for _, out := range outputs { assetID := out.AssetID() @@ -697,7 +719,7 @@ func (b *builder) NewExportTx( avax.SortTransferableOutputs(outputs, txs.Codec) // sort exported outputs tx := &txs.ExportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: changeOutputs, @@ -727,8 +749,8 @@ func (b *builder) NewTransformSubnetTx( options ...common.Option, ) (*txs.TransformSubnetTx, error) { toBurn := map[ids.ID]uint64{ - b.backend.AVAXAssetID(): b.backend.TransformSubnetTxFee(), - assetID: maxSupply - initialSupply, + b.context.AVAXAssetID: b.context.TransformSubnetTxFee, + assetID: maxSupply - initialSupply, } toStake := map[ids.ID]uint64{} ops := common.NewOptions(options) @@ -744,7 +766,7 @@ func (b *builder) NewTransformSubnetTx( tx := &txs.TransformSubnetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: outputs, @@ -778,12 +800,12 @@ func (b *builder) NewAddPermissionlessValidatorTx( shares uint32, options ...common.Option, ) (*txs.AddPermissionlessValidatorTx, error) { - avaxAssetID := b.backend.AVAXAssetID() + avaxAssetID := b.context.AVAXAssetID toBurn := map[ids.ID]uint64{} if vdr.Subnet == constants.PrimaryNetworkID { - toBurn[avaxAssetID] = b.backend.AddPrimaryNetworkValidatorFee() + toBurn[avaxAssetID] = b.context.AddPrimaryNetworkValidatorFee } else { - toBurn[avaxAssetID] = b.backend.AddSubnetValidatorFee() + toBurn[avaxAssetID] = b.context.AddSubnetValidatorFee } toStake := map[ids.ID]uint64{ assetID: vdr.Wght, @@ -798,7 +820,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( utils.Sort(delegationRewardsOwner.Addrs) tx := &txs.AddPermissionlessValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: baseOutputs, @@ -821,12 +843,12 @@ func (b *builder) NewAddPermissionlessDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.AddPermissionlessDelegatorTx, error) { - avaxAssetID := b.backend.AVAXAssetID() + avaxAssetID := b.context.AVAXAssetID toBurn := map[ids.ID]uint64{} if vdr.Subnet == constants.PrimaryNetworkID { - toBurn[avaxAssetID] = b.backend.AddPrimaryNetworkDelegatorFee() + toBurn[avaxAssetID] = b.context.AddPrimaryNetworkDelegatorFee } else { - toBurn[avaxAssetID] = b.backend.AddSubnetDelegatorFee() + toBurn[avaxAssetID] = b.context.AddSubnetDelegatorFee } toStake := map[ids.ID]uint64{ assetID: vdr.Wght, @@ -840,7 +862,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( utils.Sort(rewardsOwner.Addrs) tx := &txs.AddPermissionlessDelegatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: b.backend.NetworkID(), + NetworkID: b.context.NetworkID, BlockchainID: constants.PlatformChainID, Ins: inputs, Outs: baseOutputs, @@ -1157,7 +1179,7 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se } func (b *builder) initCtx(tx txs.UnsignedTx) error { - ctx, err := NewSnowContext(b.backend.NetworkID(), b.backend.AVAXAssetID()) + ctx, err := newSnowContext(b.context.NetworkID, b.context.AVAXAssetID) if err != nil { return err } diff --git a/wallet/chain/p/builder_with_options.go b/wallet/chain/p/builder/builder_with_options.go similarity index 80% rename from wallet/chain/p/builder_with_options.go rename to wallet/chain/p/builder/builder_with_options.go index 7bfaf0046308..d831e0c76daa 100644 --- a/wallet/chain/p/builder_with_options.go +++ b/wallet/chain/p/builder/builder_with_options.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package p +package builder import ( "time" @@ -11,35 +11,38 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) -var _ backends.Builder = (*builderWithOptions)(nil) +var _ Builder = (*builderWithOptions)(nil) type builderWithOptions struct { - backends.Builder + builder Builder options []common.Option } -// NewBuilderWithOptions returns a new transaction builder that will use the -// given options by default. +// NewWithOptions returns a new builder that will use the given options by +// default. // // - [builder] is the builder that will be called to perform the underlying // operations. // - [options] will be provided to the builder in addition to the options // provided in the method calls. -func NewBuilderWithOptions(builder backends.Builder, options ...common.Option) backends.Builder { +func NewWithOptions(builder Builder, options ...common.Option) Builder { return &builderWithOptions{ - Builder: builder, + builder: builder, options: options, } } +func (b *builderWithOptions) Context() *Context { + return b.builder.Context() +} + func (b *builderWithOptions) GetBalance( options ...common.Option, ) (map[ids.ID]uint64, error) { - return b.Builder.GetBalance( + return b.builder.GetBalance( common.UnionOptions(b.options, options)..., ) } @@ -48,19 +51,29 @@ func (b *builderWithOptions) GetImportableBalance( chainID ids.ID, options ...common.Option, ) (map[ids.ID]uint64, error) { - return b.Builder.GetImportableBalance( + return b.builder.GetImportableBalance( chainID, common.UnionOptions(b.options, options)..., ) } +func (b *builderWithOptions) NewBaseTx( + outputs []*avax.TransferableOutput, + options ...common.Option, +) (*txs.BaseTx, error) { + return b.builder.NewBaseTx( + outputs, + common.UnionOptions(b.options, options)..., + ) +} + func (b *builderWithOptions) NewAddValidatorTx( vdr *txs.Validator, rewardsOwner *secp256k1fx.OutputOwners, shares uint32, options ...common.Option, ) (*txs.AddValidatorTx, error) { - return b.Builder.NewAddValidatorTx( + return b.builder.NewAddValidatorTx( vdr, rewardsOwner, shares, @@ -72,18 +85,18 @@ func (b *builderWithOptions) NewAddSubnetValidatorTx( vdr *txs.SubnetValidator, options ...common.Option, ) (*txs.AddSubnetValidatorTx, error) { - return b.Builder.NewAddSubnetValidatorTx( + return b.builder.NewAddSubnetValidatorTx( vdr, common.UnionOptions(b.options, options)..., ) } -func (b *builderWithOptions) RemoveSubnetValidatorTx( +func (b *builderWithOptions) NewRemoveSubnetValidatorTx( nodeID ids.NodeID, subnetID ids.ID, options ...common.Option, ) (*txs.RemoveSubnetValidatorTx, error) { - return b.Builder.NewRemoveSubnetValidatorTx( + return b.builder.NewRemoveSubnetValidatorTx( nodeID, subnetID, common.UnionOptions(b.options, options)..., @@ -95,7 +108,7 @@ func (b *builderWithOptions) NewAddDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.AddDelegatorTx, error) { - return b.Builder.NewAddDelegatorTx( + return b.builder.NewAddDelegatorTx( vdr, rewardsOwner, common.UnionOptions(b.options, options)..., @@ -110,7 +123,7 @@ func (b *builderWithOptions) NewCreateChainTx( chainName string, options ...common.Option, ) (*txs.CreateChainTx, error) { - return b.Builder.NewCreateChainTx( + return b.builder.NewCreateChainTx( subnetID, genesis, vmID, @@ -124,7 +137,7 @@ func (b *builderWithOptions) NewCreateSubnetTx( owner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.CreateSubnetTx, error) { - return b.Builder.NewCreateSubnetTx( + return b.builder.NewCreateSubnetTx( owner, common.UnionOptions(b.options, options)..., ) @@ -135,7 +148,7 @@ func (b *builderWithOptions) NewTransferSubnetOwnershipTx( owner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.TransferSubnetOwnershipTx, error) { - return b.Builder.NewTransferSubnetOwnershipTx( + return b.builder.NewTransferSubnetOwnershipTx( subnetID, owner, common.UnionOptions(b.options, options)..., @@ -147,7 +160,7 @@ func (b *builderWithOptions) NewImportTx( to *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.ImportTx, error) { - return b.Builder.NewImportTx( + return b.builder.NewImportTx( sourceChainID, to, common.UnionOptions(b.options, options)..., @@ -159,7 +172,7 @@ func (b *builderWithOptions) NewExportTx( outputs []*avax.TransferableOutput, options ...common.Option, ) (*txs.ExportTx, error) { - return b.Builder.NewExportTx( + return b.builder.NewExportTx( chainID, outputs, common.UnionOptions(b.options, options)..., @@ -183,7 +196,7 @@ func (b *builderWithOptions) NewTransformSubnetTx( uptimeRequirement uint32, options ...common.Option, ) (*txs.TransformSubnetTx, error) { - return b.Builder.NewTransformSubnetTx( + return b.builder.NewTransformSubnetTx( subnetID, assetID, initialSupply, @@ -211,7 +224,7 @@ func (b *builderWithOptions) NewAddPermissionlessValidatorTx( shares uint32, options ...common.Option, ) (*txs.AddPermissionlessValidatorTx, error) { - return b.Builder.NewAddPermissionlessValidatorTx( + return b.builder.NewAddPermissionlessValidatorTx( vdr, signer, assetID, @@ -228,7 +241,7 @@ func (b *builderWithOptions) NewAddPermissionlessDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.AddPermissionlessDelegatorTx, error) { - return b.Builder.NewAddPermissionlessDelegatorTx( + return b.builder.NewAddPermissionlessDelegatorTx( vdr, assetID, rewardsOwner, diff --git a/wallet/chain/p/builder/context.go b/wallet/chain/p/builder/context.go new file mode 100644 index 000000000000..4b03cd41dce2 --- /dev/null +++ b/wallet/chain/p/builder/context.go @@ -0,0 +1,38 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package builder + +import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" +) + +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 +} + +func newSnowContext(networkID uint32, avaxAssetID ids.ID) (*snow.Context, error) { + lookup := ids.NewAliaser() + return &snow.Context{ + NetworkID: networkID, + SubnetID: constants.PrimaryNetworkID, + ChainID: constants.PlatformChainID, + AVAXAssetID: avaxAssetID, + Log: logging.NoLog{}, + BCLookup: lookup, + }, lookup.Alias(constants.PlatformChainID, Alias) +} diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 9f99202d33ed..9f73b9e399b9 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -21,7 +21,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/builder" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -33,22 +33,22 @@ var ( avaxAssetID = ids.Empty.Prefix(1789) subnetAssetID = ids.Empty.Prefix(2024) - testCtx = backends.NewContext( - constants.UnitTestID, - avaxAssetID, - units.MicroAvax, // BaseTxFee - 19*units.MicroAvax, // CreateSubnetTxFee - 789*units.MicroAvax, // TransformSubnetTxFee - 1234*units.MicroAvax, // CreateBlockchainTxFee - 19*units.MilliAvax, // AddPrimaryNetworkValidatorFee - 765*units.MilliAvax, // AddPrimaryNetworkDelegatorFee - 1010*units.MilliAvax, // AddSubnetValidatorFee - 9*units.Avax, // AddSubnetDelegatorFee - ) + 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, + } ) -// These tests create and sign a tx, then verify that utxos included -// in the tx are exactly necessary to pay fees for it +// These tests create a tx, then verify that utxos included in the tx are +// exactly necessary to pay fees for it. func TestBaseTx(t *testing.T) { var ( @@ -60,11 +60,11 @@ func TestBaseTx(t *testing.T) { chainUTXOs = common.NewDeterministicChainUTXOs(require, map[ids.ID][]*avax.UTXO{ constants.PlatformChainID: utxos, }) - backend = NewBackend(testCtx, chainUTXOs, nil) + backend = NewBackend(testContext, chainUTXOs, nil) // builder utxoAddr = utxosKey.Address() - builder = backends.NewBuilder(set.Of(utxoAddr), backend) + builder = builder.New(set.Of(utxoAddr), testContext, backend) // data to build the transaction outputsToMove = []*avax.TransferableOutput{{ @@ -88,7 +88,7 @@ func TestBaseTx(t *testing.T) { require.Len(ins, 2) require.Len(outs, 2) - expectedConsumed := testCtx.BaseTxFee() + outputsToMove[0].Out.Amount() + expectedConsumed := testContext.BaseTxFee + outputsToMove[0].Out.Amount() consumed := ins[0].In.Amount() + ins[1].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) require.Equal(outputsToMove[0], outs[1]) @@ -120,11 +120,11 @@ func TestAddSubnetValidatorTx(t *testing.T) { }, } - backend = NewBackend(testCtx, chainUTXOs, subnets) + backend = NewBackend(testContext, chainUTXOs, subnets) // builder utxoAddr = utxosKey.Address() - builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = builder.New(set.Of(utxoAddr, subnetAuthAddr), testContext, backend) // data to build the transaction subnetValidator = &txs.SubnetValidator{ @@ -146,7 +146,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { require.Len(ins, 2) require.Len(outs, 1) - expectedConsumed := testCtx.AddSubnetValidatorFee() + expectedConsumed := testContext.AddSubnetValidatorFee consumed := ins[0].In.Amount() + ins[1].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) } @@ -177,11 +177,11 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { }, } - backend = NewBackend(testCtx, chainUTXOs, subnets) + backend = NewBackend(testContext, chainUTXOs, subnets) // builder utxoAddr = utxosKey.Address() - builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = builder.New(set.Of(utxoAddr, subnetAuthAddr), testContext, backend) ) // build the transaction @@ -197,7 +197,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { require.Len(ins, 1) require.Len(outs, 1) - expectedConsumed := testCtx.BaseTxFee() + expectedConsumed := testContext.BaseTxFee consumed := ins[0].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) } @@ -228,10 +228,10 @@ func TestCreateChainTx(t *testing.T) { }, } - backend = NewBackend(testCtx, chainUTXOs, subnets) + backend = NewBackend(testContext, chainUTXOs, subnets) utxoAddr = utxosKey.Address() - builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = builder.New(set.Of(utxoAddr, subnetAuthAddr), testContext, backend) // data to build the transaction genesisBytes = []byte{'a', 'b', 'c'} @@ -256,7 +256,7 @@ func TestCreateChainTx(t *testing.T) { require.Len(ins, 1) require.Len(outs, 1) - expectedConsumed := testCtx.CreateBlockchainTxFee() + expectedConsumed := testContext.CreateBlockchainTxFee consumed := ins[0].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) } @@ -287,11 +287,11 @@ func TestCreateSubnetTx(t *testing.T) { }, } - backend = NewBackend(testCtx, chainUTXOs, subnets) + backend = NewBackend(testContext, chainUTXOs, subnets) // builder utxoAddr = utxosKey.Address() - builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = builder.New(set.Of(utxoAddr, subnetAuthAddr), testContext, backend) ) // build the transaction @@ -304,7 +304,7 @@ func TestCreateSubnetTx(t *testing.T) { require.Len(ins, 1) require.Len(outs, 1) - expectedConsumed := testCtx.CreateSubnetTxFee() + expectedConsumed := testContext.CreateSubnetTxFee consumed := ins[0].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) } @@ -335,11 +335,11 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { }, } - backend = NewBackend(testCtx, chainUTXOs, subnets) + backend = NewBackend(testContext, chainUTXOs, subnets) // builder utxoAddr = utxosKey.Address() - builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = builder.New(set.Of(utxoAddr, subnetAuthAddr), testContext, backend) ) // build the transaction @@ -355,7 +355,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { require.Len(ins, 1) require.Len(outs, 1) - expectedConsumed := testCtx.BaseTxFee() + expectedConsumed := testContext.BaseTxFee consumed := ins[0].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) } @@ -374,11 +374,11 @@ func TestImportTx(t *testing.T) { sourceChainID: importedUTXOs, }) - backend = NewBackend(testCtx, chainUTXOs, nil) + backend = NewBackend(testContext, chainUTXOs, nil) // builder utxoAddr = utxosKey.Address() - builder = backends.NewBuilder(set.Of(utxoAddr), backend) + builder = builder.New(set.Of(utxoAddr), testContext, backend) // data to build the transaction importKey = testKeys[0] @@ -405,7 +405,7 @@ func TestImportTx(t *testing.T) { require.Len(importedIns, 1) require.Len(outs, 1) - expectedConsumed := testCtx.BaseTxFee() + expectedConsumed := testContext.BaseTxFee consumed := importedIns[0].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) } @@ -420,11 +420,11 @@ func TestExportTx(t *testing.T) { chainUTXOs = common.NewDeterministicChainUTXOs(require, map[ids.ID][]*avax.UTXO{ constants.PlatformChainID: utxos, }) - backend = NewBackend(testCtx, chainUTXOs, nil) + backend = NewBackend(testContext, chainUTXOs, nil) // builder utxoAddr = utxosKey.Address() - builder = backends.NewBuilder(set.Of(utxoAddr), backend) + builder = builder.New(set.Of(utxoAddr), testContext, backend) // data to build the transaction subnetID = ids.GenerateTestID() @@ -453,7 +453,7 @@ func TestExportTx(t *testing.T) { require.Len(ins, 2) require.Len(outs, 1) - expectedConsumed := testCtx.BaseTxFee() + exportedOutputs[0].Out.Amount() + expectedConsumed := testContext.BaseTxFee + exportedOutputs[0].Out.Amount() consumed := ins[0].In.Amount() + ins[1].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) require.Equal(utx.ExportedOutputs, exportedOutputs) @@ -485,11 +485,11 @@ func TestTransformSubnetTx(t *testing.T) { }, } - backend = NewBackend(testCtx, chainUTXOs, subnets) + backend = NewBackend(testContext, chainUTXOs, subnets) // builder utxoAddr = utxosKey.Address() - builder = backends.NewBuilder(set.Of(utxoAddr, subnetAuthAddr), backend) + builder = builder.New(set.Of(utxoAddr, subnetAuthAddr), testContext, backend) // data to build the transaction initialSupply = 40 * units.MegaAvax @@ -524,7 +524,7 @@ func TestTransformSubnetTx(t *testing.T) { expectedConsumedSubnetAsset := maxSupply - initialSupply consumedSubnetAsset := ins[0].In.Amount() - outs[1].Out.Amount() require.Equal(expectedConsumedSubnetAsset, consumedSubnetAsset) - expectedConsumed := testCtx.TransformSubnetTxFee() + expectedConsumed := testContext.TransformSubnetTxFee consumed := ins[1].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) } @@ -539,13 +539,13 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { chainUTXOs = common.NewDeterministicChainUTXOs(require, map[ids.ID][]*avax.UTXO{ constants.PlatformChainID: utxos, }) - backend = NewBackend(testCtx, chainUTXOs, nil) + backend = NewBackend(testContext, chainUTXOs, nil) // builder utxoAddr = utxosKey.Address() rewardKey = testKeys[0] rewardAddr = rewardKey.Address() - builder = backends.NewBuilder(set.Of(utxoAddr, rewardAddr), backend) + builder = builder.New(set.Of(utxoAddr, rewardAddr), testContext, backend) // data to build the transaction validationRewardsOwner = &secp256k1fx.OutputOwners{ @@ -594,7 +594,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { expectedConsumedSubnetAsset := utx.Validator.Weight() consumedSubnetAsset := staked[0].Out.Amount() + staked[1].Out.Amount() require.Equal(expectedConsumedSubnetAsset, consumedSubnetAsset) - expectedConsumed := testCtx.AddPrimaryNetworkValidatorFee() + expectedConsumed := testContext.AddPrimaryNetworkValidatorFee consumed := ins[1].In.Amount() + ins[3].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) } @@ -609,13 +609,13 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { chainUTXOs = common.NewDeterministicChainUTXOs(require, map[ids.ID][]*avax.UTXO{ constants.PlatformChainID: utxos, }) - backend = NewBackend(testCtx, chainUTXOs, nil) + backend = NewBackend(testContext, chainUTXOs, nil) // builder utxoAddr = utxosKey.Address() rewardKey = testKeys[0] rewardAddr = rewardKey.Address() - builder = backends.NewBuilder(set.Of(utxoAddr, rewardAddr), backend) + builder = builder.New(set.Of(utxoAddr, rewardAddr), testContext, backend) // data to build the transaction rewardsOwner = &secp256k1fx.OutputOwners{ @@ -652,7 +652,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { expectedConsumedSubnetAsset := utx.Validator.Weight() consumedSubnetAsset := staked[0].Out.Amount() + staked[1].Out.Amount() require.Equal(expectedConsumedSubnetAsset, consumedSubnetAsset) - expectedConsumed := testCtx.AddPrimaryNetworkDelegatorFee() + expectedConsumed := testContext.AddPrimaryNetworkDelegatorFee consumed := ins[1].In.Amount() + ins[3].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) } diff --git a/wallet/chain/p/context.go b/wallet/chain/p/context.go index 862e2364525a..057d5553ea02 100644 --- a/wallet/chain/p/context.go +++ b/wallet/chain/p/context.go @@ -4,24 +4,24 @@ package p import ( + "context" + "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/vms/avm" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" - - stdcontext "context" + "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) -func NewContextFromURI(ctx stdcontext.Context, uri string) (backends.Context, error) { +func NewContextFromURI(ctx context.Context, uri string) (*builder.Context, error) { infoClient := info.NewClient(uri) xChainClient := avm.NewClient(uri, "X") return NewContextFromClients(ctx, infoClient, xChainClient) } func NewContextFromClients( - ctx stdcontext.Context, + ctx context.Context, infoClient info.Client, xChainClient avm.Client, -) (backends.Context, error) { +) (*builder.Context, error) { networkID, err := infoClient.GetNetworkID(ctx) if err != nil { return nil, err @@ -37,16 +37,16 @@ func NewContextFromClients( return nil, err } - return backends.NewContext( - networkID, - asset.AssetID, - uint64(txFees.TxFee), - uint64(txFees.CreateSubnetTxFee), - uint64(txFees.TransformSubnetTxFee), - uint64(txFees.CreateBlockchainTxFee), - uint64(txFees.AddPrimaryNetworkValidatorFee), - uint64(txFees.AddPrimaryNetworkDelegatorFee), - uint64(txFees.AddSubnetValidatorFee), - uint64(txFees.AddSubnetDelegatorFee), - ), nil + return &builder.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), + }, nil } diff --git a/wallet/chain/p/backends/signer.go b/wallet/chain/p/signer/signer.go similarity index 71% rename from wallet/chain/p/backends/signer.go rename to wallet/chain/p/signer/signer.go index 6b99cba60cf5..08b3a9d9963b 100644 --- a/wallet/chain/p/backends/signer.go +++ b/wallet/chain/p/signer/signer.go @@ -1,10 +1,13 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package backends +package signer import ( + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/keychain" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/txs" stdcontext "context" @@ -24,12 +27,17 @@ type Signer interface { Sign(ctx stdcontext.Context, tx *txs.Tx) error } +type Backend interface { + GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) + GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) +} + type txSigner struct { kc keychain.Keychain - backend SignerBackend + backend Backend } -func NewSigner(kc keychain.Keychain, backend SignerBackend) Signer { +func New(kc keychain.Keychain, backend Backend) Signer { return &txSigner{ kc: kc, backend: backend, @@ -37,7 +45,7 @@ func NewSigner(kc keychain.Keychain, backend SignerBackend) Signer { } func (s *txSigner) Sign(ctx stdcontext.Context, tx *txs.Tx) error { - return tx.Unsigned.Visit(&signerVisitor{ + return tx.Unsigned.Visit(&visitor{ kc: s.kc, backend: s.backend, ctx: ctx, diff --git a/wallet/chain/p/backends/signer_visitor.go b/wallet/chain/p/signer/visitor.go similarity index 85% rename from wallet/chain/p/backends/signer_visitor.go rename to wallet/chain/p/signer/visitor.go index 5a237cfc499c..58d6a5e0b3c0 100644 --- a/wallet/chain/p/backends/signer_visitor.go +++ b/wallet/chain/p/signer/visitor.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package backends +package signer import ( "context" @@ -22,7 +22,7 @@ import ( ) var ( - _ txs.Visitor = (*signerVisitor)(nil) + _ txs.Visitor = (*visitor)(nil) ErrUnknownOwnerType = errors.New("unknown owner type") ErrUnknownOutputType = errors.New("unknown output type") @@ -35,23 +35,23 @@ var ( emptySig [secp256k1.SignatureLen]byte ) -// signerVisitor handles signing transactions for the signer -type signerVisitor struct { +// visitor handles signing transactions for the signer +type visitor struct { kc keychain.Keychain - backend SignerBackend + backend Backend ctx context.Context tx *txs.Tx } -func (*signerVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { +func (*visitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error { return ErrUnsupportedTxType } -func (*signerVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error { +func (*visitor) RewardValidatorTx(*txs.RewardValidatorTx) error { return ErrUnsupportedTxType } -func (s *signerVisitor) BaseTx(tx *txs.BaseTx) error { +func (s *visitor) BaseTx(tx *txs.BaseTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -59,7 +59,7 @@ func (s *signerVisitor) BaseTx(tx *txs.BaseTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) AddValidatorTx(tx *txs.AddValidatorTx) error { +func (s *visitor) AddValidatorTx(tx *txs.AddValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -67,7 +67,7 @@ func (s *signerVisitor) AddValidatorTx(tx *txs.AddValidatorTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { +func (s *visitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -80,7 +80,7 @@ func (s *signerVisitor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error return sign(s.tx, false, txSigners) } -func (s *signerVisitor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { +func (s *visitor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -88,7 +88,7 @@ func (s *signerVisitor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) CreateChainTx(tx *txs.CreateChainTx) error { +func (s *visitor) CreateChainTx(tx *txs.CreateChainTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -101,7 +101,7 @@ func (s *signerVisitor) CreateChainTx(tx *txs.CreateChainTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { +func (s *visitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -109,7 +109,7 @@ func (s *signerVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) ImportTx(tx *txs.ImportTx) error { +func (s *visitor) ImportTx(tx *txs.ImportTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -122,7 +122,7 @@ func (s *signerVisitor) ImportTx(tx *txs.ImportTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) ExportTx(tx *txs.ExportTx) error { +func (s *visitor) ExportTx(tx *txs.ExportTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -130,7 +130,7 @@ func (s *signerVisitor) ExportTx(tx *txs.ExportTx) error { return sign(s.tx, false, txSigners) } -func (s *signerVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { +func (s *visitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -143,7 +143,7 @@ func (s *signerVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) return sign(s.tx, true, txSigners) } -func (s *signerVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { +func (s *visitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -156,7 +156,7 @@ func (s *signerVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershi return sign(s.tx, true, txSigners) } -func (s *signerVisitor) TransformSubnetTx(tx *txs.TransformSubnetTx) error { +func (s *visitor) TransformSubnetTx(tx *txs.TransformSubnetTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -169,7 +169,7 @@ func (s *signerVisitor) TransformSubnetTx(tx *txs.TransformSubnetTx) error { return sign(s.tx, true, txSigners) } -func (s *signerVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { +func (s *visitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -177,7 +177,7 @@ func (s *signerVisitor) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessVa return sign(s.tx, true, txSigners) } -func (s *signerVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { +func (s *visitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { txSigners, err := s.getSigners(constants.PlatformChainID, tx.Ins) if err != nil { return err @@ -185,7 +185,7 @@ func (s *signerVisitor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDe return sign(s.tx, true, txSigners) } -func (s *signerVisitor) getSigners(sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { +func (s *visitor) getSigners(sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { txSigners := make([][]keychain.Signer, len(ins)) for credIndex, transferInput := range ins { inIntf := transferInput.In @@ -240,7 +240,7 @@ func (s *signerVisitor) getSigners(sourceChainID ids.ID, ins []*avax.Transferabl return txSigners, nil } -func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Verifiable) ([]keychain.Signer, error) { +func (s *visitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Verifiable) ([]keychain.Signer, error) { subnetInput, ok := subnetAuth.(*secp256k1fx.Input) if !ok { return nil, errUnknownSubnetAuthType diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 0647d7e8db33..e5952f1067c6 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -11,12 +11,14 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" - "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/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/builder" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + vmsigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" + walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) var ( @@ -26,13 +28,11 @@ var ( ) type Wallet interface { - backends.Context - // Builder returns the builder that will be used to create the transactions. - Builder() backends.Builder + Builder() builder.Builder // Signer returns the signer that will be used to sign the transactions. - Signer() backends.Signer + Signer() walletsigner.Signer // IssueBaseTx creates, signs, and issues a new simple value transfer. // @@ -220,7 +220,7 @@ type Wallet interface { // the delegation reward will be sent to the validator's [rewardsOwner]. IssueAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer signer.Signer, + signer vmsigner.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, @@ -257,8 +257,8 @@ type Wallet interface { } func NewWallet( - builder backends.Builder, - signer backends.Signer, + builder builder.Builder, + signer walletsigner.Signer, client platformvm.Client, backend Backend, ) Wallet { @@ -272,16 +272,16 @@ func NewWallet( type wallet struct { Backend - builder backends.Builder - signer backends.Signer + builder builder.Builder + signer walletsigner.Signer client platformvm.Client } -func (w *wallet) Builder() backends.Builder { +func (w *wallet) Builder() builder.Builder { return w.builder } -func (w *wallet) Signer() backends.Signer { +func (w *wallet) Signer() walletsigner.Signer { return w.signer } @@ -448,7 +448,7 @@ func (w *wallet) IssueTransformSubnetTx( func (w *wallet) IssueAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer signer.Signer, + signer vmsigner.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, @@ -494,7 +494,7 @@ func (w *wallet) IssueUnsignedTx( ) (*txs.Tx, error) { ops := common.NewOptions(options) ctx := ops.Context() - tx, err := backends.SignUnsigned(ctx, w.signer, utx) + tx, err := walletsigner.SignUnsigned(ctx, w.signer, utx) if err != nil { return nil, err } diff --git a/wallet/chain/p/wallet_with_options.go b/wallet/chain/p/wallet_with_options.go index 53067332dc4d..92965f2e4f1f 100644 --- a/wallet/chain/p/wallet_with_options.go +++ b/wallet/chain/p/wallet_with_options.go @@ -8,11 +8,13 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/builder" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + vmsigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" + walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) var _ Wallet = (*walletWithOptions)(nil) @@ -22,28 +24,32 @@ func NewWalletWithOptions( options ...common.Option, ) Wallet { return &walletWithOptions{ - Wallet: wallet, + wallet: wallet, options: options, } } type walletWithOptions struct { - Wallet + wallet Wallet options []common.Option } -func (w *walletWithOptions) Builder() backends.Builder { - return NewBuilderWithOptions( - w.Wallet.Builder(), +func (w *walletWithOptions) Builder() builder.Builder { + return builder.NewWithOptions( + w.wallet.Builder(), w.options..., ) } +func (w *walletWithOptions) Signer() walletsigner.Signer { + return w.wallet.Signer() +} + func (w *walletWithOptions) IssueBaseTx( outputs []*avax.TransferableOutput, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueBaseTx( + return w.wallet.IssueBaseTx( outputs, common.UnionOptions(w.options, options)..., ) @@ -55,7 +61,7 @@ func (w *walletWithOptions) IssueAddValidatorTx( shares uint32, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueAddValidatorTx( + return w.wallet.IssueAddValidatorTx( vdr, rewardsOwner, shares, @@ -67,7 +73,7 @@ func (w *walletWithOptions) IssueAddSubnetValidatorTx( vdr *txs.SubnetValidator, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueAddSubnetValidatorTx( + return w.wallet.IssueAddSubnetValidatorTx( vdr, common.UnionOptions(w.options, options)..., ) @@ -78,7 +84,7 @@ func (w *walletWithOptions) IssueRemoveSubnetValidatorTx( subnetID ids.ID, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueRemoveSubnetValidatorTx( + return w.wallet.IssueRemoveSubnetValidatorTx( nodeID, subnetID, common.UnionOptions(w.options, options)..., @@ -90,7 +96,7 @@ func (w *walletWithOptions) IssueAddDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueAddDelegatorTx( + return w.wallet.IssueAddDelegatorTx( vdr, rewardsOwner, common.UnionOptions(w.options, options)..., @@ -105,7 +111,7 @@ func (w *walletWithOptions) IssueCreateChainTx( chainName string, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueCreateChainTx( + return w.wallet.IssueCreateChainTx( subnetID, genesis, vmID, @@ -119,7 +125,7 @@ func (w *walletWithOptions) IssueCreateSubnetTx( owner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueCreateSubnetTx( + return w.wallet.IssueCreateSubnetTx( owner, common.UnionOptions(w.options, options)..., ) @@ -130,7 +136,7 @@ func (w *walletWithOptions) IssueTransferSubnetOwnershipTx( owner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueTransferSubnetOwnershipTx( + return w.wallet.IssueTransferSubnetOwnershipTx( subnetID, owner, common.UnionOptions(w.options, options)..., @@ -142,7 +148,7 @@ func (w *walletWithOptions) IssueImportTx( to *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueImportTx( + return w.wallet.IssueImportTx( sourceChainID, to, common.UnionOptions(w.options, options)..., @@ -154,7 +160,7 @@ func (w *walletWithOptions) IssueExportTx( outputs []*avax.TransferableOutput, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueExportTx( + return w.wallet.IssueExportTx( chainID, outputs, common.UnionOptions(w.options, options)..., @@ -178,7 +184,7 @@ func (w *walletWithOptions) IssueTransformSubnetTx( uptimeRequirement uint32, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueTransformSubnetTx( + return w.wallet.IssueTransformSubnetTx( subnetID, assetID, initialSupply, @@ -199,14 +205,14 @@ func (w *walletWithOptions) IssueTransformSubnetTx( func (w *walletWithOptions) IssueAddPermissionlessValidatorTx( vdr *txs.SubnetValidator, - signer signer.Signer, + signer vmsigner.Signer, assetID ids.ID, validationRewardsOwner *secp256k1fx.OutputOwners, delegationRewardsOwner *secp256k1fx.OutputOwners, shares uint32, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueAddPermissionlessValidatorTx( + return w.wallet.IssueAddPermissionlessValidatorTx( vdr, signer, assetID, @@ -223,7 +229,7 @@ func (w *walletWithOptions) IssueAddPermissionlessDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueAddPermissionlessDelegatorTx( + return w.wallet.IssueAddPermissionlessDelegatorTx( vdr, assetID, rewardsOwner, @@ -235,7 +241,7 @@ func (w *walletWithOptions) IssueUnsignedTx( utx txs.UnsignedTx, options ...common.Option, ) (*txs.Tx, error) { - return w.Wallet.IssueUnsignedTx( + return w.wallet.IssueUnsignedTx( utx, common.UnionOptions(w.options, options)..., ) @@ -245,7 +251,7 @@ func (w *walletWithOptions) IssueTx( tx *txs.Tx, options ...common.Option, ) error { - return w.Wallet.IssueTx( + return w.wallet.IssueTx( tx, common.UnionOptions(w.options, options)..., ) diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 0e559affc45e..980eabbbe5c5 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -22,7 +22,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/builder" "github.com/ava-labs/avalanchego/wallet/chain/x" walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -58,7 +58,7 @@ type UTXOClient interface { type AVAXState struct { PClient platformvm.Client - PCTX backends.Context + PCTX *builder.Context XClient avm.Client XCTX x.Context CClient evm.Client diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index 987229d1ec22..8f0348f2b7ca 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -54,7 +54,7 @@ func main() { // Get the P-chain wallet pWallet := wallet.P() - avaxAssetID := pWallet.AVAXAssetID() + avaxAssetID := pWallet.Builder().Context().AVAXAssetID addValidatorStartTime := time.Now() addValidatorTx, err := pWallet.IssueAddPermissionlessValidatorTx( diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index 32cdcf983ba0..81b78ad5bc2b 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -48,7 +48,7 @@ func main() { // Get the P-chain wallet pWallet := wallet.P() - avaxAssetID := pWallet.AVAXAssetID() + avaxAssetID := pWallet.Builder().Context().AVAXAssetID issueTxStartTime := time.Now() tx, err := pWallet.IssueBaseTx([]*avax.TransferableOutput{ diff --git a/wallet/subnet/primary/examples/get-p-chain-balance/main.go b/wallet/subnet/primary/examples/get-p-chain-balance/main.go index df8d0bdf62d1..e190247515bf 100644 --- a/wallet/subnet/primary/examples/get-p-chain-balance/main.go +++ b/wallet/subnet/primary/examples/get-p-chain-balance/main.go @@ -12,10 +12,9 @@ import ( "github.com/ava-labs/avalanchego/utils/formatting/address" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/wallet/chain/p" + "github.com/ava-labs/avalanchego/wallet/chain/p/builder" "github.com/ava-labs/avalanchego/wallet/subnet/primary" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - - pbackends "github.com/ava-labs/avalanchego/wallet/chain/p/backends" ) func main() { @@ -40,14 +39,14 @@ func main() { pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, state.UTXOs) pBackend := p.NewBackend(state.PCTX, pUTXOs, nil) - pBuilder := pbackends.NewBuilder(addresses, pBackend) + pBuilder := builder.New(addresses, state.PCTX, pBackend) currentBalances, err := pBuilder.GetBalance() if err != nil { log.Fatalf("failed to get the balance: %s\n", err) } - avaxID := state.PCTX.AVAXAssetID() + avaxID := state.PCTX.AVAXAssetID avaxBalance := currentBalances[avaxID] log.Printf("current AVAX balance of %s is %d nAVAX\n", addrStr, avaxBalance) } diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 47777eb25d1b..6a9e9d3124b0 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -16,7 +16,8 @@ import ( "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - pbackends "github.com/ava-labs/avalanchego/wallet/chain/p/backends" + pbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" + psigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) var _ Wallet = (*wallet)(nil) @@ -120,8 +121,8 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { pUTXOs := common.NewChainUTXOs(constants.PlatformChainID, avaxState.UTXOs) pBackend := p.NewBackend(avaxState.PCTX, pUTXOs, pChainTxs) - pBuilder := pbackends.NewBuilder(avaxAddrs, pBackend) - pSigner := pbackends.NewSigner(config.AVAXKeychain, pBackend) + pBuilder := pbuilder.New(avaxAddrs, avaxState.PCTX, pBackend) + pSigner := psigner.New(config.AVAXKeychain, pBackend) xChainID := avaxState.XCTX.BlockchainID() xUTXOs := common.NewChainUTXOs(xChainID, avaxState.UTXOs) From 51729d935f5d1f046e9c8b9e53bf606481735a48 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 18:13:58 -0400 Subject: [PATCH 056/120] nit --- wallet/chain/p/builder/builder.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index 70433b11dac8..a95939405717 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -24,10 +24,10 @@ import ( ) var ( - errNoChangeAddress = errors.New("no possible change address") + ErrNoChangeAddress = errors.New("no possible change address") ErrUnknownOutputType = errors.New("unknown output type") - errUnknownOwnerType = errors.New("unknown owner type") - errInsufficientAuthorization = errors.New("insufficient authorization") + ErrUnknownOwnerType = errors.New("unknown owner type") + ErrInsufficientAuthorization = errors.New("insufficient authorization") ErrInsufficientFunds = errors.New("insufficient funds") _ Builder = (*builder)(nil) @@ -955,7 +955,7 @@ func (b *builder) spend( addr, ok := addrs.Peek() if !ok { - return nil, nil, nil, errNoChangeAddress + return nil, nil, nil, ErrNoChangeAddress } changeOwner := options.ChangeOwner(&secp256k1fx.OutputOwners{ Threshold: 1, @@ -1163,7 +1163,7 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se } owner, ok := ownerIntf.(*secp256k1fx.OutputOwners) if !ok { - return nil, errUnknownOwnerType + return nil, ErrUnknownOwnerType } addrs := options.Addresses(b.addrs) @@ -1171,7 +1171,7 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se inputSigIndices, ok := common.MatchOwners(owner, addrs, minIssuanceTime) if !ok { // We can't authorize the subnet - return nil, errInsufficientAuthorization + return nil, ErrInsufficientAuthorization } return &secp256k1fx.Input{ SigIndices: inputSigIndices, From 9481ff77dfdc9a6de768cf3f9a60289b34fb37f1 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 20:13:54 -0400 Subject: [PATCH 057/120] nit --- vms/platformvm/txs/builder/backend.go | 38 +++---------- vms/platformvm/txs/builder/builder.go | 56 ++++++++++++------- vms/platformvm/txs/builder/context.go | 32 +++++++++++ .../txs/executor/create_chain_test.go | 15 +++-- .../txs/executor/create_subnet_test.go | 15 +++-- vms/platformvm/txs/executor/import_test.go | 4 +- 6 files changed, 94 insertions(+), 66 deletions(-) create mode 100644 vms/platformvm/txs/builder/context.go diff --git a/vms/platformvm/txs/builder/backend.go b/vms/platformvm/txs/builder/backend.go index 06477cfd5553..4fb4d8904446 100644 --- a/vms/platformvm/txs/builder/backend.go +++ b/vms/platformvm/txs/builder/backend.go @@ -9,38 +9,28 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/state" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/signer" + + walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) -var _ backends.Backend = (*Backend)(nil) +var ( + _ walletbuilder.Backend = (*Backend)(nil) + _ signer.Backend = (*Backend)(nil) +) func NewBackend( - ctx *snow.Context, cfg *config.Config, state state.State, atomicUTXOsMan avax.AtomicUTXOManager, ) *Backend { - backendCtx := backends.NewContext( - ctx.NetworkID, - ctx.AVAXAssetID, - cfg.TxFee, - cfg.GetCreateSubnetTxFee(state.GetTimestamp()), - cfg.TransformSubnetTxFee, - cfg.GetCreateBlockchainTxFee(state.GetTimestamp()), - cfg.AddPrimaryNetworkValidatorFee, - cfg.AddPrimaryNetworkDelegatorFee, - cfg.AddSubnetValidatorFee, - cfg.AddSubnetDelegatorFee, - ) return &Backend{ - Context: backendCtx, cfg: cfg, state: state, atomicUTXOsMan: atomicUTXOsMan, @@ -48,26 +38,12 @@ func NewBackend( } type Backend struct { - backends.Context - cfg *config.Config addrs set.Set[ids.ShortID] state state.State atomicUTXOsMan avax.AtomicUTXOManager } -// Override [backend.Context.CreateSubnetTxFee] to refresh fee -// relevant in unit tests only -func (b *Backend) CreateSubnetTxFee() uint64 { - return b.cfg.GetCreateSubnetTxFee(b.state.GetTimestamp()) -} - -// Override [backend.Context.CreateBlockchainTxFee] to refresh fee -// relevant in unit tests only -func (b *Backend) CreateBlockchainTxFee() uint64 { - return b.cfg.GetCreateBlockchainTxFee(b.state.GetTimestamp()) -} - func (b *Backend) ResetAddresses(addrs set.Set[ids.ShortID]) { b.addrs = addrs } diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 8daacafefad0..d49f12edd5f2 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -15,12 +15,14 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/config" - "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/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" + + vmsigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" + walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" + walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) // Max number of items allowed in a page @@ -161,7 +163,7 @@ type ProposalTxBuilder interface { startTime, endTime uint64, nodeID ids.NodeID, - pop *signer.ProofOfPossession, + pop *vmsigner.ProofOfPossession, rewardAddress ids.ShortID, shares uint32, keys []*secp256k1.PrivateKey, @@ -258,7 +260,7 @@ func New( ) Builder { return &builder{ ctx: ctx, - backend: NewBackend(ctx, cfg, state, atomicUTXOManager), + backend: NewBackend(cfg, state, atomicUTXOManager), } } @@ -291,7 +293,7 @@ func (b *builder) NewImportTx( return nil, fmt.Errorf("failed building import tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -330,7 +332,7 @@ func (b *builder) NewExportTx( return nil, fmt.Errorf("failed building export tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -354,7 +356,7 @@ func (b *builder) NewCreateChainTx( return nil, fmt.Errorf("failed building create chain tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -381,7 +383,7 @@ func (b *builder) NewCreateSubnetTx( return nil, fmt.Errorf("failed building create subnet tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -430,7 +432,7 @@ func (b *builder) NewTransformSubnetTx( return nil, fmt.Errorf("failed building transform subnet tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -467,7 +469,7 @@ func (b *builder) NewAddValidatorTx( return nil, fmt.Errorf("failed building add validator tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -479,7 +481,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( startTime, endTime uint64, nodeID ids.NodeID, - pop *signer.ProofOfPossession, + pop *vmsigner.ProofOfPossession, rewardAddress ids.ShortID, shares uint32, keys []*secp256k1.PrivateKey, @@ -516,7 +518,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( return nil, fmt.Errorf("failed building add permissionless validator tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -556,7 +558,7 @@ func (b *builder) NewAddDelegatorTx( return nil, fmt.Errorf("failed building add delegator tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -600,7 +602,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( return nil, fmt.Errorf("failed building add permissionless delegator tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -637,7 +639,7 @@ func (b *builder) NewAddSubnetValidatorTx( return nil, fmt.Errorf("failed building add subnet validator tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -662,7 +664,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( return nil, fmt.Errorf("failed building remove subnet validator tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -694,7 +696,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( return nil, fmt.Errorf("failed building transfer subnet ownership tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } @@ -726,19 +728,31 @@ func (b *builder) NewBaseTx( return nil, fmt.Errorf("failed building base tx: %w", err) } - tx, err := backends.SignUnsigned(context.Background(), pSigner, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) if err != nil { return nil, err } return tx, tx.SyntacticVerify(b.ctx) } -func (b *builder) builders(keys []*secp256k1.PrivateKey) (backends.Builder, backends.Signer) { +func (b *builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, walletsigner.Signer) { var ( kc = secp256k1fx.NewKeychain(keys...) addrs = kc.Addresses() - builder = backends.NewBuilder(addrs, b.backend) - signer = backends.NewSigner(kc, b.backend) + context = &walletbuilder.Context{ + NetworkID: b.ctx.NetworkID, + AVAXAssetID: b.ctx.AVAXAssetID, + BaseTxFee: b.backend.cfg.TxFee, + CreateSubnetTxFee: b.backend.cfg.GetCreateSubnetTxFee(b.backend.state.GetTimestamp()), + TransformSubnetTxFee: b.backend.cfg.TransformSubnetTxFee, + CreateBlockchainTxFee: b.backend.cfg.GetCreateBlockchainTxFee(b.backend.state.GetTimestamp()), + AddPrimaryNetworkValidatorFee: b.backend.cfg.AddPrimaryNetworkValidatorFee, + AddPrimaryNetworkDelegatorFee: b.backend.cfg.AddPrimaryNetworkDelegatorFee, + AddSubnetValidatorFee: b.backend.cfg.AddSubnetValidatorFee, + AddSubnetDelegatorFee: b.backend.cfg.AddSubnetDelegatorFee, + } + builder = walletbuilder.New(addrs, context, b.backend) + signer = walletsigner.New(kc, b.backend) ) b.backend.ResetAddresses(addrs) diff --git a/vms/platformvm/txs/builder/context.go b/vms/platformvm/txs/builder/context.go new file mode 100644 index 000000000000..78fcf87def4e --- /dev/null +++ b/vms/platformvm/txs/builder/context.go @@ -0,0 +1,32 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package builder + +import ( + "time" + + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/vms/platformvm/config" + + walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" +) + +func NewContext( + ctx *snow.Context, + cfg *config.Config, + timestamp time.Time, +) *walletbuilder.Context { + return &walletbuilder.Context{ + NetworkID: ctx.NetworkID, + AVAXAssetID: ctx.AVAXAssetID, + BaseTxFee: cfg.TxFee, + CreateSubnetTxFee: cfg.GetCreateSubnetTxFee(timestamp), + TransformSubnetTxFee: cfg.TransformSubnetTxFee, + CreateBlockchainTxFee: cfg.GetCreateBlockchainTxFee(timestamp), + AddPrimaryNetworkValidatorFee: cfg.AddPrimaryNetworkValidatorFee, + AddPrimaryNetworkDelegatorFee: cfg.AddPrimaryNetworkDelegatorFee, + AddSubnetValidatorFee: cfg.AddSubnetValidatorFee, + AddSubnetDelegatorFee: cfg.AddSubnetDelegatorFee, + } +} diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 8b51e098b7e3..7ab69b519ec2 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -19,10 +19,12 @@ 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/builder" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/signer" + + vmbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" + walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) // Ensure Execute fails when there are not enough control sigs @@ -206,9 +208,10 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateBlockchainTxFee = test.fee - backend := builder.NewBackend(env.ctx, &cfg, env.state, env.atomicUTXOs) + builderContext := vmbuilder.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) + backend := vmbuilder.NewBackend(&cfg, env.state, env.atomicUTXOs) backend.ResetAddresses(addrs) - pBuilder := backends.NewBuilder(addrs, backend) + pBuilder := walletbuilder.New(addrs, builderContext, backend) utx, err := pBuilder.NewCreateChainTx( testSubnet1.ID(), @@ -220,8 +223,8 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { require.NoError(err) kc := secp256k1fx.NewKeychain(preFundedKeys...) - s := backends.NewSigner(kc, backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + s := signer.New(kc, backend) + tx, err := signer.SignUnsigned(context.Background(), s, utx) require.NoError(err) stateDiff, err := state.NewDiff(lastAcceptedID, env) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index e8d88a541a48..bcf9a6b2e6de 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -14,10 +14,12 @@ 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/builder" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/signer" + + vmbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" + walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) func TestCreateSubnetTxAP3FeeChange(t *testing.T) { @@ -65,9 +67,10 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateSubnetTxFee = test.fee - backend := builder.NewBackend(env.ctx, &cfg, env.state, env.atomicUTXOs) + builderContext := vmbuilder.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) + backend := vmbuilder.NewBackend(&cfg, env.state, env.atomicUTXOs) backend.ResetAddresses(addrs) - pBuilder := backends.NewBuilder(addrs, backend) + pBuilder := walletbuilder.New(addrs, builderContext, backend) utx, err := pBuilder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{}, // owner @@ -75,8 +78,8 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { require.NoError(err) kc := secp256k1fx.NewKeychain(preFundedKeys...) - s := backends.NewSigner(kc, backend) - tx, err := backends.SignUnsigned(context.Background(), s, utx) + s := signer.New(kc, backend) + tx, err := signer.SignUnsigned(context.Background(), s, utx) require.NoError(err) stateDiff, err := state.NewDiff(lastAcceptedID, env) diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index 40ef33852fc6..5ac6a76354b2 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -18,7 +18,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" + "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) var fundedSharedMemoryCalls byte @@ -54,7 +54,7 @@ func TestNewImportTx(t *testing.T) { }, ), sourceKeys: []*secp256k1.PrivateKey{sourceKey}, - expectedErr: backends.ErrInsufficientFunds, + expectedErr: builder.ErrInsufficientFunds, }, { description: "can barely pay fee", From ade5178edb73bfe89babfab02b3357be3195d23a Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 20:28:46 -0400 Subject: [PATCH 058/120] fix merge --- vms/platformvm/vm_test.go | 6 +++--- wallet/chain/p/builder/builder.go | 2 +- wallet/chain/p/builder/context.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index bf43748e1bd1..185b9e5201b7 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -60,7 +60,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/chain/p/backends" smcon "github.com/ava-labs/avalanchego/snow/consensus/snowman" smeng "github.com/ava-labs/avalanchego/snow/engine/snowman" @@ -69,6 +68,7 @@ import ( blockbuilder "github.com/ava-labs/avalanchego/vms/platformvm/block/builder" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" + walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) const ( @@ -988,7 +988,7 @@ func TestAtomicImport(t *testing.T) { ids.ShortEmpty, // change addr nil, ) - require.ErrorIs(err, backends.ErrInsufficientFunds) + require.ErrorIs(err, walletbuilder.ErrInsufficientFunds) // Provide the avm UTXO @@ -2137,7 +2137,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { keys[0].PublicKey().Address(), }, } - ctx, err := backends.NewSnowContext(vm.ctx.NetworkID, vm.ctx.AVAXAssetID) + ctx, err := builder.NewSnowContext(vm.ctx.NetworkID, vm.ctx.AVAXAssetID) require.NoError(err) expectedOwner.InitCtx(ctx) require.Equal(expectedOwner, subnetOwner) diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index d9506ec34a5f..b411efae8dd6 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -1186,7 +1186,7 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se } func (b *builder) initCtx(tx txs.UnsignedTx) error { - ctx, err := newSnowContext(b.context.NetworkID, b.context.AVAXAssetID) + ctx, err := NewSnowContext(b.context.NetworkID, b.context.AVAXAssetID) if err != nil { return err } diff --git a/wallet/chain/p/builder/context.go b/wallet/chain/p/builder/context.go index 4b03cd41dce2..f465ae9fa86b 100644 --- a/wallet/chain/p/builder/context.go +++ b/wallet/chain/p/builder/context.go @@ -25,7 +25,7 @@ type Context struct { AddSubnetDelegatorFee uint64 } -func newSnowContext(networkID uint32, avaxAssetID ids.ID) (*snow.Context, error) { +func NewSnowContext(networkID uint32, avaxAssetID ids.ID) (*snow.Context, error) { lookup := ids.NewAliaser() return &snow.Context{ NetworkID: networkID, From ba483942795d7ee868241715fdb5394b8df204a7 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 20:29:25 -0400 Subject: [PATCH 059/120] nit --- wallet/chain/p/builder/builder.go | 2 +- wallet/chain/p/builder/context.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index a95939405717..e142342dc483 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -1179,7 +1179,7 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se } func (b *builder) initCtx(tx txs.UnsignedTx) error { - ctx, err := newSnowContext(b.context.NetworkID, b.context.AVAXAssetID) + ctx, err := NewSnowContext(b.context.NetworkID, b.context.AVAXAssetID) if err != nil { return err } diff --git a/wallet/chain/p/builder/context.go b/wallet/chain/p/builder/context.go index 4b03cd41dce2..f465ae9fa86b 100644 --- a/wallet/chain/p/builder/context.go +++ b/wallet/chain/p/builder/context.go @@ -25,7 +25,7 @@ type Context struct { AddSubnetDelegatorFee uint64 } -func newSnowContext(networkID uint32, avaxAssetID ids.ID) (*snow.Context, error) { +func NewSnowContext(networkID uint32, avaxAssetID ids.ID) (*snow.Context, error) { lookup := ids.NewAliaser() return &snow.Context{ NetworkID: networkID, From 6de663b69ea76513054fdf8a7ecf0cb4b4c54ebf Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 20:35:26 -0400 Subject: [PATCH 060/120] save --- vms/platformvm/vm_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 185b9e5201b7..d1135ebc540d 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -2137,7 +2137,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { keys[0].PublicKey().Address(), }, } - ctx, err := builder.NewSnowContext(vm.ctx.NetworkID, vm.ctx.AVAXAssetID) + ctx, err := walletbuilder.NewSnowContext(vm.ctx.NetworkID, vm.ctx.AVAXAssetID) require.NoError(err) expectedOwner.InitCtx(ctx) require.Equal(expectedOwner, subnetOwner) From 6c9004d22a0bed336ee93bf23810a745328b5761 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 20:42:31 -0400 Subject: [PATCH 061/120] nit --- vms/platformvm/txs/builder/builder.go | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index d49f12edd5f2..d33bc85829e4 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -739,18 +739,7 @@ func (b *builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, var ( kc = secp256k1fx.NewKeychain(keys...) addrs = kc.Addresses() - context = &walletbuilder.Context{ - NetworkID: b.ctx.NetworkID, - AVAXAssetID: b.ctx.AVAXAssetID, - BaseTxFee: b.backend.cfg.TxFee, - CreateSubnetTxFee: b.backend.cfg.GetCreateSubnetTxFee(b.backend.state.GetTimestamp()), - TransformSubnetTxFee: b.backend.cfg.TransformSubnetTxFee, - CreateBlockchainTxFee: b.backend.cfg.GetCreateBlockchainTxFee(b.backend.state.GetTimestamp()), - AddPrimaryNetworkValidatorFee: b.backend.cfg.AddPrimaryNetworkValidatorFee, - AddPrimaryNetworkDelegatorFee: b.backend.cfg.AddPrimaryNetworkDelegatorFee, - AddSubnetValidatorFee: b.backend.cfg.AddSubnetValidatorFee, - AddSubnetDelegatorFee: b.backend.cfg.AddSubnetDelegatorFee, - } + context = NewContext(b.ctx, b.backend.cfg, b.backend.state.GetTimestamp()) builder = walletbuilder.New(addrs, context, b.backend) signer = walletsigner.New(kc, b.backend) ) From 318be91da4d5185707688b4178bd82071fba9b3b Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 20:57:56 -0400 Subject: [PATCH 062/120] nit --- wallet/chain/p/builder/context.go | 44 ++++++++++++++++++++++++++ wallet/chain/p/context.go | 52 ------------------------------- wallet/subnet/primary/api.go | 3 +- 3 files changed, 45 insertions(+), 54 deletions(-) delete mode 100644 wallet/chain/p/context.go diff --git a/wallet/chain/p/builder/context.go b/wallet/chain/p/builder/context.go index f465ae9fa86b..f0da23fdc5f9 100644 --- a/wallet/chain/p/builder/context.go +++ b/wallet/chain/p/builder/context.go @@ -4,10 +4,14 @@ package builder import ( + "context" + + "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/vms/avm" ) const Alias = "P" @@ -25,6 +29,46 @@ type Context struct { AddSubnetDelegatorFee uint64 } +func NewContextFromURI(ctx context.Context, uri string) (*Context, error) { + infoClient := info.NewClient(uri) + xChainClient := avm.NewClient(uri, "X") + return NewContextFromClients(ctx, infoClient, xChainClient) +} + +func NewContextFromClients( + ctx context.Context, + infoClient info.Client, + xChainClient avm.Client, +) (*Context, error) { + networkID, err := infoClient.GetNetworkID(ctx) + if err != nil { + return nil, err + } + + asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") + if err != nil { + return nil, err + } + + txFees, err := infoClient.GetTxFee(ctx) + if err != nil { + return nil, err + } + + 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), + }, nil +} + func NewSnowContext(networkID uint32, avaxAssetID ids.ID) (*snow.Context, error) { lookup := ids.NewAliaser() return &snow.Context{ diff --git a/wallet/chain/p/context.go b/wallet/chain/p/context.go deleted file mode 100644 index 057d5553ea02..000000000000 --- a/wallet/chain/p/context.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package p - -import ( - "context" - - "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/vms/avm" - "github.com/ava-labs/avalanchego/wallet/chain/p/builder" -) - -func NewContextFromURI(ctx context.Context, uri string) (*builder.Context, error) { - infoClient := info.NewClient(uri) - xChainClient := avm.NewClient(uri, "X") - return NewContextFromClients(ctx, infoClient, xChainClient) -} - -func NewContextFromClients( - ctx context.Context, - infoClient info.Client, - xChainClient avm.Client, -) (*builder.Context, error) { - networkID, err := infoClient.GetNetworkID(ctx) - if err != nil { - return nil, err - } - - asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") - if err != nil { - return nil, err - } - - txFees, err := infoClient.GetTxFee(ctx) - if err != nil { - return nil, err - } - - return &builder.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), - }, nil -} diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 980eabbbe5c5..7486cde263e9 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -21,7 +21,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/wallet/chain/c" - "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/p/builder" "github.com/ava-labs/avalanchego/wallet/chain/x" @@ -79,7 +78,7 @@ func FetchState( xClient := avm.NewClient(uri, "X") cClient := evm.NewCChainClient(uri) - pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient) + pCTX, err := builder.NewContextFromClients(ctx, infoClient, xClient) if err != nil { return nil, err } From 41f14053820148ad097ec8b2327602984a85b269 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 21:03:48 -0400 Subject: [PATCH 063/120] nit --- wallet/chain/p/signer/visitor.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/wallet/chain/p/signer/visitor.go b/wallet/chain/p/signer/visitor.go index 58d6a5e0b3c0..5dd4abe2b7d2 100644 --- a/wallet/chain/p/signer/visitor.go +++ b/wallet/chain/p/signer/visitor.go @@ -24,13 +24,13 @@ import ( var ( _ txs.Visitor = (*visitor)(nil) - ErrUnknownOwnerType = errors.New("unknown owner type") - ErrUnknownOutputType = errors.New("unknown output type") ErrUnsupportedTxType = errors.New("unsupported tx type") - errUnknownInputType = errors.New("unknown input type") - errUnknownCredentialType = errors.New("unknown credential type") - errUnknownSubnetAuthType = errors.New("unknown subnet auth type") - errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + ErrUnknownInputType = errors.New("unknown input type") + ErrUnknownOutputType = errors.New("unknown output type") + ErrInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + ErrUnknownSubnetAuthType = errors.New("unknown subnet auth type") + ErrUnknownOwnerType = errors.New("unknown owner type") + ErrUnknownCredentialType = errors.New("unknown credential type") emptySig [secp256k1.SignatureLen]byte ) @@ -195,7 +195,7 @@ func (s *visitor) getSigners(sourceChainID ids.ID, ins []*avax.TransferableInput input, ok := inIntf.(*secp256k1fx.TransferInput) if !ok { - return nil, errUnknownInputType + return nil, ErrUnknownInputType } inputSigners := make([]keychain.Signer, len(input.SigIndices)) @@ -224,7 +224,7 @@ func (s *visitor) getSigners(sourceChainID ids.ID, ins []*avax.TransferableInput for sigIndex, addrIndex := range input.SigIndices { if addrIndex >= uint32(len(out.Addrs)) { - return nil, errInvalidUTXOSigIndex + return nil, ErrInvalidUTXOSigIndex } addr := out.Addrs[addrIndex] @@ -243,7 +243,7 @@ func (s *visitor) getSigners(sourceChainID ids.ID, ins []*avax.TransferableInput func (s *visitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Verifiable) ([]keychain.Signer, error) { subnetInput, ok := subnetAuth.(*secp256k1fx.Input) if !ok { - return nil, errUnknownSubnetAuthType + return nil, ErrUnknownSubnetAuthType } ownerIntf, err := s.backend.GetSubnetOwner(s.ctx, subnetID) @@ -262,7 +262,7 @@ func (s *visitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Verifiable authSigners := make([]keychain.Signer, len(subnetInput.SigIndices)) for sigIndex, addrIndex := range subnetInput.SigIndices { if addrIndex >= uint32(len(owner.Addrs)) { - return nil, errInvalidUTXOSigIndex + return nil, ErrInvalidUTXOSigIndex } addr := owner.Addrs[addrIndex] @@ -299,7 +299,7 @@ func sign(tx *txs.Tx, signHash bool, txSigners [][]keychain.Signer) error { cred, ok := credIntf.(*secp256k1fx.Credential) if !ok { - return errUnknownCredentialType + return ErrUnknownCredentialType } if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) From edbfd16e72c1eef4aa91897a98cf69392a215081 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 21:07:06 -0400 Subject: [PATCH 064/120] nit --- .../subnet/primary/examples/create-locked-stakeable/main.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index 81b78ad5bc2b..a6cf5c78604e 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -48,7 +48,9 @@ func main() { // Get the P-chain wallet pWallet := wallet.P() - avaxAssetID := pWallet.Builder().Context().AVAXAssetID + pBuilder := pWallet.Builder() + pContext := pBuilder.Context() + avaxAssetID := pContext.AVAXAssetID issueTxStartTime := time.Now() tx, err := pWallet.IssueBaseTx([]*avax.TransferableOutput{ From bc5b5e01759b3017eb148a8d5e2d8331da46a9cf Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 21:08:38 -0400 Subject: [PATCH 065/120] nit --- wallet/subnet/primary/examples/add-primary-validator/main.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index 8f0348f2b7ca..7c2b6c055855 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -54,7 +54,9 @@ func main() { // Get the P-chain wallet pWallet := wallet.P() - avaxAssetID := pWallet.Builder().Context().AVAXAssetID + pBuilder := pWallet.Builder() + pContext := pBuilder.Context() + avaxAssetID := pContext.AVAXAssetID addValidatorStartTime := time.Now() addValidatorTx, err := pWallet.IssueAddPermissionlessValidatorTx( From b2d11ce56cb67c637d025c99283bd510b786f5ec Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 21:17:41 -0400 Subject: [PATCH 066/120] nit --- vms/platformvm/block/executor/helpers_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 4f5c7a668b33..906ed5edcba4 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -169,7 +169,6 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment res.uptimes = uptime.NewManager(res.mockedState, res.clk) res.utxosVerifier = utxo.NewVerifier(res.ctx, res.clk, res.fx) - res.mockedState.EXPECT().GetTimestamp().Return(time.Time{}).Times(2) // to initialize createSubnet/BlockchainTx fee res.txBuilder = p_tx_builder.New( res.ctx, res.config, From 09be1c4287c123543497ed335fe133e5d99ec1b8 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 21 Mar 2024 15:55:29 +0100 Subject: [PATCH 067/120] minor renaming for clarify --- tests/e2e/p/workflow.go | 8 +- vms/components/fees/config.go | 14 +- vms/platformvm/block/builder/builder.go | 4 +- vms/platformvm/block/builder/helpers_test.go | 4 +- vms/platformvm/block/executor/helpers_test.go | 4 +- vms/platformvm/block/executor/manager.go | 4 +- vms/platformvm/block/executor/verifier.go | 4 +- vms/platformvm/config/dynamic_fees_config.go | 8 +- vms/platformvm/service_test.go | 14 +- vms/platformvm/txs/builder/builder.go | 130 ++++----- .../txs/executor/atomic_tx_executor.go | 4 +- .../txs/executor/create_chain_test.go | 30 +- .../txs/executor/create_subnet_test.go | 14 +- vms/platformvm/txs/executor/helpers_test.go | 4 +- .../txs/executor/staker_tx_verification.go | 60 ++-- .../txs/executor/standard_tx_executor.go | 72 ++--- .../txs/executor/standard_tx_executor_test.go | 124 ++++----- vms/platformvm/txs/fees/calculator.go | 6 +- vms/platformvm/txs/fees/calculator_test.go | 18 +- vms/platformvm/vm_test.go | 28 +- wallet/chain/p/builder_test.go | 261 +++++++++--------- wallet/chain/p/wallet.go | 86 +++--- 22 files changed, 451 insertions(+), 450 deletions(-) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index d1afaee56222..71dfefd5446a 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -158,10 +158,10 @@ var _ = e2e.DescribePChain("[Workflow]", func() { // retrieve fees paid for the tx feeCfg := config.GetDynamicFeesConfig(true /*isEActive*/) feeCalc := fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: tx.Creds, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Credentials: tx.Creds, } require.NoError(tx.Unsigned.Visit(&feeCalc)) diff --git a/vms/components/fees/config.go b/vms/components/fees/config.go index 2d7fffac114c..20b528703866 100644 --- a/vms/components/fees/config.go +++ b/vms/components/fees/config.go @@ -4,12 +4,12 @@ package fees type DynamicFeesConfig struct { - // UnitFees contains, per each fee dimension, the - // unit fees valid as soon as fork introducing dynamic fees - // activates. Unit fees are not currently updated by any dynamic fees algo. - UnitFees Dimensions `json:"initial-unit-fees"` + // FeeRate contains, per each fee dimension, the fee rate, + // i.e. the fee per unit of complexity. Fee rates are + // valid as soon as fork introducing dynamic fees activates. + FeeRate Dimensions `json:"fee-rate"` - // BlockUnitsCap contains, per each fee dimension, the - // maximal complexity a valid block can host - BlockUnitsCap Dimensions `json:"block-unit-caps"` + // BlockMaxComplexity contains, per each fee dimension, the + // maximal complexity a valid block can host. + BlockMaxComplexity Dimensions `json:"block-max-complexity"` } diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 880ba1b6c870..53047b10cdd7 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -336,7 +336,7 @@ func packBlockTxs( var ( isEActivated = backend.Config.IsEActivated(timestamp) feeCfg = config.GetDynamicFeesConfig(isEActivated) - feeMan = fees.NewManager(feeCfg.UnitFees) + feeMan = fees.NewManager(feeCfg.FeeRate) blockTxs []*txs.Tx inputs set.Set[ids.ID] @@ -363,7 +363,7 @@ func packBlockTxs( executor := &txexecutor.StandardTxExecutor{ Backend: backend, BlkFeeManager: feeMan, - UnitCaps: feeCfg.BlockUnitsCap, + UnitCaps: feeCfg.BlockMaxComplexity, State: txDiff, Tx: tx, } diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 023a311e158c..6a1b8f89d447 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -266,8 +266,8 @@ func addSubnet(t *testing.T, env *environment) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := txexecutor.StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: stateDiff, Tx: testSubnet1, } diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 4d5ab7af8340..e42fab90aa0f 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -283,8 +283,8 @@ func addSubnet(env *environment) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := executor.StandardTxExecutor{ Backend: env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: stateDiff, Tx: testSubnet1, } diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index 84fb7f69ce4f..cfc6d39bab05 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -148,8 +148,8 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { feesCfg := config.GetDynamicFeesConfig(isEActivated) return tx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: m.txExecutorBackend, - BlkFeeManager: fees.NewManager(feesCfg.UnitFees), - UnitCaps: feesCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feesCfg.FeeRate), + UnitCaps: feesCfg.BlockMaxComplexity, State: stateDiff, Tx: tx, }) diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index c140e3ecff6d..5218604e851d 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -449,7 +449,7 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID var ( isEActivated = v.txExecutorBackend.Config.IsEActivated(state.GetTimestamp()) feesCfg = config.GetDynamicFeesConfig(isEActivated) - feesMan = fees.NewManager(feesCfg.UnitFees) + feesMan = fees.NewManager(feesCfg.FeeRate) onAcceptFunc func() inputs set.Set[ids.ID] @@ -460,7 +460,7 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID txExecutor := executor.StandardTxExecutor{ Backend: v.txExecutorBackend, BlkFeeManager: feesMan, - UnitCaps: feesCfg.BlockUnitsCap, + UnitCaps: feesCfg.BlockMaxComplexity, State: state, Tx: tx, } diff --git a/vms/platformvm/config/dynamic_fees_config.go b/vms/platformvm/config/dynamic_fees_config.go index a7925f4147e9..9c7f6755da28 100644 --- a/vms/platformvm/config/dynamic_fees_config.go +++ b/vms/platformvm/config/dynamic_fees_config.go @@ -16,19 +16,19 @@ import ( // eUpgradeDynamicFeesConfig to be tuned TODO ABENEGIA var ( eUpgradeDynamicFeesConfig = commonfees.DynamicFeesConfig{ - UnitFees: commonfees.Dimensions{ + FeeRate: commonfees.Dimensions{ 1 * units.NanoAvax, 2 * units.NanoAvax, 3 * units.NanoAvax, 4 * units.NanoAvax, }, - BlockUnitsCap: commonfees.Max, + BlockMaxComplexity: commonfees.Max, } preEUpgradeDynamicFeesConfig = commonfees.DynamicFeesConfig{ - UnitFees: commonfees.Empty, - BlockUnitsCap: commonfees.Max, + FeeRate: commonfees.Empty, + BlockMaxComplexity: commonfees.Max, } customDynamicFeesConfig *commonfees.DynamicFeesConfig diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 7c8c5a7bd763..4cbfd06250f2 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -356,14 +356,14 @@ func TestGetBalance(t *testing.T) { var ( chainTime = service.vm.state.GetTimestamp() feeCfg = config.GetDynamicFeesConfig(service.vm.Config.IsEActivated(chainTime)) - feeMan = commonfees.NewManager(feeCfg.UnitFees) + feeMan = commonfees.NewManager(feeCfg.FeeRate) feeCalc = &fees.Calculator{ - IsEUpgradeActive: service.vm.IsEActivated(chainTime), - Config: &service.vm.Config, - ChainTime: chainTime, - FeeManager: feeMan, - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: testSubnet1.Creds, + IsEUpgradeActive: service.vm.IsEActivated(chainTime), + Config: &service.vm.Config, + ChainTime: chainTime, + FeeManager: feeMan, + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Credentials: testSubnet1.Creds, } ) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 0049a2631d3f..746e05c9a01f 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -289,11 +289,11 @@ func (b *builder) NewImportTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -336,11 +336,11 @@ func (b *builder) NewExportTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -390,11 +390,11 @@ func (b *builder) NewCreateChainTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -432,11 +432,11 @@ func (b *builder) NewCreateSubnetTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -488,11 +488,11 @@ func (b *builder) NewTransformSubnetTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -543,11 +543,11 @@ func (b *builder) NewAddValidatorTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -600,11 +600,11 @@ func (b *builder) NewAddPermissionlessValidatorTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -661,11 +661,11 @@ func (b *builder) NewAddDelegatorTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -715,11 +715,11 @@ func (b *builder) NewAddPermissionlessDelegatorTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -773,11 +773,11 @@ func (b *builder) NewAddSubnetValidatorTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -821,11 +821,11 @@ func (b *builder) NewRemoveSubnetValidatorTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -861,11 +861,11 @@ func (b *builder) NewTransferSubnetOwnershipTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) @@ -906,11 +906,11 @@ func (b *builder) NewBaseTx( isEUpgradeActive = b.cfg.IsEActivated(chainTime) feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) diff --git a/vms/platformvm/txs/executor/atomic_tx_executor.go b/vms/platformvm/txs/executor/atomic_tx_executor.go index 6dfec80f345e..eaad587c97c0 100644 --- a/vms/platformvm/txs/executor/atomic_tx_executor.go +++ b/vms/platformvm/txs/executor/atomic_tx_executor.go @@ -104,8 +104,8 @@ func (e *AtomicTxExecutor) atomicTx(tx txs.UnsignedTx) error { feesCfg := config.GetDynamicFeesConfig(false /*isEActive*/) executor := StandardTxExecutor{ Backend: e.Backend, - BlkFeeManager: commonfees.NewManager(feesCfg.UnitFees), - UnitCaps: feesCfg.BlockUnitsCap, + BlkFeeManager: commonfees.NewManager(feesCfg.FeeRate), + UnitCaps: feesCfg.BlockMaxComplexity, State: e.OnAccept, Tx: e.Tx, } diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index d1554480ce8b..779d4dbff456 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -59,8 +59,8 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: stateDiff, Tx: tx, } @@ -103,8 +103,8 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: stateDiff, Tx: tx, } @@ -141,8 +141,8 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: stateDiff, Tx: tx, } @@ -176,8 +176,8 @@ func TestCreateChainTxValid(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: stateDiff, Tx: tx, } @@ -237,11 +237,11 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { chainTime = env.state.GetTimestamp() feeCfg = config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, - Config: &cfg, - ChainTime: test.time, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: false, + Config: &cfg, + ChainTime: test.time, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, } ) backend.ResetAddresses(addrs) @@ -270,8 +270,8 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { feeCfg = config.GetDynamicFeesConfig(env.config.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: stateDiff, Tx: tx, } diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index bc05180c03c7..f133f252ace7 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -80,11 +80,11 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { chainTime = env.state.GetTimestamp() feeCfg = config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, - Config: &cfg, - ChainTime: test.time, - FeeManager: commonfees.NewManager(feeCfg.UnitFees), - ConsumedUnitsCap: feeCfg.BlockUnitsCap, + IsEUpgradeActive: false, + Config: &cfg, + ChainTime: test.time, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, Fee: test.fee, } @@ -111,8 +111,8 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { feeCfg = config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: stateDiff, Tx: tx, } diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 8c8080b7960e..9b7e49faf36f 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -240,8 +240,8 @@ func addSubnet( feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: stateDiff, Tx: testSubnet1, } diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index d8a46af98af0..382d864e31ed 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -269,12 +269,12 @@ func verifyAddSubnetValidatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), - Config: backend.Config, - ChainTime: currentTimestamp, - FeeManager: feeManager, - ConsumedUnitsCap: unitCaps, - Credentials: sTx.Creds, + IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + BlockMaxComplexity: unitCaps, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -358,12 +358,12 @@ func verifyRemoveSubnetValidatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), - Config: backend.Config, - ChainTime: currentTimestamp, - FeeManager: feeManager, - ConsumedUnitsCap: unitCaps, - Credentials: sTx.Creds, + IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + BlockMaxComplexity: unitCaps, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return nil, false, err @@ -617,12 +617,12 @@ func verifyAddPermissionlessValidatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), - Config: backend.Config, - ChainTime: currentTimestamp, - FeeManager: feeManager, - ConsumedUnitsCap: unitCaps, - Credentials: sTx.Creds, + IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + BlockMaxComplexity: unitCaps, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -773,12 +773,12 @@ func verifyAddPermissionlessDelegatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), - Config: backend.Config, - ChainTime: currentTimestamp, - FeeManager: feeManager, - ConsumedUnitsCap: unitCaps, - Credentials: sTx.Creds, + IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + BlockMaxComplexity: unitCaps, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -840,12 +840,12 @@ func verifyTransferSubnetOwnershipTx( // Verify the flowcheck currentTimestamp := chainState.GetTimestamp() feeCalculator := fees.Calculator{ - IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), - Config: backend.Config, - ChainTime: currentTimestamp, - FeeManager: feeManager, - ConsumedUnitsCap: unitCaps, - Credentials: sTx.Creds, + IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), + Config: backend.Config, + ChainTime: currentTimestamp, + FeeManager: feeManager, + BlockMaxComplexity: unitCaps, + Credentials: sTx.Creds, } 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 96a7fcc28577..cd1c65d6b2a4 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -74,12 +74,12 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), - Config: e.Backend.Config, - ChainTime: currentTimestamp, - FeeManager: e.BlkFeeManager, - ConsumedUnitsCap: e.UnitCaps, - Credentials: e.Tx.Creds, + IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), + Config: e.Backend.Config, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + BlockMaxComplexity: e.UnitCaps, + Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -131,12 +131,12 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), - Config: e.Backend.Config, - ChainTime: currentTimestamp, - FeeManager: e.BlkFeeManager, - ConsumedUnitsCap: e.UnitCaps, - Credentials: e.Tx.Creds, + IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), + Config: e.Backend.Config, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + BlockMaxComplexity: e.UnitCaps, + Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -227,12 +227,12 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { currentTimestamp = e.State.GetTimestamp() ) feeCalculator := fees.Calculator{ - IsEUpgradeActive: cfg.IsEActivated(currentTimestamp), - Config: cfg, - ChainTime: currentTimestamp, - FeeManager: e.BlkFeeManager, - ConsumedUnitsCap: e.UnitCaps, - Credentials: e.Tx.Creds, + IsEUpgradeActive: cfg.IsEActivated(currentTimestamp), + Config: cfg, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + BlockMaxComplexity: e.UnitCaps, + Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -291,12 +291,12 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), - Config: e.Backend.Config, - ChainTime: currentTimestamp, - FeeManager: e.BlkFeeManager, - ConsumedUnitsCap: e.UnitCaps, - Credentials: e.Tx.Creds, + IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), + Config: e.Backend.Config, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + BlockMaxComplexity: e.UnitCaps, + Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -494,12 +494,12 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error } feeCalculator := fees.Calculator{ - IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), - Config: e.Backend.Config, - ChainTime: currentTimestamp, - FeeManager: e.BlkFeeManager, - ConsumedUnitsCap: e.UnitCaps, - Credentials: e.Tx.Creds, + IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), + Config: e.Backend.Config, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + BlockMaxComplexity: e.UnitCaps, + Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return err @@ -636,12 +636,12 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { currentTimestamp = e.State.GetTimestamp() ) feeCalculator := fees.Calculator{ - IsEUpgradeActive: cfg.IsEActivated(currentTimestamp), - Config: cfg, - ChainTime: currentTimestamp, - FeeManager: e.BlkFeeManager, - ConsumedUnitsCap: e.UnitCaps, - Credentials: e.Tx.Creds, + IsEUpgradeActive: cfg.IsEActivated(currentTimestamp), + Config: cfg, + ChainTime: currentTimestamp, + FeeManager: e.BlkFeeManager, + BlockMaxComplexity: e.UnitCaps, + Credentials: e.Tx.Creds, } 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 0cb22ed16fbb..434a55df73ad 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -92,8 +92,8 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: stateDiff, Tx: tx, } @@ -343,8 +343,8 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(freshTH.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &freshTH.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -386,8 +386,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -419,8 +419,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -467,8 +467,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -515,8 +515,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -546,8 +546,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -577,8 +577,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -610,8 +610,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -672,8 +672,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: duplicateSubnetTx, } @@ -714,8 +714,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -752,8 +752,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -788,8 +788,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -834,8 +834,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -874,8 +874,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -918,8 +918,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -959,8 +959,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -999,8 +999,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, State: onAcceptState, Tx: tx, } @@ -1586,8 +1586,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -1613,8 +1613,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -1643,8 +1643,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -1676,8 +1676,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -1707,8 +1707,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -1737,8 +1737,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -1769,8 +1769,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -1804,8 +1804,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -1961,8 +1961,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -1990,8 +1990,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -2021,8 +2021,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -2057,8 +2057,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } @@ -2098,8 +2098,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.UnitFees), - UnitCaps: feeCfg.BlockUnitsCap, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + UnitCaps: feeCfg.BlockMaxComplexity, Tx: env.tx, State: env.state, } diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index 3005f84f4b73..63823f0e7aa3 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -35,8 +35,8 @@ type Calculator struct { ChainTime time.Time // Post E-fork inputs - FeeManager *fees.Manager - ConsumedUnitsCap fees.Dimensions + FeeManager *fees.Manager + BlockMaxComplexity fees.Dimensions // common inputs Credentials []verify.Verifiable @@ -316,7 +316,7 @@ func (fc *Calculator) meterTx( } func (fc *Calculator) AddFeesFor(consumedUnits fees.Dimensions) (uint64, error) { - boundBreached, dimension := fc.FeeManager.CumulateUnits(consumedUnits, fc.ConsumedUnitsCap) + boundBreached, dimension := fc.FeeManager.CumulateUnits(consumedUnits, fc.BlockMaxComplexity) if boundBreached { return 0, fmt.Errorf("%w: breached dimension %d", errFailedConsumedUnitsCumulation, dimension) } diff --git a/vms/platformvm/txs/fees/calculator_test.go b/vms/platformvm/txs/fees/calculator_test.go index aa418b2eebe6..c8d74106ea87 100644 --- a/vms/platformvm/txs/fees/calculator_test.go +++ b/vms/platformvm/txs/fees/calculator_test.go @@ -70,9 +70,9 @@ func TestAddAndRemoveFees(t *testing.T) { r := require.New(t) fc := &Calculator{ - IsEUpgradeActive: true, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: fees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } var ( @@ -921,12 +921,12 @@ func TestTxFees(t *testing.T) { uTx, sTx := tt.unsignedAndSignedTx(t) fc := &Calculator{ - IsEUpgradeActive: cfg.IsEActivated(chainTime), - Config: cfg, - ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - ConsumedUnitsCap: consumedUnitCaps, - Credentials: sTx.Creds, + IsEUpgradeActive: cfg.IsEActivated(chainTime), + Config: cfg, + ChainTime: chainTime, + FeeManager: fees.NewManager(testUnitFees), + BlockMaxComplexity: consumedUnitCaps, + Credentials: sTx.Creds, } err := uTx.Visit(fc) r.ErrorIs(err, tt.expectedError) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index c460ca0eabbd..e3eb6c49929b 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -377,14 +377,14 @@ func TestGenesis(t *testing.T) { var ( chainTime = vm.state.GetTimestamp() feeCfg = config.GetDynamicFeesConfig(vm.Config.IsEActivated(chainTime)) - feeMan = commonfees.NewManager(feeCfg.UnitFees) + feeMan = commonfees.NewManager(feeCfg.FeeRate) feeCalc = &fees.Calculator{ - IsEUpgradeActive: vm.IsEActivated(chainTime), - Config: &vm.Config, - ChainTime: chainTime, - FeeManager: feeMan, - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: testSubnet1.Creds, + IsEUpgradeActive: vm.IsEActivated(chainTime), + Config: &vm.Config, + ChainTime: chainTime, + FeeManager: feeMan, + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Credentials: testSubnet1.Creds, } ) @@ -2268,14 +2268,14 @@ func TestBaseTx(t *testing.T) { var ( chainTime = vm.state.GetTimestamp() feeCfg = config.GetDynamicFeesConfig(vm.Config.IsEActivated(chainTime)) - feeMan = commonfees.NewManager(feeCfg.UnitFees) + feeMan = commonfees.NewManager(feeCfg.FeeRate) feeCalc = &fees.Calculator{ - IsEUpgradeActive: vm.IsEActivated(chainTime), - Config: &vm.Config, - ChainTime: chainTime, - FeeManager: feeMan, - ConsumedUnitsCap: feeCfg.BlockUnitsCap, - Credentials: baseTx.Creds, + IsEUpgradeActive: vm.IsEActivated(chainTime), + Config: &vm.Config, + ChainTime: chainTime, + FeeManager: feeMan, + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Credentials: baseTx.Creds, } ) diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index c7ea5e6b8a57..d7a598a2c46f 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -30,6 +30,7 @@ import ( "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" stdcontext "context" + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) @@ -100,9 +101,9 @@ func TestBaseTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewBaseTx( outputsToMove, @@ -114,10 +115,10 @@ func TestBaseTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(9930*units.MicroAvax, fc.Fee) @@ -140,8 +141,8 @@ func TestBaseTx(t *testing.T) { Config: &config.Config{ TxFee: testContext.CreateSubnetTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, } utx, err := builder.NewBaseTx( outputsToMove, @@ -157,9 +158,9 @@ func TestBaseTx(t *testing.T) { Config: &config.Config{ TxFee: testContext.CreateSubnetTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, - Credentials: tx.Creds, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(testContext.CreateSubnetTxFee, fc.Fee) @@ -229,9 +230,9 @@ func TestAddSubnetValidatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewAddSubnetValidatorTx(subnetValidator, feeCalc) require.NoError(err) @@ -244,9 +245,9 @@ func TestAddSubnetValidatorTx(t *testing.T) { Config: &config.Config{ AddSubnetValidatorFee: units.MilliAvax, }, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(9765*units.MicroAvax, fc.Fee) @@ -268,8 +269,8 @@ func TestAddSubnetValidatorTx(t *testing.T) { Config: &config.Config{ AddSubnetValidatorFee: testContext.AddSubnetValidatorFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, } utx, err := builder.NewAddSubnetValidatorTx(subnetValidator, feeCalc) require.NoError(err) @@ -282,9 +283,9 @@ func TestAddSubnetValidatorTx(t *testing.T) { Config: &config.Config{ AddSubnetValidatorFee: testContext.AddSubnetValidatorFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, - Credentials: tx.Creds, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(testContext.AddSubnetValidatorFee, fc.Fee) @@ -345,9 +346,9 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewRemoveSubnetValidatorTx( ids.GenerateTestNodeID(), @@ -360,10 +361,10 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(9741*units.MicroAvax, fc.Fee) @@ -386,8 +387,8 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { Config: &config.Config{ TxFee: testContext.BaseTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, } utx, err := builder.NewRemoveSubnetValidatorTx( ids.GenerateTestNodeID(), @@ -404,9 +405,9 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { Config: &config.Config{ TxFee: testContext.BaseTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, - Credentials: tx.Creds, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(testContext.BaseTxFee, fc.Fee) @@ -473,9 +474,9 @@ func TestCreateChainTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewCreateChainTx( subnetID, @@ -491,10 +492,10 @@ func TestCreateChainTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(9808*units.MicroAvax, fc.Fee) @@ -516,8 +517,8 @@ func TestCreateChainTx(t *testing.T) { Config: &config.Config{ CreateBlockchainTxFee: testContext.CreateBlockchainTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, } utx, err := builder.NewCreateChainTx( subnetID, @@ -537,8 +538,8 @@ func TestCreateChainTx(t *testing.T) { Config: &config.Config{ CreateBlockchainTxFee: testContext.CreateBlockchainTxFee, }, - ConsumedUnitsCap: commonfees.Max, - Credentials: tx.Creds, + BlockMaxComplexity: commonfees.Max, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(testContext.CreateBlockchainTxFee, fc.Fee) @@ -599,9 +600,9 @@ func TestCreateSubnetTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewCreateSubnetTx( subnetOwner, @@ -613,10 +614,10 @@ func TestCreateSubnetTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(9644*units.MicroAvax, fc.Fee) @@ -638,8 +639,8 @@ func TestCreateSubnetTx(t *testing.T) { Config: &config.Config{ CreateSubnetTxFee: testContext.CreateSubnetTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, } utx, err := builder.NewCreateSubnetTx( subnetOwner, @@ -655,9 +656,9 @@ func TestCreateSubnetTx(t *testing.T) { Config: &config.Config{ CreateSubnetTxFee: testContext.CreateSubnetTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, - Credentials: tx.Creds, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(testContext.CreateSubnetTxFee, fc.Fee) @@ -718,9 +719,9 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewTransferSubnetOwnershipTx( subnetID, @@ -733,10 +734,10 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(9761*units.MicroAvax, fc.Fee) @@ -758,8 +759,8 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { Config: &config.Config{ TxFee: testContext.BaseTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, } utx, err := builder.NewTransferSubnetOwnershipTx( subnetID, @@ -776,9 +777,9 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { Config: &config.Config{ TxFee: testContext.BaseTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, - Credentials: tx.Creds, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(testContext.BaseTxFee, fc.Fee) @@ -833,9 +834,9 @@ func TestImportTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewImportTx( sourceChainID, @@ -848,10 +849,10 @@ func TestImportTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(14251*units.MicroAvax, fc.Fee) @@ -875,8 +876,8 @@ func TestImportTx(t *testing.T) { Config: &config.Config{ TxFee: testContext.BaseTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, } utx, err := builder.NewImportTx( sourceChainID, @@ -893,9 +894,9 @@ func TestImportTx(t *testing.T) { Config: &config.Config{ TxFee: testContext.BaseTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, - Credentials: tx.Creds, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(testContext.BaseTxFee, fc.Fee) @@ -948,9 +949,9 @@ func TestExportTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewExportTx( subnetID, @@ -963,10 +964,10 @@ func TestExportTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(9966*units.MicroAvax, fc.Fee) @@ -989,8 +990,8 @@ func TestExportTx(t *testing.T) { Config: &config.Config{ TxFee: testContext.BaseTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, } utx, err := builder.NewExportTx( subnetID, @@ -1007,9 +1008,9 @@ func TestExportTx(t *testing.T) { Config: &config.Config{ TxFee: testContext.BaseTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, - Credentials: tx.Creds, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(testContext.BaseTxFee, fc.Fee) @@ -1075,9 +1076,9 @@ func TestTransformSubnetTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewTransformSubnetTx( subnetID, @@ -1102,10 +1103,10 @@ func TestTransformSubnetTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(14763*units.MicroAvax, fc.Fee) @@ -1130,8 +1131,8 @@ func TestTransformSubnetTx(t *testing.T) { Config: &config.Config{ TransformSubnetTxFee: testContext.TransformSubnetTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, } utx, err := builder.NewTransformSubnetTx( subnetID, @@ -1160,9 +1161,9 @@ func TestTransformSubnetTx(t *testing.T) { Config: &config.Config{ TransformSubnetTxFee: testContext.TransformSubnetTxFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, - Credentials: tx.Creds, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(testContext.TransformSubnetTxFee, fc.Fee) @@ -1222,9 +1223,9 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ @@ -1248,10 +1249,10 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(20404*units.MicroAvax, fc.Fee) @@ -1278,8 +1279,8 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { Config: &config.Config{ AddPrimaryNetworkValidatorFee: testContext.AddPrimaryNetworkValidatorFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, } utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ @@ -1307,9 +1308,9 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { Config: &config.Config{ AddPrimaryNetworkValidatorFee: testContext.AddPrimaryNetworkValidatorFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, - Credentials: tx.Creds, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(testContext.AddPrimaryNetworkValidatorFee, fc.Fee) @@ -1362,9 +1363,9 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewAddPermissionlessDelegatorTx( &txs.SubnetValidator{ @@ -1385,10 +1386,10 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), - ConsumedUnitsCap: testBlockMaxConsumedUnits, - Credentials: tx.Creds, + IsEUpgradeActive: true, + FeeManager: commonfees.NewManager(testUnitFees), + BlockMaxComplexity: testBlockMaxConsumedUnits, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(20212*units.MicroAvax, fc.Fee) @@ -1415,8 +1416,8 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { Config: &config.Config{ AddPrimaryNetworkDelegatorFee: testContext.AddPrimaryNetworkDelegatorFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, } utx, err := builder.NewAddPermissionlessDelegatorTx( &txs.SubnetValidator{ @@ -1441,9 +1442,9 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { Config: &config.Config{ AddPrimaryNetworkDelegatorFee: testContext.AddPrimaryNetworkDelegatorFee, }, - FeeManager: commonfees.NewManager(commonfees.Empty), - ConsumedUnitsCap: commonfees.Max, - Credentials: tx.Creds, + FeeManager: commonfees.NewManager(commonfees.Empty), + BlockMaxComplexity: commonfees.Max, + Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) require.Equal(testContext.AddPrimaryNetworkDelegatorFee, fc.Fee) diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 92cd8b4fa0db..036da2ca2d8b 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -280,8 +280,8 @@ type wallet struct { signer walletsigner.Signer client platformvm.Client - isEForkActive bool - unitFees, unitCaps commonfees.Dimensions + isEForkActive bool + feeRates, blockMaxComplexity commonfees.Dimensions } func (w *wallet) Builder() builder.Builder { @@ -304,14 +304,14 @@ func (w *wallet) IssueBaseTx( utx txs.UnsignedTx err error - feesMan = commonfees.NewManager(w.unitFees) + feesMan = commonfees.NewManager(w.feeRates) feeCalc = &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ CreateSubnetTxFee: w.builder.Context().CreateSubnetTxFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } ) @@ -332,14 +332,14 @@ func (w *wallet) IssueAddValidatorTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ AddPrimaryNetworkValidatorFee: w.builder.Context().AddPrimaryNetworkValidatorFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewAddValidatorTx(vdr, rewardsOwner, shares, feeCalc, options...) @@ -357,14 +357,14 @@ func (w *wallet) IssueAddSubnetValidatorTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ TxFee: w.builder.Context().BaseTxFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewAddSubnetValidatorTx(vdr, feeCalc, options...) @@ -383,14 +383,14 @@ func (w *wallet) IssueRemoveSubnetValidatorTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ TxFee: w.builder.Context().BaseTxFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewRemoveSubnetValidatorTx(nodeID, subnetID, feeCalc, options...) @@ -409,14 +409,14 @@ func (w *wallet) IssueAddDelegatorTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ AddPrimaryNetworkDelegatorFee: w.builder.Context().AddPrimaryNetworkDelegatorFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewAddDelegatorTx(vdr, rewardsOwner, feeCalc, options...) @@ -438,14 +438,14 @@ func (w *wallet) IssueCreateChainTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ CreateBlockchainTxFee: w.builder.Context().CreateBlockchainTxFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewCreateChainTx(subnetID, genesis, vmID, fxIDs, chainName, feeCalc, options...) @@ -463,14 +463,14 @@ func (w *wallet) IssueCreateSubnetTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ CreateSubnetTxFee: w.builder.Context().CreateSubnetTxFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewCreateSubnetTx(owner, feeCalc, options...) if err != nil { @@ -488,14 +488,14 @@ func (w *wallet) IssueTransferSubnetOwnershipTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ TxFee: w.builder.Context().BaseTxFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewTransferSubnetOwnershipTx(subnetID, owner, feeCalc, options...) @@ -514,14 +514,14 @@ func (w *wallet) IssueImportTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ TxFee: w.builder.Context().BaseTxFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewImportTx(sourceChainID, to, feeCalc, options...) @@ -540,14 +540,14 @@ func (w *wallet) IssueExportTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ TxFee: w.builder.Context().BaseTxFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewExportTx(chainID, outputs, feeCalc, options...) @@ -578,14 +578,14 @@ func (w *wallet) IssueTransformSubnetTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ TransformSubnetTxFee: w.builder.Context().TransformSubnetTxFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewTransformSubnetTx( subnetID, @@ -624,15 +624,15 @@ func (w *wallet) IssueAddPermissionlessValidatorTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ AddPrimaryNetworkValidatorFee: w.builder.Context().AddPrimaryNetworkValidatorFee, AddSubnetValidatorFee: w.builder.Context().AddSubnetValidatorFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewAddPermissionlessValidatorTx( @@ -661,15 +661,15 @@ func (w *wallet) IssueAddPermissionlessDelegatorTx( return nil, err } - feesMan := commonfees.NewManager(w.unitFees) + feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ IsEUpgradeActive: w.isEForkActive, Config: &config.Config{ AddPrimaryNetworkDelegatorFee: w.builder.Context().AddPrimaryNetworkDelegatorFee, AddSubnetDelegatorFee: w.builder.Context().AddSubnetDelegatorFee, }, - FeeManager: feesMan, - ConsumedUnitsCap: w.unitCaps, + FeeManager: feesMan, + BlockMaxComplexity: w.blockMaxComplexity, } utx, err := w.builder.NewAddPermissionlessDelegatorTx( @@ -753,7 +753,7 @@ func (w *wallet) refreshFork(options ...common.Option) error { w.isEForkActive = !chainTime.Before(eForkTime) feeCfg := config.GetDynamicFeesConfig(w.isEForkActive) - w.unitFees = feeCfg.UnitFees - w.unitCaps = feeCfg.BlockUnitsCap + w.feeRates = feeCfg.FeeRate + w.blockMaxComplexity = feeCfg.BlockMaxComplexity return nil } From b4f53294c7b1c9faf5351d637ea33d01ed686013 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 21 Mar 2024 16:38:28 +0100 Subject: [PATCH 068/120] some more renaming --- vms/components/fees/manager.go | 44 +-- vms/platformvm/block/builder/builder.go | 10 +- vms/platformvm/block/builder/helpers_test.go | 10 +- vms/platformvm/block/executor/helpers_test.go | 10 +- vms/platformvm/block/executor/manager.go | 10 +- vms/platformvm/block/executor/verifier.go | 14 +- vms/platformvm/config/dynamic_fees_config.go | 2 +- .../txs/executor/atomic_tx_executor.go | 10 +- .../txs/executor/create_chain_test.go | 50 +-- .../txs/executor/create_subnet_test.go | 10 +- vms/platformvm/txs/executor/helpers_test.go | 10 +- .../txs/executor/staker_tx_verification.go | 20 +- .../txs/executor/standard_tx_executor.go | 30 +- .../txs/executor/standard_tx_executor_test.go | 284 +++++++++--------- vms/platformvm/txs/fees/calculator.go | 4 +- vms/platformvm/txs/fees/calculator_test.go | 68 ++--- wallet/chain/p/builder_test.go | 47 ++- 17 files changed, 316 insertions(+), 317 deletions(-) diff --git a/vms/components/fees/manager.go b/vms/components/fees/manager.go index 325c0a73f994..cf18276c1938 100644 --- a/vms/components/fees/manager.go +++ b/vms/components/fees/manager.go @@ -10,26 +10,26 @@ import ( ) type Manager struct { - // Avax denominated unit fees for all fee dimensions - unitFees Dimensions + // Avax denominated fee rates, i.e. fees per unit of complexity. + feeRates Dimensions - // cumulatedUnits helps aggregating the units consumed by a block - // so that we can verify it's not too big/build it properly. - cumulatedUnits Dimensions + // cumulatedComplexity helps aggregating the units of complexity consumed + // by a block so that we can verify it's not too big/build it properly. + cumulatedComplexity Dimensions } -func NewManager(unitFees Dimensions) *Manager { +func NewManager(feeRate Dimensions) *Manager { return &Manager{ - unitFees: unitFees, + feeRates: feeRate, } } -func (m *Manager) GetUnitFees() Dimensions { - return m.unitFees +func (m *Manager) GetFeeRates() Dimensions { + return m.feeRates } -func (m *Manager) GetCumulatedUnits() Dimensions { - return m.cumulatedUnits +func (m *Manager) GetCumulatedComplexity() Dimensions { + return m.cumulatedComplexity } // CalculateFee must be a stateless method @@ -37,7 +37,7 @@ func (m *Manager) CalculateFee(units Dimensions) (uint64, error) { fee := uint64(0) for i := Dimension(0); i < FeeDimensions; i++ { - contribution, err := safemath.Mul64(m.unitFees[i], units[i]) + contribution, err := safemath.Mul64(m.feeRates[i], units[i]) if err != nil { return 0, err } @@ -49,13 +49,13 @@ func (m *Manager) CalculateFee(units Dimensions) (uint64, error) { return fee, nil } -// CumulateUnits tries to cumulate the consumed units [units]. Before +// CumulateComplexity tries to cumulate the consumed complexity [units]. Before // actually cumulating them, it checks whether the result would breach [bounds]. // If so, it returns the first dimension to breach bounds. -func (m *Manager) CumulateUnits(units, bounds Dimensions) (bool, Dimension) { +func (m *Manager) CumulateComplexity(units, bounds Dimensions) (bool, Dimension) { // Ensure we can consume (don't want partial update of values) for i := Dimension(0); i < FeeDimensions; i++ { - consumed, err := safemath.Add64(m.cumulatedUnits[i], units[i]) + consumed, err := safemath.Add64(m.cumulatedComplexity[i], units[i]) if err != nil { return true, i } @@ -66,27 +66,27 @@ func (m *Manager) CumulateUnits(units, bounds Dimensions) (bool, Dimension) { // Commit to consumption for i := Dimension(0); i < FeeDimensions; i++ { - consumed, err := safemath.Add64(m.cumulatedUnits[i], units[i]) + consumed, err := safemath.Add64(m.cumulatedComplexity[i], units[i]) if err != nil { return true, i } - m.cumulatedUnits[i] = consumed + m.cumulatedComplexity[i] = consumed } return false, 0 } -// Sometimes, e.g. while building a tx, we'd like freedom to speculatively add units -// and to remove them later on. [RemoveUnits] grants this freedom -func (m *Manager) RemoveUnits(unitsToRm Dimensions) error { +// Sometimes, e.g. while building a tx, we'd like freedom to speculatively add complexity +// and to remove it later on. [RemoveComplexity] grants this freedom +func (m *Manager) RemoveComplexity(unitsToRm Dimensions) error { var revertedUnits Dimensions for i := Dimension(0); i < FeeDimensions; i++ { - prev, err := safemath.Sub(m.cumulatedUnits[i], unitsToRm[i]) + prev, err := safemath.Sub(m.cumulatedComplexity[i], unitsToRm[i]) if err != nil { return fmt.Errorf("%w: dimension %d", err, i) } revertedUnits[i] = prev } - m.cumulatedUnits = revertedUnits + m.cumulatedComplexity = revertedUnits return nil } diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 53047b10cdd7..a81e67d7c953 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -361,11 +361,11 @@ func packBlockTxs( } executor := &txexecutor.StandardTxExecutor{ - Backend: backend, - BlkFeeManager: feeMan, - UnitCaps: feeCfg.BlockMaxComplexity, - State: txDiff, - Tx: tx, + Backend: backend, + BlkFeeManager: feeMan, + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: txDiff, + 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 6a1b8f89d447..f91bc6bec27c 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -265,11 +265,11 @@ func addSubnet(t *testing.T, env *environment) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := txexecutor.StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: stateDiff, - Tx: testSubnet1, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: stateDiff, + 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 e42fab90aa0f..bd18867dfc54 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -282,11 +282,11 @@ func addSubnet(env *environment) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := executor.StandardTxExecutor{ - Backend: env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: stateDiff, - Tx: testSubnet1, + Backend: env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: stateDiff, + 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 cfc6d39bab05..449b22c394c1 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -147,11 +147,11 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { isEActivated := m.txExecutorBackend.Config.IsEActivated(stateDiff.GetTimestamp()) feesCfg := config.GetDynamicFeesConfig(isEActivated) return tx.Unsigned.Visit(&executor.StandardTxExecutor{ - Backend: m.txExecutorBackend, - BlkFeeManager: fees.NewManager(feesCfg.FeeRate), - UnitCaps: feesCfg.BlockMaxComplexity, - State: stateDiff, - Tx: tx, + Backend: m.txExecutorBackend, + BlkFeeManager: fees.NewManager(feesCfg.FeeRate), + BlockMaxComplexity: feesCfg.BlockMaxComplexity, + State: stateDiff, + Tx: tx, }) } diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 5218604e851d..0e81af3ee839 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -88,7 +88,7 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { onDecisionState, onCommitState, onAbortState, - feesMan.GetCumulatedUnits(), + feesMan.GetCumulatedComplexity(), inputs, atomicRequests, onAcceptFunc, @@ -432,7 +432,7 @@ func (v *verifier) standardBlock( onAcceptFunc: onAcceptFunc, timestamp: onAcceptState.GetTimestamp(), - blockComplexity: feeMan.GetCumulatedUnits(), + blockComplexity: feeMan.GetCumulatedComplexity(), inputs: inputs, atomicRequests: atomicRequests, } @@ -458,11 +458,11 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID ) for _, tx := range txs { txExecutor := executor.StandardTxExecutor{ - Backend: v.txExecutorBackend, - BlkFeeManager: feesMan, - UnitCaps: feesCfg.BlockMaxComplexity, - State: state, - Tx: tx, + Backend: v.txExecutorBackend, + BlkFeeManager: feesMan, + BlockMaxComplexity: feesCfg.BlockMaxComplexity, + State: state, + Tx: tx, } if err := tx.Unsigned.Visit(&txExecutor); err != nil { txID := tx.ID() diff --git a/vms/platformvm/config/dynamic_fees_config.go b/vms/platformvm/config/dynamic_fees_config.go index 9c7f6755da28..a9cf48e99242 100644 --- a/vms/platformvm/config/dynamic_fees_config.go +++ b/vms/platformvm/config/dynamic_fees_config.go @@ -50,7 +50,7 @@ func ResetDynamicFeesConfig(ctx *snow.Context, customFeesConfig *commonfees.Dyna return nil // nothing to do } if ctx.NetworkID == constants.MainnetID || ctx.NetworkID == constants.FujiID { - return fmt.Errorf("forbidden resetting dynamic unit fees config for network %s", constants.NetworkName(ctx.NetworkID)) + return fmt.Errorf("forbidden resetting dynamic fee rates config for network %s", constants.NetworkName(ctx.NetworkID)) } customDynamicFeesConfig = customFeesConfig diff --git a/vms/platformvm/txs/executor/atomic_tx_executor.go b/vms/platformvm/txs/executor/atomic_tx_executor.go index eaad587c97c0..c301d4fe7453 100644 --- a/vms/platformvm/txs/executor/atomic_tx_executor.go +++ b/vms/platformvm/txs/executor/atomic_tx_executor.go @@ -103,11 +103,11 @@ func (e *AtomicTxExecutor) atomicTx(tx txs.UnsignedTx) error { feesCfg := config.GetDynamicFeesConfig(false /*isEActive*/) executor := StandardTxExecutor{ - Backend: e.Backend, - BlkFeeManager: commonfees.NewManager(feesCfg.FeeRate), - UnitCaps: feesCfg.BlockMaxComplexity, - State: e.OnAccept, - Tx: e.Tx, + Backend: e.Backend, + BlkFeeManager: commonfees.NewManager(feesCfg.FeeRate), + BlockMaxComplexity: feesCfg.BlockMaxComplexity, + State: e.OnAccept, + 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 779d4dbff456..9a5f0d332edd 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -58,11 +58,11 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -102,11 +102,11 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { chainTime := stateDiff.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -140,11 +140,11 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { currentTime := stateDiff.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(currentTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, database.ErrNotFound) @@ -175,11 +175,11 @@ func TestCreateChainTxValid(t *testing.T) { currentTime := stateDiff.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(currentTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: stateDiff, + Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) } @@ -269,11 +269,11 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { currentTime := stateDiff.GetTimestamp() feeCfg = config.GetDynamicFeesConfig(env.config.IsEActivated(currentTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + 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 f133f252ace7..29e5b46e38ec 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -110,11 +110,11 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { chainTime = stateDiff.GetTimestamp() feeCfg = config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, test.expectedErr) diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 9b7e49faf36f..adb03719d366 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -239,11 +239,11 @@ func addSubnet( chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: stateDiff, - Tx: testSubnet1, + Backend: &env.backend, + BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: stateDiff, + Tx: testSubnet1, } require.NoError(testSubnet1.Unsigned.Visit(&executor)) diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 382d864e31ed..45157421e5d2 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -199,7 +199,7 @@ func verifyAddValidatorTx( func verifyAddSubnetValidatorTx( backend *Backend, feeManager *commonFees.Manager, - unitCaps commonFees.Dimensions, + maxComplexity commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddSubnetValidatorTx, @@ -273,7 +273,7 @@ func verifyAddSubnetValidatorTx( Config: backend.Config, ChainTime: currentTimestamp, FeeManager: feeManager, - BlockMaxComplexity: unitCaps, + BlockMaxComplexity: maxComplexity, Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { @@ -307,7 +307,7 @@ func verifyAddSubnetValidatorTx( func verifyRemoveSubnetValidatorTx( backend *Backend, feeManager *commonFees.Manager, - unitCaps commonFees.Dimensions, + maxComplexity commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.RemoveSubnetValidatorTx, @@ -362,7 +362,7 @@ func verifyRemoveSubnetValidatorTx( Config: backend.Config, ChainTime: currentTimestamp, FeeManager: feeManager, - BlockMaxComplexity: unitCaps, + BlockMaxComplexity: maxComplexity, Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { @@ -518,7 +518,7 @@ func verifyAddDelegatorTx( func verifyAddPermissionlessValidatorTx( backend *Backend, feeManager *commonFees.Manager, - unitCaps commonFees.Dimensions, + maxComplexity commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddPermissionlessValidatorTx, @@ -621,7 +621,7 @@ func verifyAddPermissionlessValidatorTx( Config: backend.Config, ChainTime: currentTimestamp, FeeManager: feeManager, - BlockMaxComplexity: unitCaps, + BlockMaxComplexity: maxComplexity, Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { @@ -649,7 +649,7 @@ func verifyAddPermissionlessValidatorTx( func verifyAddPermissionlessDelegatorTx( backend *Backend, feeManager *commonFees.Manager, - unitCaps commonFees.Dimensions, + maxComplexity commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddPermissionlessDelegatorTx, @@ -777,7 +777,7 @@ func verifyAddPermissionlessDelegatorTx( Config: backend.Config, ChainTime: currentTimestamp, FeeManager: feeManager, - BlockMaxComplexity: unitCaps, + BlockMaxComplexity: maxComplexity, Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { @@ -809,7 +809,7 @@ func verifyAddPermissionlessDelegatorTx( func verifyTransferSubnetOwnershipTx( backend *Backend, feeManager *commonFees.Manager, - unitCaps commonFees.Dimensions, + maxComplexity commonFees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.TransferSubnetOwnershipTx, @@ -844,7 +844,7 @@ func verifyTransferSubnetOwnershipTx( Config: backend.Config, ChainTime: currentTimestamp, FeeManager: feeManager, - BlockMaxComplexity: unitCaps, + BlockMaxComplexity: maxComplexity, Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index cd1c65d6b2a4..f0c7d823e143 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -35,10 +35,10 @@ var ( type StandardTxExecutor struct { // inputs, to be filled before visitor methods are called *Backend - BlkFeeManager *commonFees.Manager - UnitCaps commonFees.Dimensions - State state.Diff // state is expected to be modified - Tx *txs.Tx + BlkFeeManager *commonFees.Manager + BlockMaxComplexity commonFees.Dimensions + State state.Diff // state is expected to be modified + Tx *txs.Tx // outputs of visitor execution OnAccept func() // may be nil @@ -78,7 +78,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { Config: e.Backend.Config, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, - BlockMaxComplexity: e.UnitCaps, + BlockMaxComplexity: e.BlockMaxComplexity, Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { @@ -135,7 +135,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { Config: e.Backend.Config, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, - BlockMaxComplexity: e.UnitCaps, + BlockMaxComplexity: e.BlockMaxComplexity, Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { @@ -231,7 +231,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { Config: cfg, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, - BlockMaxComplexity: e.UnitCaps, + BlockMaxComplexity: e.BlockMaxComplexity, Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { @@ -295,7 +295,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { Config: e.Backend.Config, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, - BlockMaxComplexity: e.UnitCaps, + BlockMaxComplexity: e.BlockMaxComplexity, Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { @@ -399,7 +399,7 @@ func (e *StandardTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) if err := verifyAddSubnetValidatorTx( e.Backend, e.BlkFeeManager, - e.UnitCaps, + e.BlockMaxComplexity, e.State, e.Tx, tx, @@ -446,7 +446,7 @@ func (e *StandardTxExecutor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidat staker, isCurrentValidator, err := verifyRemoveSubnetValidatorTx( e.Backend, e.BlkFeeManager, - e.UnitCaps, + e.BlockMaxComplexity, e.State, e.Tx, tx, @@ -498,7 +498,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error Config: e.Backend.Config, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, - BlockMaxComplexity: e.UnitCaps, + BlockMaxComplexity: e.BlockMaxComplexity, Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { @@ -539,7 +539,7 @@ func (e *StandardTxExecutor) AddPermissionlessValidatorTx(tx *txs.AddPermissionl if err := verifyAddPermissionlessValidatorTx( e.Backend, e.BlkFeeManager, - e.UnitCaps, + e.BlockMaxComplexity, e.State, e.Tx, tx, @@ -573,7 +573,7 @@ func (e *StandardTxExecutor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionl if err := verifyAddPermissionlessDelegatorTx( e.Backend, e.BlkFeeManager, - e.UnitCaps, + e.BlockMaxComplexity, e.State, e.Tx, tx, @@ -599,7 +599,7 @@ func (e *StandardTxExecutor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwn err := verifyTransferSubnetOwnershipTx( e.Backend, e.BlkFeeManager, - e.UnitCaps, + e.BlockMaxComplexity, e.State, e.Tx, tx, @@ -640,7 +640,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { Config: cfg, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, - BlockMaxComplexity: e.UnitCaps, + BlockMaxComplexity: e.BlockMaxComplexity, Credentials: e.Tx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 434a55df73ad..436c4638810d 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -91,11 +91,11 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: stateDiff, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: stateDiff, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, test.expectedError) @@ -342,11 +342,11 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { chainTime := freshTH.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(freshTH.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &freshTH.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &freshTH.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, tt.expectedExecutionErr) @@ -385,11 +385,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrPeriodMismatch) @@ -418,11 +418,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) } @@ -466,11 +466,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrNotValidator) @@ -514,11 +514,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrPeriodMismatch) @@ -545,11 +545,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrPeriodMismatch) @@ -576,11 +576,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } require.NoError(tx.Unsigned.Visit(&executor)) } @@ -609,11 +609,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrTimestampNotBeforeStartTime) @@ -671,11 +671,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: duplicateSubnetTx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: duplicateSubnetTx, } err = duplicateSubnetTx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrDuplicateValidator) @@ -713,11 +713,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, secp256k1fx.ErrInputIndicesNotSortedUnique) @@ -751,11 +751,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -787,11 +787,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, errUnauthorizedSubnetModification) @@ -833,11 +833,11 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrDuplicateValidator) @@ -873,11 +873,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrTimestampNotBeforeStartTime) @@ -917,11 +917,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrAlreadyValidator) @@ -958,11 +958,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrAlreadyValidator) @@ -998,11 +998,11 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { chainTime := env.state.GetTimestamp() feeCfg := config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) executor := StandardTxExecutor{ - Backend: &env.backend, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - State: onAcceptState, - Tx: tx, + Backend: &env.backend, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + State: onAcceptState, + Tx: tx, } err = tx.Unsigned.Visit(&executor) require.ErrorIs(err, ErrFlowCheckFailed) @@ -1586,10 +1586,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1613,10 +1613,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1643,10 +1643,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1676,10 +1676,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1707,10 +1707,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1737,10 +1737,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1769,10 +1769,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1804,10 +1804,10 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1961,10 +1961,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -1990,10 +1990,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -2021,10 +2021,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -2057,10 +2057,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e @@ -2098,10 +2098,10 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { FlowChecker: env.flowChecker, Ctx: &snow.Context{}, }, - BlkFeeManager: fees.NewManager(feeCfg.FeeRate), - UnitCaps: feeCfg.BlockMaxComplexity, - Tx: env.tx, - State: env.state, + BlkFeeManager: fees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + Tx: env.tx, + State: env.state, } e.Bootstrapped.Set(true) return env.unsignedTx, e diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index 63823f0e7aa3..9c6e6c6942c4 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -316,7 +316,7 @@ func (fc *Calculator) meterTx( } func (fc *Calculator) AddFeesFor(consumedUnits fees.Dimensions) (uint64, error) { - boundBreached, dimension := fc.FeeManager.CumulateUnits(consumedUnits, fc.BlockMaxComplexity) + boundBreached, dimension := fc.FeeManager.CumulateComplexity(consumedUnits, fc.BlockMaxComplexity) if boundBreached { return 0, fmt.Errorf("%w: breached dimension %d", errFailedConsumedUnitsCumulation, dimension) } @@ -331,7 +331,7 @@ func (fc *Calculator) AddFeesFor(consumedUnits fees.Dimensions) (uint64, error) } func (fc *Calculator) RemoveFeesFor(unitsToRm fees.Dimensions) (uint64, error) { - if err := fc.FeeManager.RemoveUnits(unitsToRm); err != nil { + if err := fc.FeeManager.RemoveComplexity(unitsToRm); err != nil { return 0, fmt.Errorf("failed removing units: %w", err) } diff --git a/vms/platformvm/txs/fees/calculator_test.go b/vms/platformvm/txs/fees/calculator_test.go index c8d74106ea87..e3c50f044f25 100644 --- a/vms/platformvm/txs/fees/calculator_test.go +++ b/vms/platformvm/txs/fees/calculator_test.go @@ -26,7 +26,7 @@ import ( ) var ( - testUnitFees = fees.Dimensions{ + testFeeRates = fees.Dimensions{ 1 * units.MicroAvax, 2 * units.MicroAvax, 3 * units.MicroAvax, @@ -61,7 +61,7 @@ type feeTests struct { description string cfgAndChainTimeF func() (*config.Config, time.Time) unsignedAndSignedTx func(t *testing.T) (txs.UnsignedTx, *txs.Tx) - consumedUnitCapsF func() fees.Dimensions + maxComplexityF func() fees.Dimensions expectedError error checksF func(*testing.T, *Calculator) } @@ -71,7 +71,7 @@ func TestAddAndRemoveFees(t *testing.T) { fc := &Calculator{ IsEUpgradeActive: true, - FeeManager: fees.NewManager(testUnitFees), + FeeManager: fees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } @@ -82,25 +82,25 @@ func TestAddAndRemoveFees(t *testing.T) { feeDelta, err := fc.AddFeesFor(units) r.NoError(err) - r.Equal(units, fc.FeeManager.GetCumulatedUnits()) + r.Equal(units, fc.FeeManager.GetCumulatedComplexity()) r.NotZero(feeDelta) r.Equal(feeDelta, fc.Fee) feeDelta2, err := fc.AddFeesFor(units) r.NoError(err) - r.Equal(doubleUnits, fc.FeeManager.GetCumulatedUnits()) + r.Equal(doubleUnits, fc.FeeManager.GetCumulatedComplexity()) r.Equal(feeDelta, feeDelta2) r.Equal(feeDelta+feeDelta2, fc.Fee) feeDelta3, err := fc.RemoveFeesFor(units) r.NoError(err) - r.Equal(units, fc.FeeManager.GetCumulatedUnits()) + r.Equal(units, fc.FeeManager.GetCumulatedComplexity()) r.Equal(feeDelta, feeDelta3) r.Equal(feeDelta, fc.Fee) feeDelta4, err := fc.RemoveFeesFor(units) r.NoError(err) - r.Zero(fc.FeeManager.GetCumulatedUnits()) + r.Zero(fc.FeeManager.GetCumulatedComplexity()) r.Equal(feeDelta, feeDelta4) r.Zero(fc.Fee) } @@ -186,7 +186,7 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.FeeManager.GetCumulatedUnits(), + fc.FeeManager.GetCumulatedComplexity(), ) }, }, @@ -202,7 +202,7 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, - consumedUnitCapsF: func() fees.Dimensions { + maxComplexityF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 90 - 1 return caps @@ -288,7 +288,7 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.FeeManager.GetCumulatedUnits(), + fc.FeeManager.GetCumulatedComplexity(), ) }, }, @@ -305,7 +305,7 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, unsignedAndSignedTx: createChainTx, - consumedUnitCapsF: func() fees.Dimensions { + maxComplexityF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 90 - 1 return caps @@ -354,7 +354,7 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.FeeManager.GetCumulatedUnits(), + fc.FeeManager.GetCumulatedComplexity(), ) }, }, @@ -370,7 +370,7 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, - consumedUnitCapsF: func() fees.Dimensions { + maxComplexityF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 90 - 1 return caps @@ -420,7 +420,7 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.FeeManager.GetCumulatedUnits(), + fc.FeeManager.GetCumulatedComplexity(), ) }, }, @@ -436,7 +436,7 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, - consumedUnitCapsF: func() fees.Dimensions { + maxComplexityF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 90 - 1 return caps @@ -486,7 +486,7 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.FeeManager.GetCumulatedUnits(), + fc.FeeManager.GetCumulatedComplexity(), ) }, }, @@ -502,7 +502,7 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, - consumedUnitCapsF: func() fees.Dimensions { + maxComplexityF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 90 - 1 return caps @@ -552,7 +552,7 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.FeeManager.GetCumulatedUnits(), + fc.FeeManager.GetCumulatedComplexity(), ) }, }, @@ -568,7 +568,7 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, - consumedUnitCapsF: func() fees.Dimensions { + maxComplexityF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 90 - 1 return caps @@ -618,7 +618,7 @@ func TestTxFees(t *testing.T) { 266, 1000, }, - fc.FeeManager.GetCumulatedUnits(), + fc.FeeManager.GetCumulatedComplexity(), ) }, }, @@ -634,7 +634,7 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, - consumedUnitCapsF: func() fees.Dimensions { + maxComplexityF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 90 - 1 return caps @@ -684,7 +684,7 @@ func TestTxFees(t *testing.T) { 266, 1000, }, - fc.FeeManager.GetCumulatedUnits(), + fc.FeeManager.GetCumulatedComplexity(), ) }, }, @@ -700,7 +700,7 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, - consumedUnitCapsF: func() fees.Dimensions { + maxComplexityF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 90 - 1 return caps @@ -750,7 +750,7 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.FeeManager.GetCumulatedUnits(), + fc.FeeManager.GetCumulatedComplexity(), ) }, }, @@ -766,7 +766,7 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, - consumedUnitCapsF: func() fees.Dimensions { + maxComplexityF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 90 - 1 return caps @@ -816,7 +816,7 @@ func TestTxFees(t *testing.T) { 262, 2000, }, - fc.FeeManager.GetCumulatedUnits(), + fc.FeeManager.GetCumulatedComplexity(), ) }, }, @@ -832,7 +832,7 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, - consumedUnitCapsF: func() fees.Dimensions { + maxComplexityF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 180 - 1 return caps @@ -882,7 +882,7 @@ func TestTxFees(t *testing.T) { 266, 1000, }, - fc.FeeManager.GetCumulatedUnits(), + fc.FeeManager.GetCumulatedComplexity(), ) }, }, @@ -898,7 +898,7 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, - consumedUnitCapsF: func() fees.Dimensions { + maxComplexityF: func() fees.Dimensions { caps := testBlockMaxConsumedUnits caps[fees.UTXORead] = 90 - 1 return caps @@ -913,9 +913,9 @@ func TestTxFees(t *testing.T) { t.Run(tt.description, func(t *testing.T) { cfg, chainTime := tt.cfgAndChainTimeF() - consumedUnitCaps := testBlockMaxConsumedUnits - if tt.consumedUnitCapsF != nil { - consumedUnitCaps = tt.consumedUnitCapsF() + maxComplexity := testBlockMaxConsumedUnits + if tt.maxComplexityF != nil { + maxComplexity = tt.maxComplexityF() } uTx, sTx := tt.unsignedAndSignedTx(t) @@ -924,8 +924,8 @@ func TestTxFees(t *testing.T) { IsEUpgradeActive: cfg.IsEActivated(chainTime), Config: cfg, ChainTime: chainTime, - FeeManager: fees.NewManager(testUnitFees), - BlockMaxComplexity: consumedUnitCaps, + FeeManager: fees.NewManager(testFeeRates), + BlockMaxComplexity: maxComplexity, Credentials: sTx.Creds, } err := uTx.Visit(fc) diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index d7a598a2c46f..e2b8bee64b3e 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -30,7 +30,6 @@ import ( "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" stdcontext "context" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) @@ -56,7 +55,7 @@ var ( AddSubnetDelegatorFee: 9 * units.Avax, } - testUnitFees = commonfees.Dimensions{ + testFeeRates = commonfees.Dimensions{ 1 * units.MicroAvax, 2 * units.MicroAvax, 3 * units.MicroAvax, @@ -102,7 +101,7 @@ func TestBaseTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewBaseTx( @@ -116,7 +115,7 @@ func TestBaseTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, Credentials: tx.Creds, } @@ -231,7 +230,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewAddSubnetValidatorTx(subnetValidator, feeCalc) @@ -245,7 +244,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { Config: &config.Config{ AddSubnetValidatorFee: units.MilliAvax, }, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, Credentials: tx.Creds, } @@ -347,7 +346,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewRemoveSubnetValidatorTx( @@ -362,7 +361,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, Credentials: tx.Creds, } @@ -475,7 +474,7 @@ func TestCreateChainTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewCreateChainTx( @@ -493,7 +492,7 @@ func TestCreateChainTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, Credentials: tx.Creds, } @@ -601,7 +600,7 @@ func TestCreateSubnetTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewCreateSubnetTx( @@ -615,7 +614,7 @@ func TestCreateSubnetTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, Credentials: tx.Creds, } @@ -720,7 +719,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewTransferSubnetOwnershipTx( @@ -735,7 +734,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, Credentials: tx.Creds, } @@ -835,7 +834,7 @@ func TestImportTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewImportTx( @@ -850,7 +849,7 @@ func TestImportTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, Credentials: tx.Creds, } @@ -950,7 +949,7 @@ func TestExportTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewExportTx( @@ -965,7 +964,7 @@ func TestExportTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, Credentials: tx.Creds, } @@ -1077,7 +1076,7 @@ func TestTransformSubnetTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewTransformSubnetTx( @@ -1104,7 +1103,7 @@ func TestTransformSubnetTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, Credentials: tx.Creds, } @@ -1224,7 +1223,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewAddPermissionlessValidatorTx( @@ -1250,7 +1249,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, Credentials: tx.Creds, } @@ -1364,7 +1363,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, } utx, err := builder.NewAddPermissionlessDelegatorTx( @@ -1387,7 +1386,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, - FeeManager: commonfees.NewManager(testUnitFees), + FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxConsumedUnits, Credentials: tx.Creds, } From 711733e4bfcc1a470d28481c1b52c62f67bf888d Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 21 Mar 2024 17:03:11 +0100 Subject: [PATCH 069/120] nits --- tests/e2e/p/permissionless_subnets.go | 4 ++-- wallet/chain/p/wallet.go | 28 +++++++++++++-------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/e2e/p/permissionless_subnets.go b/tests/e2e/p/permissionless_subnets.go index dc92bdd60d5c..e50a39674a1b 100644 --- a/tests/e2e/p/permissionless_subnets.go +++ b/tests/e2e/p/permissionless_subnets.go @@ -61,9 +61,9 @@ var _ = e2e.DescribePChain("[Permissionless Subnets]", func() { owner, e2e.WithDefaultContext(), ) - - subnetID = subnetTx.ID() require.NoError(err) + subnetID = subnetTx.ID() + require.NotEqual(subnetID, constants.PrimaryNetworkID) }) diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 036da2ca2d8b..dc803c2a7b5d 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -296,7 +296,7 @@ func (w *wallet) IssueBaseTx( outputs []*avax.TransferableOutput, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -328,7 +328,7 @@ func (w *wallet) IssueAddValidatorTx( shares uint32, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -353,7 +353,7 @@ func (w *wallet) IssueAddSubnetValidatorTx( vdr *txs.SubnetValidator, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -379,7 +379,7 @@ func (w *wallet) IssueRemoveSubnetValidatorTx( subnetID ids.ID, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -405,7 +405,7 @@ func (w *wallet) IssueAddDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -434,7 +434,7 @@ func (w *wallet) IssueCreateChainTx( chainName string, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -459,7 +459,7 @@ func (w *wallet) IssueCreateSubnetTx( owner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -484,7 +484,7 @@ func (w *wallet) IssueTransferSubnetOwnershipTx( owner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -510,7 +510,7 @@ func (w *wallet) IssueImportTx( to *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -536,7 +536,7 @@ func (w *wallet) IssueExportTx( outputs []*avax.TransferableOutput, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -574,7 +574,7 @@ func (w *wallet) IssueTransformSubnetTx( uptimeRequirement uint32, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -620,7 +620,7 @@ func (w *wallet) IssueAddPermissionlessValidatorTx( shares uint32, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -657,7 +657,7 @@ func (w *wallet) IssueAddPermissionlessDelegatorTx( rewardsOwner *secp256k1fx.OutputOwners, options ...common.Option, ) (*txs.Tx, error) { - if err := w.refreshFork(options...); err != nil { + if err := w.refreshFeesData(options...); err != nil { return nil, err } @@ -733,7 +733,7 @@ func (w *wallet) IssueTx( return nil } -func (w *wallet) refreshFork(options ...common.Option) error { +func (w *wallet) refreshFeesData(options ...common.Option) error { if w.isEForkActive { // E fork enables dinamic fees and it is active // not need to recheck From b89665271f1db39cb5f2f91ccfb0f408262f39a9 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 21 Mar 2024 17:24:58 +0100 Subject: [PATCH 070/120] minor code consolidation --- vms/platformvm/txs/builder/builder.go | 172 +++++--------------------- 1 file changed, 29 insertions(+), 143 deletions(-) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 746e05c9a01f..36f7de291dce 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -284,17 +284,7 @@ func (b *builder) NewImportTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) outOwner := &secp256k1fx.OutputOwners{ @@ -331,17 +321,7 @@ func (b *builder) NewExportTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) outputs := []*avax.TransferableOutput{{ @@ -385,17 +365,7 @@ func (b *builder) NewCreateChainTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) utx, err := pBuilder.NewCreateChainTx( @@ -427,17 +397,7 @@ func (b *builder) NewCreateSubnetTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) utils.Sort(ownerAddrs) // sort control addresses @@ -483,17 +443,7 @@ func (b *builder) NewTransformSubnetTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) utx, err := pBuilder.NewTransformSubnetTx( @@ -538,17 +488,7 @@ func (b *builder) NewAddValidatorTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) vdr := &txs.Validator{ @@ -595,17 +535,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) vdr := &txs.SubnetValidator{ @@ -656,17 +586,7 @@ func (b *builder) NewAddDelegatorTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) vdr := &txs.Validator{ @@ -710,17 +630,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) vdr := &txs.SubnetValidator{ @@ -768,17 +678,7 @@ func (b *builder) NewAddSubnetValidatorTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) vdr := &txs.SubnetValidator{ @@ -816,17 +716,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) utx, err := pBuilder.NewRemoveSubnetValidatorTx( @@ -856,17 +746,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) utils.Sort(ownerAddrs) // sort control addresses @@ -901,17 +781,7 @@ func (b *builder) NewBaseTx( ) (*txs.Tx, error) { var ( pBuilder, pSigner = b.builders(keys) - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) - - feeCalc = &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, - Config: b.cfg, - ChainTime: chainTime, - FeeManager: commonfees.NewManager(feeCfg.FeeRate), - BlockMaxComplexity: feeCfg.BlockMaxComplexity, - } + feeCalc = b.feeCalculator() ) out := &avax.TransferableOutput{ @@ -951,6 +821,22 @@ func (b *builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, return builder, signer } +func (b *builder) feeCalculator() *fees.Calculator { + var ( + chainTime = b.state.GetTimestamp() + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) + isEUpgradeActive = b.cfg.IsEActivated(chainTime) + ) + + return &fees.Calculator{ + IsEUpgradeActive: isEUpgradeActive, + Config: b.cfg, + ChainTime: chainTime, + FeeManager: commonfees.NewManager(feeCfg.FeeRate), + BlockMaxComplexity: feeCfg.BlockMaxComplexity, + } +} + func options(changeAddr ids.ShortID, memo []byte) []common.Option { return common.UnionOptions( []common.Option{common.WithChangeOwner(&secp256k1fx.OutputOwners{ From 7295437c8891f8fea93376e6733ecf504448f49e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 26 Mar 2024 09:54:58 +0100 Subject: [PATCH 071/120] nits --- vms/components/fees/helpers.go | 34 +++---- .../txs/executor/staker_tx_verification.go | 22 ++--- .../txs/executor/standard_tx_executor.go | 6 +- vms/platformvm/txs/fees/calculator.go | 88 +++++++++---------- vms/platformvm/txs/fees/calculator_test.go | 50 +++++------ wallet/chain/p/builder/builder.go | 26 +++--- wallet/chain/p/builder_test.go | 46 +++++----- 7 files changed, 136 insertions(+), 136 deletions(-) diff --git a/vms/components/fees/helpers.go b/vms/components/fees/helpers.go index 069cfa9a0305..ff6e0943c5fa 100644 --- a/vms/components/fees/helpers.go +++ b/vms/components/fees/helpers.go @@ -15,40 +15,40 @@ import ( ) func MeterInput(c codec.Manager, v uint16, in *avax.TransferableInput) (Dimensions, error) { - var consumedUnits Dimensions + var complexity Dimensions cost, err := in.In.Cost() if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving cost of input %s: %w", in.ID, err) + return complexity, fmt.Errorf("failed retrieving cost of input %s: %w", in.ID, err) } inSize, err := c.Size(v, in) if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving size of input %s: %w", in.ID, err) + return complexity, fmt.Errorf("failed retrieving size of input %s: %w", in.ID, err) } uInSize := uint64(inSize) - consumedUnits[Bandwidth] += uInSize - codec.CodecVersionSize - consumedUnits[UTXORead] += uInSize // inputs are read - consumedUnits[UTXOWrite] += uInSize // inputs are deleted - consumedUnits[Compute] += cost - return consumedUnits, nil + complexity[Bandwidth] += uInSize - codec.CodecVersionSize + complexity[UTXORead] += uInSize // inputs are read + complexity[UTXOWrite] += uInSize // inputs are deleted + complexity[Compute] += cost + return complexity, nil } func MeterOutput(c codec.Manager, v uint16, out *avax.TransferableOutput) (Dimensions, error) { - var consumedUnits Dimensions + var complexity Dimensions outSize, err := c.Size(v, out) if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving size of output %s: %w", out.ID, err) + return complexity, fmt.Errorf("failed retrieving size of output %s: %w", out.ID, err) } uOutSize := uint64(outSize) - consumedUnits[Bandwidth] += uOutSize - codec.CodecVersionSize - consumedUnits[UTXOWrite] += uOutSize - return consumedUnits, nil + complexity[Bandwidth] += uOutSize - codec.CodecVersionSize + complexity[UTXOWrite] += uOutSize + return complexity, nil } func MeterCredential(c codec.Manager, v uint16, keysCount int) (Dimensions, error) { - var consumedUnits Dimensions + var complexity Dimensions // Ensure that codec picks interface instead of the pointer to evaluate size. creds := make([]verify.Verifiable, 0, 1) @@ -58,10 +58,10 @@ func MeterCredential(c codec.Manager, v uint16, keysCount int) (Dimensions, erro credSize, err := c.Size(v, creds) if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving size of credentials: %w", err) + return complexity, fmt.Errorf("failed retrieving size of credentials: %w", err) } credSize -= wrappers.IntLen // length of the slice, we want the single credential - consumedUnits[Bandwidth] += uint64(credSize) - codec.CodecVersionSize - return consumedUnits, nil + complexity[Bandwidth] += uint64(credSize) - codec.CodecVersionSize + return complexity, nil } diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 45157421e5d2..2a37803f68b7 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -18,7 +18,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" safemath "github.com/ava-labs/avalanchego/utils/math" - commonFees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var ( @@ -198,8 +198,8 @@ func verifyAddValidatorTx( // AddSubnetValidatorTx. func verifyAddSubnetValidatorTx( backend *Backend, - feeManager *commonFees.Manager, - maxComplexity commonFees.Dimensions, + feeManager *commonfees.Manager, + maxComplexity commonfees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddSubnetValidatorTx, @@ -306,8 +306,8 @@ func verifyAddSubnetValidatorTx( // * The flow checker passes. func verifyRemoveSubnetValidatorTx( backend *Backend, - feeManager *commonFees.Manager, - maxComplexity commonFees.Dimensions, + feeManager *commonfees.Manager, + maxComplexity commonfees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.RemoveSubnetValidatorTx, @@ -517,8 +517,8 @@ func verifyAddDelegatorTx( // AddPermissionlessValidatorTx. func verifyAddPermissionlessValidatorTx( backend *Backend, - feeManager *commonFees.Manager, - maxComplexity commonFees.Dimensions, + feeManager *commonfees.Manager, + maxComplexity commonfees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddPermissionlessValidatorTx, @@ -648,8 +648,8 @@ func verifyAddPermissionlessValidatorTx( // AddPermissionlessDelegatorTx. func verifyAddPermissionlessDelegatorTx( backend *Backend, - feeManager *commonFees.Manager, - maxComplexity commonFees.Dimensions, + feeManager *commonfees.Manager, + maxComplexity commonfees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.AddPermissionlessDelegatorTx, @@ -808,8 +808,8 @@ func verifyAddPermissionlessDelegatorTx( // * The flow checker passes. func verifyTransferSubnetOwnershipTx( backend *Backend, - feeManager *commonFees.Manager, - maxComplexity commonFees.Dimensions, + feeManager *commonfees.Manager, + maxComplexity commonfees.Dimensions, chainState state.Chain, sTx *txs.Tx, tx *txs.TransferSubnetOwnershipTx, diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index f0c7d823e143..be33692930f3 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -21,7 +21,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fees" - commonFees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var ( @@ -35,8 +35,8 @@ var ( type StandardTxExecutor struct { // inputs, to be filled before visitor methods are called *Backend - BlkFeeManager *commonFees.Manager - BlockMaxComplexity commonFees.Dimensions + BlkFeeManager *commonfees.Manager + BlockMaxComplexity commonfees.Dimensions State state.Diff // state is expected to be modified Tx *txs.Tx diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index 9c6e6c6942c4..452d6734302e 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -22,8 +22,8 @@ import ( var ( _ txs.Visitor = (*Calculator)(nil) - errFailedFeeCalculation = errors.New("failed fee calculation") - errFailedConsumedUnitsCumulation = errors.New("failed cumulating consumed units") + errFailedFeeCalculation = errors.New("failed fee calculation") + errFailedComplexityCumulation = errors.New("failed cumulating complexity") ) type Calculator struct { @@ -73,12 +73,12 @@ func (fc *Calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { return nil } - consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) + complexity, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } - _, err = fc.AddFeesFor(consumedUnits) + _, err = fc.AddFeesFor(complexity) return err } @@ -88,12 +88,12 @@ func (fc *Calculator) CreateChainTx(tx *txs.CreateChainTx) error { return nil } - consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) + complexity, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } - _, err = fc.AddFeesFor(consumedUnits) + _, err = fc.AddFeesFor(complexity) return err } @@ -103,12 +103,12 @@ func (fc *Calculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { return nil } - consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) + complexity, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } - _, err = fc.AddFeesFor(consumedUnits) + _, err = fc.AddFeesFor(complexity) return err } @@ -118,12 +118,12 @@ func (fc *Calculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) e return nil } - consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) + complexity, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } - _, err = fc.AddFeesFor(consumedUnits) + _, err = fc.AddFeesFor(complexity) return err } @@ -133,12 +133,12 @@ func (fc *Calculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { return nil } - consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) + complexity, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } - _, err = fc.AddFeesFor(consumedUnits) + _, err = fc.AddFeesFor(complexity) return err } @@ -148,12 +148,12 @@ func (fc *Calculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipT return nil } - consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) + complexity, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } - _, err = fc.AddFeesFor(consumedUnits) + _, err = fc.AddFeesFor(complexity) return err } @@ -171,12 +171,12 @@ func (fc *Calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessVali copy(outs, tx.Outs) copy(outs[len(tx.Outs):], tx.StakeOuts) - consumedUnits, err := fc.meterTx(tx, outs, tx.Ins) + complexity, err := fc.meterTx(tx, outs, tx.Ins) if err != nil { return err } - _, err = fc.AddFeesFor(consumedUnits) + _, err = fc.AddFeesFor(complexity) return err } @@ -194,12 +194,12 @@ func (fc *Calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDele copy(outs, tx.Outs) copy(outs[len(tx.Outs):], tx.StakeOuts) - consumedUnits, err := fc.meterTx(tx, outs, tx.Ins) + complexity, err := fc.meterTx(tx, outs, tx.Ins) if err != nil { return err } - _, err = fc.AddFeesFor(consumedUnits) + _, err = fc.AddFeesFor(complexity) return err } @@ -209,12 +209,12 @@ func (fc *Calculator) BaseTx(tx *txs.BaseTx) error { return nil } - consumedUnits, err := fc.meterTx(tx, tx.Outs, tx.Ins) + complexity, err := fc.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err } - _, err = fc.AddFeesFor(consumedUnits) + _, err = fc.AddFeesFor(complexity) return err } @@ -228,12 +228,12 @@ func (fc *Calculator) ImportTx(tx *txs.ImportTx) error { copy(ins, tx.Ins) copy(ins[len(tx.Ins):], tx.ImportedInputs) - consumedUnits, err := fc.meterTx(tx, tx.Outs, ins) + complexity, err := fc.meterTx(tx, tx.Outs, ins) if err != nil { return err } - _, err = fc.AddFeesFor(consumedUnits) + _, err = fc.AddFeesFor(complexity) return err } @@ -247,12 +247,12 @@ func (fc *Calculator) ExportTx(tx *txs.ExportTx) error { copy(outs, tx.Outs) copy(outs[len(tx.Outs):], tx.ExportedOutputs) - consumedUnits, err := fc.meterTx(tx, outs, tx.Ins) + complexity, err := fc.meterTx(tx, outs, tx.Ins) if err != nil { return err } - _, err = fc.AddFeesFor(consumedUnits) + _, err = fc.AddFeesFor(complexity) return err } @@ -261,67 +261,67 @@ func (fc *Calculator) meterTx( allOuts []*avax.TransferableOutput, allIns []*avax.TransferableInput, ) (fees.Dimensions, error) { - var consumedUnits fees.Dimensions + var complexity fees.Dimensions uTxSize, err := txs.Codec.Size(txs.CodecVersion, uTx) if err != nil { - return consumedUnits, fmt.Errorf("couldn't calculate UnsignedTx marshal length: %w", err) + return complexity, fmt.Errorf("couldn't calculate UnsignedTx marshal length: %w", err) } - consumedUnits[fees.Bandwidth] = uint64(uTxSize) + complexity[fees.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 fc.Credentials { c, ok := cred.(*secp256k1fx.Credential) if !ok { - return consumedUnits, fmt.Errorf("don't know how to calculate complexity of %T", cred) + return complexity, fmt.Errorf("don't know how to calculate complexity of %T", cred) } credDimensions, err := fees.MeterCredential(txs.Codec, txs.CodecVersion, len(c.Sigs)) if err != nil { - return consumedUnits, fmt.Errorf("failed adding credential %d: %w", i, err) + return complexity, fmt.Errorf("failed adding credential %d: %w", i, err) } - consumedUnits, err = fees.Add(consumedUnits, credDimensions) + complexity, err = fees.Add(complexity, credDimensions) if err != nil { - return consumedUnits, fmt.Errorf("failed adding credentials: %w", err) + return complexity, fmt.Errorf("failed adding credentials: %w", err) } } - consumedUnits[fees.Bandwidth] += wrappers.IntLen // length of the credentials slice - consumedUnits[fees.Bandwidth] += codec.CodecVersionSize + complexity[fees.Bandwidth] += wrappers.IntLen // length of the credentials slice + complexity[fees.Bandwidth] += codec.CodecVersionSize for _, in := range allIns { inputDimensions, err := fees.MeterInput(txs.Codec, txs.CodecVersion, in) if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving size of inputs: %w", err) + return complexity, fmt.Errorf("failed retrieving size of inputs: %w", err) } inputDimensions[fees.Bandwidth] = 0 // inputs bandwidth is already accounted for above, so we zero it - consumedUnits, err = fees.Add(consumedUnits, inputDimensions) + complexity, err = fees.Add(complexity, inputDimensions) if err != nil { - return consumedUnits, fmt.Errorf("failed adding inputs: %w", err) + return complexity, fmt.Errorf("failed adding inputs: %w", err) } } for _, out := range allOuts { outputDimensions, err := fees.MeterOutput(txs.Codec, txs.CodecVersion, out) if err != nil { - return consumedUnits, fmt.Errorf("failed retrieving size of outputs: %w", err) + return complexity, fmt.Errorf("failed retrieving size of outputs: %w", err) } outputDimensions[fees.Bandwidth] = 0 // outputs bandwidth is already accounted for above, so we zero it - consumedUnits, err = fees.Add(consumedUnits, outputDimensions) + complexity, err = fees.Add(complexity, outputDimensions) if err != nil { - return consumedUnits, fmt.Errorf("failed adding outputs: %w", err) + return complexity, fmt.Errorf("failed adding outputs: %w", err) } } - return consumedUnits, nil + return complexity, nil } -func (fc *Calculator) AddFeesFor(consumedUnits fees.Dimensions) (uint64, error) { - boundBreached, dimension := fc.FeeManager.CumulateComplexity(consumedUnits, fc.BlockMaxComplexity) +func (fc *Calculator) AddFeesFor(complexity fees.Dimensions) (uint64, error) { + boundBreached, dimension := fc.FeeManager.CumulateComplexity(complexity, fc.BlockMaxComplexity) if boundBreached { - return 0, fmt.Errorf("%w: breached dimension %d", errFailedConsumedUnitsCumulation, dimension) + return 0, fmt.Errorf("%w: breached dimension %d", errFailedComplexityCumulation, dimension) } - fee, err := fc.FeeManager.CalculateFee(consumedUnits) + fee, err := fc.FeeManager.CalculateFee(complexity) if err != nil { return 0, fmt.Errorf("%w: %w", errFailedFeeCalculation, err) } diff --git a/vms/platformvm/txs/fees/calculator_test.go b/vms/platformvm/txs/fees/calculator_test.go index e3c50f044f25..a14408e27d00 100644 --- a/vms/platformvm/txs/fees/calculator_test.go +++ b/vms/platformvm/txs/fees/calculator_test.go @@ -32,7 +32,7 @@ var ( 3 * units.MicroAvax, 4 * units.MicroAvax, } - testBlockMaxConsumedUnits = fees.Dimensions{ + testBlockMaxComplexity = fees.Dimensions{ 3000, 3500, 1000, @@ -72,7 +72,7 @@ func TestAddAndRemoveFees(t *testing.T) { fc := &Calculator{ IsEUpgradeActive: true, FeeManager: fees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } var ( @@ -203,12 +203,12 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits + caps := testBlockMaxComplexity caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: addSubnetValidatorTx, - expectedError: errFailedConsumedUnitsCumulation, + expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *Calculator) {}, }, { @@ -306,11 +306,11 @@ func TestTxFees(t *testing.T) { }, unsignedAndSignedTx: createChainTx, maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits + caps := testBlockMaxComplexity caps[fees.UTXORead] = 90 - 1 return caps }, - expectedError: errFailedConsumedUnitsCumulation, + expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *Calculator) {}, }, { @@ -371,12 +371,12 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits + caps := testBlockMaxComplexity caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: createSubnetTx, - expectedError: errFailedConsumedUnitsCumulation, + expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *Calculator) {}, }, { @@ -437,12 +437,12 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits + caps := testBlockMaxComplexity caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: removeSubnetValidatorTx, - expectedError: errFailedConsumedUnitsCumulation, + expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *Calculator) {}, }, { @@ -503,12 +503,12 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits + caps := testBlockMaxComplexity caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: transformSubnetTx, - expectedError: errFailedConsumedUnitsCumulation, + expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *Calculator) {}, }, { @@ -569,12 +569,12 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits + caps := testBlockMaxComplexity caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: transferSubnetOwnershipTx, - expectedError: errFailedConsumedUnitsCumulation, + expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *Calculator) {}, }, { @@ -635,12 +635,12 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits + caps := testBlockMaxComplexity caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: addPermissionlessValidatorTx, - expectedError: errFailedConsumedUnitsCumulation, + expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *Calculator) {}, }, { @@ -701,12 +701,12 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits + caps := testBlockMaxComplexity caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: addPermissionlessDelegatorTx, - expectedError: errFailedConsumedUnitsCumulation, + expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *Calculator) {}, }, { @@ -767,12 +767,12 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits + caps := testBlockMaxComplexity caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: baseTx, - expectedError: errFailedConsumedUnitsCumulation, + expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *Calculator) {}, }, { @@ -833,12 +833,12 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits + caps := testBlockMaxComplexity caps[fees.UTXORead] = 180 - 1 return caps }, unsignedAndSignedTx: importTx, - expectedError: errFailedConsumedUnitsCumulation, + expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *Calculator) {}, }, { @@ -899,12 +899,12 @@ func TestTxFees(t *testing.T) { return &cfg, chainTime }, maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxConsumedUnits + caps := testBlockMaxComplexity caps[fees.UTXORead] = 90 - 1 return caps }, unsignedAndSignedTx: exportTx, - expectedError: errFailedConsumedUnitsCumulation, + expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *Calculator) {}, }, } @@ -913,7 +913,7 @@ func TestTxFees(t *testing.T) { t.Run(tt.description, func(t *testing.T) { cfg, chainTime := tt.cfgAndChainTimeF() - maxComplexity := testBlockMaxConsumedUnits + maxComplexity := testBlockMaxComplexity if tt.maxComplexityF != nil { maxComplexity = tt.maxComplexityF() } diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index d90eac215e8e..42dcad9dacd5 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -350,7 +350,7 @@ func (b *builder) NewBaseTx( toBurn[assetID] = amountToBurn } - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.BaseTx(utx); err != nil { return nil, err } @@ -395,7 +395,7 @@ func (b *builder) NewAddValidatorTx( } toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.AddValidatorTx(utx); err != nil { return nil, err } @@ -443,7 +443,7 @@ func (b *builder) NewAddSubnetValidatorTx( return nil, fmt.Errorf("account for credential fees: %w", err) } - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.AddSubnetValidatorTx(utx); err != nil { return nil, err } @@ -491,7 +491,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( return nil, fmt.Errorf("account for credential fees: %w", err) } - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.RemoveSubnetValidatorTx(utx); err != nil { return nil, err } @@ -532,7 +532,7 @@ func (b *builder) NewAddDelegatorTx( } toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.AddDelegatorTx(utx); err != nil { return nil, err } @@ -590,7 +590,7 @@ func (b *builder) NewCreateChainTx( return nil, fmt.Errorf("account for credential fees: %w", err) } - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err = feeCalc.CreateChainTx(utx); err != nil { return nil, err } @@ -627,7 +627,7 @@ func (b *builder) NewCreateSubnetTx( toStake := map[ids.ID]uint64{} toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.CreateSubnetTx(utx); err != nil { return nil, err } @@ -677,7 +677,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( return nil, fmt.Errorf("account for credential fees: %w", err) } - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.TransferSubnetOwnershipTx(utx); err != nil { return nil, err } @@ -786,7 +786,7 @@ func (b *builder) NewImportTx( // 3. Finance fees as much as possible with imported, Avax-denominated UTXOs - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.ImportTx(utx); err != nil { return nil, err } @@ -889,7 +889,7 @@ func (b *builder) NewExportTx( toBurn[assetID] = amountToBurn } - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.ExportTx(utx); err != nil { return nil, err } @@ -965,7 +965,7 @@ func (b *builder) NewTransformSubnetTx( return nil, fmt.Errorf("account for credential fees: %w", err) } - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.TransformSubnetTx(utx); err != nil { return nil, err } @@ -1015,7 +1015,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( } toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.AddPermissionlessValidatorTx(utx); err != nil { return nil, err } @@ -1059,7 +1059,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( } toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - // feesMan cumulates consumed units. Let's init it with utx filled so far + // feesMan cumulates complexity. Let's init it with utx filled so far if err := feeCalc.AddPermissionlessDelegatorTx(utx); err != nil { return nil, err } diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index e2b8bee64b3e..b1c747be5f0c 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -61,7 +61,7 @@ var ( 3 * units.MicroAvax, 4 * units.MicroAvax, } - testBlockMaxConsumedUnits = commonfees.Max + testBlockMaxComplexity = commonfees.Max ) // These tests create a tx, then verify that utxos included in the tx are @@ -102,7 +102,7 @@ func TestBaseTx(t *testing.T) { feeCalc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } utx, err := builder.NewBaseTx( outputsToMove, @@ -116,7 +116,7 @@ func TestBaseTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) @@ -231,7 +231,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { feeCalc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } utx, err := builder.NewAddSubnetValidatorTx(subnetValidator, feeCalc) require.NoError(err) @@ -245,7 +245,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { AddSubnetValidatorFee: units.MilliAvax, }, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) @@ -347,7 +347,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { feeCalc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } utx, err := builder.NewRemoveSubnetValidatorTx( ids.GenerateTestNodeID(), @@ -362,7 +362,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) @@ -475,7 +475,7 @@ func TestCreateChainTx(t *testing.T) { feeCalc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } utx, err := builder.NewCreateChainTx( subnetID, @@ -493,7 +493,7 @@ func TestCreateChainTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) @@ -601,7 +601,7 @@ func TestCreateSubnetTx(t *testing.T) { feeCalc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } utx, err := builder.NewCreateSubnetTx( subnetOwner, @@ -615,7 +615,7 @@ func TestCreateSubnetTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) @@ -720,7 +720,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { feeCalc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } utx, err := builder.NewTransferSubnetOwnershipTx( subnetID, @@ -735,7 +735,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) @@ -835,7 +835,7 @@ func TestImportTx(t *testing.T) { feeCalc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } utx, err := builder.NewImportTx( sourceChainID, @@ -850,7 +850,7 @@ func TestImportTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) @@ -950,7 +950,7 @@ func TestExportTx(t *testing.T) { feeCalc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } utx, err := builder.NewExportTx( subnetID, @@ -965,7 +965,7 @@ func TestExportTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) @@ -1077,7 +1077,7 @@ func TestTransformSubnetTx(t *testing.T) { feeCalc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } utx, err := builder.NewTransformSubnetTx( subnetID, @@ -1104,7 +1104,7 @@ func TestTransformSubnetTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) @@ -1224,7 +1224,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { feeCalc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ @@ -1250,7 +1250,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) @@ -1364,7 +1364,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { feeCalc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, } utx, err := builder.NewAddPermissionlessDelegatorTx( &txs.SubnetValidator{ @@ -1387,7 +1387,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { fc := &fees.Calculator{ IsEUpgradeActive: true, FeeManager: commonfees.NewManager(testFeeRates), - BlockMaxComplexity: testBlockMaxConsumedUnits, + BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, } require.NoError(utx.Visit(fc)) From 26e83926e4b1037a71deb302d7303d08c97039a5 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 26 Mar 2024 10:55:37 +0100 Subject: [PATCH 072/120] some more cleanup --- tests/e2e/p/workflow.go | 2 +- vms/platformvm/block/executor/manager.go | 4 +- vms/platformvm/block/executor/verifier.go | 6 +- vms/platformvm/service_test.go | 2 +- vms/platformvm/txs/builder/builder.go | 8 +- .../txs/executor/create_chain_test.go | 2 +- .../txs/executor/create_subnet_test.go | 2 +- .../txs/executor/staker_tx_verification.go | 41 +++++---- .../txs/executor/standard_tx_executor.go | 30 ++++--- vms/platformvm/txs/fees/calculator.go | 24 ++--- vms/platformvm/txs/fees/calculator_test.go | 4 +- vms/platformvm/vm_test.go | 4 +- wallet/chain/p/builder_test.go | 88 +++++++++---------- wallet/chain/p/wallet.go | 26 +++--- 14 files changed, 131 insertions(+), 112 deletions(-) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 71dfefd5446a..d630533a8100 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -158,7 +158,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { // retrieve fees paid for the tx feeCfg := config.GetDynamicFeesConfig(true /*isEActive*/) feeCalc := fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(feeCfg.FeeRate), BlockMaxComplexity: feeCfg.BlockMaxComplexity, Credentials: tx.Creds, diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index 449b22c394c1..b7f9d72c4e1b 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -144,8 +144,8 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - isEActivated := m.txExecutorBackend.Config.IsEActivated(stateDiff.GetTimestamp()) - feesCfg := config.GetDynamicFeesConfig(isEActivated) + isEActive := m.txExecutorBackend.Config.IsEActivated(stateDiff.GetTimestamp()) + feesCfg := config.GetDynamicFeesConfig(isEActive) return tx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: m.txExecutorBackend, BlkFeeManager: fees.NewManager(feesCfg.FeeRate), diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 0e81af3ee839..34c2e97cf5fe 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -447,9 +447,9 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID error, ) { var ( - isEActivated = v.txExecutorBackend.Config.IsEActivated(state.GetTimestamp()) - feesCfg = config.GetDynamicFeesConfig(isEActivated) - feesMan = fees.NewManager(feesCfg.FeeRate) + isEActive = v.txExecutorBackend.Config.IsEActivated(state.GetTimestamp()) + feesCfg = config.GetDynamicFeesConfig(isEActive) + feesMan = fees.NewManager(feesCfg.FeeRate) onAcceptFunc func() inputs set.Set[ids.ID] diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 4cbfd06250f2..a5331f9db3ce 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -358,7 +358,7 @@ func TestGetBalance(t *testing.T) { feeCfg = config.GetDynamicFeesConfig(service.vm.Config.IsEActivated(chainTime)) feeMan = commonfees.NewManager(feeCfg.FeeRate) feeCalc = &fees.Calculator{ - IsEUpgradeActive: service.vm.IsEActivated(chainTime), + IsEActive: service.vm.IsEActivated(chainTime), Config: &service.vm.Config, ChainTime: chainTime, FeeManager: feeMan, diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 36f7de291dce..8912544a3b5d 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -823,13 +823,13 @@ func (b *builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, func (b *builder) feeCalculator() *fees.Calculator { var ( - chainTime = b.state.GetTimestamp() - feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) - isEUpgradeActive = b.cfg.IsEActivated(chainTime) + chainTime = b.state.GetTimestamp() + feeCfg = config.GetDynamicFeesConfig(b.cfg.IsEActivated(chainTime)) + isEActive = b.cfg.IsEActivated(chainTime) ) return &fees.Calculator{ - IsEUpgradeActive: isEUpgradeActive, + IsEActive: isEActive, Config: b.cfg, ChainTime: chainTime, FeeManager: commonfees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 9a5f0d332edd..8787c4f9ca53 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -237,7 +237,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { chainTime = env.state.GetTimestamp() feeCfg = config.GetDynamicFeesConfig(cfg.IsEActivated(chainTime)) feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &cfg, ChainTime: test.time, FeeManager: commonfees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 29e5b46e38ec..bf1eaaa4394d 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -80,7 +80,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { chainTime = env.state.GetTimestamp() feeCfg = config.GetDynamicFeesConfig(env.config.IsEActivated(chainTime)) feeCalc = &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &cfg, ChainTime: test.time, FeeManager: commonfees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 2a37803f68b7..cf7daeba8741 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -101,6 +101,7 @@ func verifyAddValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isEActive = false // AddValidatorTx is forbidden with Durango activation ) if isDurangoActive { return nil, ErrAddValidatorTxPostDurango @@ -169,10 +170,10 @@ func verifyAddValidatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: false, - Config: backend.Config, - ChainTime: currentTimestamp, - Credentials: sTx.Creds, + IsEActive: isEActive, + Config: backend.Config, + ChainTime: currentTimestamp, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return nil, err @@ -212,6 +213,7 @@ func verifyAddSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isEActive = backend.Config.IsEActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -269,7 +271,7 @@ func verifyAddSubnetValidatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), + IsEActive: isEActive, Config: backend.Config, ChainTime: currentTimestamp, FeeManager: feeManager, @@ -320,6 +322,7 @@ func verifyRemoveSubnetValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isEActive = backend.Config.IsEActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return nil, false, err @@ -358,7 +361,7 @@ func verifyRemoveSubnetValidatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), + IsEActive: isEActive, Config: backend.Config, ChainTime: currentTimestamp, FeeManager: feeManager, @@ -400,6 +403,7 @@ func verifyAddDelegatorTx( var ( currentTimestamp = chainState.GetTimestamp() isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isEActive = false // AddDelegatorTx is forbidden with Durango activation ) if isDurangoActive { return nil, ErrAddDelegatorTxPostDurango @@ -488,10 +492,10 @@ func verifyAddDelegatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: false, - Config: backend.Config, - ChainTime: currentTimestamp, - Credentials: sTx.Creds, + IsEActive: isEActive, + Config: backend.Config, + ChainTime: currentTimestamp, + Credentials: sTx.Creds, } if err := tx.Visit(&feeCalculator); err != nil { return nil, err @@ -531,6 +535,7 @@ func verifyAddPermissionlessValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isEActive = backend.Config.IsEActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -617,7 +622,7 @@ func verifyAddPermissionlessValidatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), + IsEActive: isEActive, Config: backend.Config, ChainTime: currentTimestamp, FeeManager: feeManager, @@ -662,6 +667,7 @@ func verifyAddPermissionlessDelegatorTx( var ( currentTimestamp = chainState.GetTimestamp() isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isEActive = backend.Config.IsEActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -773,7 +779,7 @@ func verifyAddPermissionlessDelegatorTx( // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), + IsEActive: isEActive, Config: backend.Config, ChainTime: currentTimestamp, FeeManager: feeManager, @@ -814,7 +820,13 @@ func verifyTransferSubnetOwnershipTx( sTx *txs.Tx, tx *txs.TransferSubnetOwnershipTx, ) error { - if !backend.Config.IsDurangoActivated(chainState.GetTimestamp()) { + var ( + currentTimestamp = chainState.GetTimestamp() + isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + isEActive = backend.Config.IsEActivated(currentTimestamp) + ) + + if !isDurangoActive { return ErrDurangoUpgradeNotActive } @@ -838,9 +850,8 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck - currentTimestamp := chainState.GetTimestamp() feeCalculator := fees.Calculator{ - IsEUpgradeActive: backend.Config.IsEActivated(currentTimestamp), + IsEActive: isEActive, Config: backend.Config, ChainTime: currentTimestamp, FeeManager: feeManager, diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index be33692930f3..2f42a62c5bd2 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -62,6 +62,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { var ( currentTimestamp = e.State.GetTimestamp() isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isEActive = e.Config.IsEActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -74,7 +75,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), + IsEActive: isEActive, Config: e.Backend.Config, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, @@ -124,6 +125,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { var ( currentTimestamp = e.State.GetTimestamp() isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isEActive = e.Config.IsEActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -131,7 +133,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), + IsEActive: isEActive, Config: e.Backend.Config, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, @@ -175,6 +177,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { var ( currentTimestamp = e.State.GetTimestamp() isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isEActive = e.Config.IsEActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -227,7 +230,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { currentTimestamp = e.State.GetTimestamp() ) feeCalculator := fees.Calculator{ - IsEUpgradeActive: cfg.IsEActivated(currentTimestamp), + IsEActive: isEActive, Config: cfg, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, @@ -278,6 +281,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { var ( currentTimestamp = e.State.GetTimestamp() isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isEActive = e.Config.IsEActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -291,7 +295,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { // Verify the flowcheck feeCalculator := fees.Calculator{ - IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), + IsEActive: isEActive, Config: e.Backend.Config, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, @@ -477,6 +481,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error var ( currentTimestamp = e.State.GetTimestamp() isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp) + isEActive = e.Config.IsEActivated(currentTimestamp) ) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err @@ -494,7 +499,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error } feeCalculator := fees.Calculator{ - IsEUpgradeActive: e.Backend.Config.IsEActivated(currentTimestamp), + IsEActive: isEActive, Config: e.Backend.Config, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, @@ -617,7 +622,14 @@ func (e *StandardTxExecutor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwn } func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { - if !e.Backend.Config.IsDurangoActivated(e.State.GetTimestamp()) { + var ( + cfg = e.Backend.Config + currentTimestamp = e.State.GetTimestamp() + IsDurangoActive = cfg.IsDurangoActivated(currentTimestamp) + isEActive = cfg.IsEActivated(currentTimestamp) + ) + + if !IsDurangoActive { return ErrDurangoUpgradeNotActive } @@ -631,12 +643,8 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { } // Verify the flowcheck - var ( - cfg = e.Backend.Config - currentTimestamp = e.State.GetTimestamp() - ) feeCalculator := fees.Calculator{ - IsEUpgradeActive: cfg.IsEActivated(currentTimestamp), + IsEActive: isEActive, Config: cfg, ChainTime: currentTimestamp, FeeManager: e.BlkFeeManager, diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index 452d6734302e..b12a11380bb6 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -28,7 +28,7 @@ var ( type Calculator struct { // setup - IsEUpgradeActive bool + IsEActive bool // Pre E-fork inputs Config *config.Config @@ -68,7 +68,7 @@ func (*Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { } func (fc *Calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { - if !fc.IsEUpgradeActive { + if !fc.IsEActive { fc.Fee = fc.Config.AddSubnetValidatorFee return nil } @@ -83,7 +83,7 @@ func (fc *Calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { } func (fc *Calculator) CreateChainTx(tx *txs.CreateChainTx) error { - if !fc.IsEUpgradeActive { + if !fc.IsEActive { fc.Fee = fc.Config.GetCreateBlockchainTxFee(fc.ChainTime) return nil } @@ -98,7 +98,7 @@ func (fc *Calculator) CreateChainTx(tx *txs.CreateChainTx) error { } func (fc *Calculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { - if !fc.IsEUpgradeActive { + if !fc.IsEActive { fc.Fee = fc.Config.GetCreateSubnetTxFee(fc.ChainTime) return nil } @@ -113,7 +113,7 @@ func (fc *Calculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } func (fc *Calculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { - if !fc.IsEUpgradeActive { + if !fc.IsEActive { fc.Fee = fc.Config.TxFee return nil } @@ -128,7 +128,7 @@ func (fc *Calculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) e } func (fc *Calculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { - if !fc.IsEUpgradeActive { + if !fc.IsEActive { fc.Fee = fc.Config.TransformSubnetTxFee return nil } @@ -143,7 +143,7 @@ func (fc *Calculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { } func (fc *Calculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { - if !fc.IsEUpgradeActive { + if !fc.IsEActive { fc.Fee = fc.Config.TxFee return nil } @@ -158,7 +158,7 @@ func (fc *Calculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipT } func (fc *Calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { - if !fc.IsEUpgradeActive { + if !fc.IsEActive { if tx.Subnet != constants.PrimaryNetworkID { fc.Fee = fc.Config.AddSubnetValidatorFee } else { @@ -181,7 +181,7 @@ func (fc *Calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessVali } func (fc *Calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { - if !fc.IsEUpgradeActive { + if !fc.IsEActive { if tx.Subnet != constants.PrimaryNetworkID { fc.Fee = fc.Config.AddSubnetDelegatorFee } else { @@ -204,7 +204,7 @@ func (fc *Calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDele } func (fc *Calculator) BaseTx(tx *txs.BaseTx) error { - if !fc.IsEUpgradeActive { + if !fc.IsEActive { fc.Fee = fc.Config.TxFee return nil } @@ -219,7 +219,7 @@ func (fc *Calculator) BaseTx(tx *txs.BaseTx) error { } func (fc *Calculator) ImportTx(tx *txs.ImportTx) error { - if !fc.IsEUpgradeActive { + if !fc.IsEActive { fc.Fee = fc.Config.TxFee return nil } @@ -238,7 +238,7 @@ func (fc *Calculator) ImportTx(tx *txs.ImportTx) error { } func (fc *Calculator) ExportTx(tx *txs.ExportTx) error { - if !fc.IsEUpgradeActive { + if !fc.IsEActive { fc.Fee = fc.Config.TxFee return nil } diff --git a/vms/platformvm/txs/fees/calculator_test.go b/vms/platformvm/txs/fees/calculator_test.go index a14408e27d00..b99c47a5810b 100644 --- a/vms/platformvm/txs/fees/calculator_test.go +++ b/vms/platformvm/txs/fees/calculator_test.go @@ -70,7 +70,7 @@ func TestAddAndRemoveFees(t *testing.T) { r := require.New(t) fc := &Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: fees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -921,7 +921,7 @@ func TestTxFees(t *testing.T) { uTx, sTx := tt.unsignedAndSignedTx(t) fc := &Calculator{ - IsEUpgradeActive: cfg.IsEActivated(chainTime), + IsEActive: cfg.IsEActivated(chainTime), Config: cfg, ChainTime: chainTime, FeeManager: fees.NewManager(testFeeRates), diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index e3eb6c49929b..f6b062a7df59 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -379,7 +379,7 @@ func TestGenesis(t *testing.T) { feeCfg = config.GetDynamicFeesConfig(vm.Config.IsEActivated(chainTime)) feeMan = commonfees.NewManager(feeCfg.FeeRate) feeCalc = &fees.Calculator{ - IsEUpgradeActive: vm.IsEActivated(chainTime), + IsEActive: vm.IsEActivated(chainTime), Config: &vm.Config, ChainTime: chainTime, FeeManager: feeMan, @@ -2270,7 +2270,7 @@ func TestBaseTx(t *testing.T) { feeCfg = config.GetDynamicFeesConfig(vm.Config.IsEActivated(chainTime)) feeMan = commonfees.NewManager(feeCfg.FeeRate) feeCalc = &fees.Calculator{ - IsEUpgradeActive: vm.IsEActivated(chainTime), + IsEActive: vm.IsEActivated(chainTime), Config: &vm.Config, ChainTime: chainTime, FeeManager: feeMan, diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index b1c747be5f0c..25afd473447e 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -100,7 +100,7 @@ func TestBaseTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -114,7 +114,7 @@ func TestBaseTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, @@ -136,7 +136,7 @@ func TestBaseTx(t *testing.T) { { // Pre E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TxFee: testContext.CreateSubnetTxFee, }, @@ -153,7 +153,7 @@ func TestBaseTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TxFee: testContext.CreateSubnetTxFee, }, @@ -229,7 +229,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -240,7 +240,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, Config: &config.Config{ AddSubnetValidatorFee: units.MilliAvax, }, @@ -264,7 +264,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { { // Pre E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ AddSubnetValidatorFee: testContext.AddSubnetValidatorFee, }, @@ -278,7 +278,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ AddSubnetValidatorFee: testContext.AddSubnetValidatorFee, }, @@ -345,7 +345,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -360,7 +360,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, @@ -382,7 +382,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { { // Pre E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TxFee: testContext.BaseTxFee, }, @@ -400,7 +400,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TxFee: testContext.BaseTxFee, }, @@ -473,7 +473,7 @@ func TestCreateChainTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -491,7 +491,7 @@ func TestCreateChainTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, @@ -512,7 +512,7 @@ func TestCreateChainTx(t *testing.T) { { // Pre E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ CreateBlockchainTxFee: testContext.CreateBlockchainTxFee, }, @@ -533,7 +533,7 @@ func TestCreateChainTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ CreateBlockchainTxFee: testContext.CreateBlockchainTxFee, }, @@ -599,7 +599,7 @@ func TestCreateSubnetTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -613,7 +613,7 @@ func TestCreateSubnetTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, @@ -634,7 +634,7 @@ func TestCreateSubnetTx(t *testing.T) { { // Pre E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ CreateSubnetTxFee: testContext.CreateSubnetTxFee, }, @@ -651,7 +651,7 @@ func TestCreateSubnetTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ CreateSubnetTxFee: testContext.CreateSubnetTxFee, }, @@ -718,7 +718,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -733,7 +733,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, @@ -754,7 +754,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { { // Pre E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TxFee: testContext.BaseTxFee, }, @@ -772,7 +772,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TxFee: testContext.BaseTxFee, }, @@ -833,7 +833,7 @@ func TestImportTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -848,7 +848,7 @@ func TestImportTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, @@ -871,7 +871,7 @@ func TestImportTx(t *testing.T) { { // Pre E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TxFee: testContext.BaseTxFee, }, @@ -889,7 +889,7 @@ func TestImportTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TxFee: testContext.BaseTxFee, }, @@ -948,7 +948,7 @@ func TestExportTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -963,7 +963,7 @@ func TestExportTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, @@ -985,7 +985,7 @@ func TestExportTx(t *testing.T) { { // Pre E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TxFee: testContext.BaseTxFee, }, @@ -1003,7 +1003,7 @@ func TestExportTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TxFee: testContext.BaseTxFee, }, @@ -1075,7 +1075,7 @@ func TestTransformSubnetTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -1102,7 +1102,7 @@ func TestTransformSubnetTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, @@ -1126,7 +1126,7 @@ func TestTransformSubnetTx(t *testing.T) { { // Pre E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TransformSubnetTxFee: testContext.TransformSubnetTxFee, }, @@ -1156,7 +1156,7 @@ func TestTransformSubnetTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ TransformSubnetTxFee: testContext.TransformSubnetTxFee, }, @@ -1222,7 +1222,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -1248,7 +1248,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, @@ -1274,7 +1274,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { { // Pre E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ AddPrimaryNetworkValidatorFee: testContext.AddPrimaryNetworkValidatorFee, }, @@ -1303,7 +1303,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ AddPrimaryNetworkValidatorFee: testContext.AddPrimaryNetworkValidatorFee, }, @@ -1362,7 +1362,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { { // Post E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, } @@ -1385,7 +1385,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: true, + IsEActive: true, FeeManager: commonfees.NewManager(testFeeRates), BlockMaxComplexity: testBlockMaxComplexity, Credentials: tx.Creds, @@ -1411,7 +1411,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { { // Pre E-Upgrade feeCalc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ AddPrimaryNetworkDelegatorFee: testContext.AddPrimaryNetworkDelegatorFee, }, @@ -1437,7 +1437,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { require.NoError(err) fc := &fees.Calculator{ - IsEUpgradeActive: false, + IsEActive: false, Config: &config.Config{ AddPrimaryNetworkDelegatorFee: testContext.AddPrimaryNetworkDelegatorFee, }, diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index dc803c2a7b5d..699c1d206b88 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -306,7 +306,7 @@ func (w *wallet) IssueBaseTx( feesMan = commonfees.NewManager(w.feeRates) feeCalc = &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ CreateSubnetTxFee: w.builder.Context().CreateSubnetTxFee, }, @@ -334,7 +334,7 @@ func (w *wallet) IssueAddValidatorTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ AddPrimaryNetworkValidatorFee: w.builder.Context().AddPrimaryNetworkValidatorFee, }, @@ -359,7 +359,7 @@ func (w *wallet) IssueAddSubnetValidatorTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ TxFee: w.builder.Context().BaseTxFee, }, @@ -385,7 +385,7 @@ func (w *wallet) IssueRemoveSubnetValidatorTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ TxFee: w.builder.Context().BaseTxFee, }, @@ -411,7 +411,7 @@ func (w *wallet) IssueAddDelegatorTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ AddPrimaryNetworkDelegatorFee: w.builder.Context().AddPrimaryNetworkDelegatorFee, }, @@ -440,7 +440,7 @@ func (w *wallet) IssueCreateChainTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ CreateBlockchainTxFee: w.builder.Context().CreateBlockchainTxFee, }, @@ -465,7 +465,7 @@ func (w *wallet) IssueCreateSubnetTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ CreateSubnetTxFee: w.builder.Context().CreateSubnetTxFee, }, @@ -490,7 +490,7 @@ func (w *wallet) IssueTransferSubnetOwnershipTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ TxFee: w.builder.Context().BaseTxFee, }, @@ -516,7 +516,7 @@ func (w *wallet) IssueImportTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ TxFee: w.builder.Context().BaseTxFee, }, @@ -542,7 +542,7 @@ func (w *wallet) IssueExportTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ TxFee: w.builder.Context().BaseTxFee, }, @@ -580,7 +580,7 @@ func (w *wallet) IssueTransformSubnetTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ TransformSubnetTxFee: w.builder.Context().TransformSubnetTxFee, }, @@ -626,7 +626,7 @@ func (w *wallet) IssueAddPermissionlessValidatorTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ AddPrimaryNetworkValidatorFee: w.builder.Context().AddPrimaryNetworkValidatorFee, AddSubnetValidatorFee: w.builder.Context().AddSubnetValidatorFee, @@ -663,7 +663,7 @@ func (w *wallet) IssueAddPermissionlessDelegatorTx( feesMan := commonfees.NewManager(w.feeRates) feeCalc := &fees.Calculator{ - IsEUpgradeActive: w.isEForkActive, + IsEActive: w.isEForkActive, Config: &config.Config{ AddPrimaryNetworkDelegatorFee: w.builder.Context().AddPrimaryNetworkDelegatorFee, AddSubnetDelegatorFee: w.builder.Context().AddSubnetDelegatorFee, From 4b6804bf4c9a22853011e5c902e7c405e2762d84 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 27 Mar 2024 10:22:57 +0100 Subject: [PATCH 073/120] fixed merge --- vms/components/fees/helpers.go | 6 +++--- vms/platformvm/txs/fees/calculator.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vms/components/fees/helpers.go b/vms/components/fees/helpers.go index ff6e0943c5fa..4908008013ce 100644 --- a/vms/components/fees/helpers.go +++ b/vms/components/fees/helpers.go @@ -27,7 +27,7 @@ func MeterInput(c codec.Manager, v uint16, in *avax.TransferableInput) (Dimensio } uInSize := uint64(inSize) - complexity[Bandwidth] += uInSize - codec.CodecVersionSize + complexity[Bandwidth] += uInSize - codec.VersionSize complexity[UTXORead] += uInSize // inputs are read complexity[UTXOWrite] += uInSize // inputs are deleted complexity[Compute] += cost @@ -42,7 +42,7 @@ func MeterOutput(c codec.Manager, v uint16, out *avax.TransferableOutput) (Dimen } uOutSize := uint64(outSize) - complexity[Bandwidth] += uOutSize - codec.CodecVersionSize + complexity[Bandwidth] += uOutSize - codec.VersionSize complexity[UTXOWrite] += uOutSize return complexity, nil } @@ -62,6 +62,6 @@ func MeterCredential(c codec.Manager, v uint16, keysCount int) (Dimensions, erro } credSize -= wrappers.IntLen // length of the slice, we want the single credential - complexity[Bandwidth] += uint64(credSize) - codec.CodecVersionSize + complexity[Bandwidth] += uint64(credSize) - codec.VersionSize return complexity, nil } diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index b12a11380bb6..85f53c461f95 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -286,7 +286,7 @@ func (fc *Calculator) meterTx( } } complexity[fees.Bandwidth] += wrappers.IntLen // length of the credentials slice - complexity[fees.Bandwidth] += codec.CodecVersionSize + complexity[fees.Bandwidth] += codec.VersionSize for _, in := range allIns { inputDimensions, err := fees.MeterInput(txs.Codec, txs.CodecVersion, in) From cb1fefeeb76bd9256f0d55b1ce9a015b76f61aa3 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 27 Mar 2024 11:12:04 +0100 Subject: [PATCH 074/120] fixed leftover --- wallet/chain/p/builder/builder.go | 1 + 1 file changed, 1 insertion(+) diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index 42dcad9dacd5..d057865c3352 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -614,6 +614,7 @@ func (b *builder) NewCreateSubnetTx( // 1. Build core transaction without utxos ops := common.NewOptions(options) + utils.Sort(owner.Addrs) utx := &txs.CreateSubnetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.context.NetworkID, From 5d3fce99bb9a1125bb7c22d88299bbb43e46c16c Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 29 Mar 2024 09:27:48 +0100 Subject: [PATCH 075/120] reduced diffs --- vms/platformvm/txs/fees/calculator.go | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index 85f53c461f95..423a11cf9be7 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -52,21 +52,6 @@ func (fc *Calculator) AddValidatorTx(*txs.AddValidatorTx) error { return nil } -func (fc *Calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { - // AddValidatorTx is banned following Durango activation, so we - // only return the pre EUpgrade fee here - fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee - 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) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { if !fc.IsEActive { fc.Fee = fc.Config.AddSubnetValidatorFee @@ -82,6 +67,13 @@ func (fc *Calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { return err } +func (fc *Calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { + // AddValidatorTx is banned following Durango activation, so we + // only return the pre EUpgrade fee here + fc.Fee = fc.Config.AddPrimaryNetworkDelegatorFee + return nil +} + func (fc *Calculator) CreateChainTx(tx *txs.CreateChainTx) error { if !fc.IsEActive { fc.Fee = fc.Config.GetCreateBlockchainTxFee(fc.ChainTime) @@ -112,6 +104,14 @@ func (fc *Calculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { return err } +func (*Calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { + return nil // no fees +} + +func (*Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { + return nil // no fees +} + func (fc *Calculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { if !fc.IsEActive { fc.Fee = fc.Config.TxFee From cad065050459bf4aea8377ae7a65245eb322e6f6 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 2 Apr 2024 19:23:54 +0200 Subject: [PATCH 076/120] hardened AddFees RemoveFees in p-chain wallet --- vms/platformvm/txs/fees/calculator.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vms/platformvm/txs/fees/calculator.go b/vms/platformvm/txs/fees/calculator.go index 469e66af21c3..8067665a286a 100644 --- a/vms/platformvm/txs/fees/calculator.go +++ b/vms/platformvm/txs/fees/calculator.go @@ -338,6 +338,10 @@ func (fc *Calculator) meterTx( } func (fc *Calculator) AddFeesFor(complexity fees.Dimensions) (uint64, error) { + if fc.feeManager == nil || complexity == fees.Empty { + return 0, nil + } + boundBreached, dimension := fc.feeManager.CumulateComplexity(complexity, fc.blockMaxComplexity) if boundBreached { return 0, fmt.Errorf("%w: breached dimension %d", errFailedComplexityCumulation, dimension) @@ -353,6 +357,10 @@ func (fc *Calculator) AddFeesFor(complexity fees.Dimensions) (uint64, error) { } func (fc *Calculator) RemoveFeesFor(unitsToRm fees.Dimensions) (uint64, error) { + if fc.feeManager == nil || unitsToRm == fees.Empty { + return 0, nil + } + if err := fc.feeManager.RemoveComplexity(unitsToRm); err != nil { return 0, fmt.Errorf("failed removing units: %w", err) } From 47cefa13abbeeeea8f8dd6bbcd384e778fee390c Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 8 Apr 2024 13:23:09 +0200 Subject: [PATCH 077/120] fix proposal blocks block-complexity --- vms/platformvm/txs/executor/proposal_tx_executor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/platformvm/txs/executor/proposal_tx_executor.go b/vms/platformvm/txs/executor/proposal_tx_executor.go index 0e3faf539013..c512a5c0d67b 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor.go @@ -165,7 +165,7 @@ func (e *ProposalTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) if err := verifyAddSubnetValidatorTx( e.Backend, e.BlkFeeManager, - commonfees.Empty, + commonfees.Max, e.OnCommitState, e.Tx, tx, From bf36767ce9b6997c7081dc5b03c96c00a81a6670 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 8 Apr 2024 14:22:06 +0200 Subject: [PATCH 078/120] minor cleanup --- vms/platformvm/txs/executor/proposal_tx_executor.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vms/platformvm/txs/executor/proposal_tx_executor.go b/vms/platformvm/txs/executor/proposal_tx_executor.go index c512a5c0d67b..ddeb1f0d230e 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor.go @@ -47,8 +47,8 @@ var ( type ProposalTxExecutor struct { // inputs, to be filled before visitor methods are called *Backend - BlkFeeManager *commonfees.Manager - Tx *txs.Tx + 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. @@ -164,7 +164,7 @@ func (e *ProposalTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) if err := verifyAddSubnetValidatorTx( e.Backend, - e.BlkFeeManager, + commonfees.NewManager(commonfees.Empty), commonfees.Max, e.OnCommitState, e.Tx, From f54eb12c763854bcfb43d67e9afc958de811beaf Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 8 Apr 2024 14:50:47 +0200 Subject: [PATCH 079/120] some more minor cleanups --- .../txs/executor/staker_tx_verification.go | 6 +++--- vms/platformvm/txs/executor/standard_tx_executor.go | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index cffbc3f2f329..68d4e9282ec8 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -354,7 +354,7 @@ func verifyRemoveSubnetValidatorTx( // Verify the flowcheck var feeCalculator *fees.Calculator if !isEActive { - feeCalculator = fees.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + feeCalculator = fees.NewStaticCalculator(backend.Config, currentTimestamp) } else { feeCalculator = fees.NewDynamicCalculator(backend.Config, feeManager, maxComplexity, sTx.Creds) } @@ -481,7 +481,7 @@ func verifyAddDelegatorTx( } // Verify the flowcheck - feeCalculator := fees.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + feeCalculator := fees.NewStaticCalculator(backend.Config, currentTimestamp) if err := tx.Visit(feeCalculator); err != nil { return nil, err } @@ -835,7 +835,7 @@ func verifyTransferSubnetOwnershipTx( // Verify the flowcheck var feeCalculator *fees.Calculator if !isEActive { - feeCalculator = fees.NewStaticCalculator(backend.Config, chainState.GetTimestamp()) + feeCalculator = fees.NewStaticCalculator(backend.Config, currentTimestamp) } else { feeCalculator = fees.NewDynamicCalculator(backend.Config, feeManager, maxComplexity, sTx.Creds) } diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 2ad2bdbf70ff..40598f7cf8ce 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -76,7 +76,7 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { // Verify the flowcheck var feeCalculator *fees.Calculator if !isEActive { - feeCalculator = fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + feeCalculator = fees.NewStaticCalculator(e.Backend.Config, currentTimestamp) } else { feeCalculator = fees.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } @@ -133,7 +133,7 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { // Verify the flowcheck var feeCalculator *fees.Calculator if !isEActive { - feeCalculator = fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + feeCalculator = fees.NewStaticCalculator(e.Backend.Config, currentTimestamp) } else { feeCalculator = fees.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } @@ -225,7 +225,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { // Verify the flowcheck var feeCalculator *fees.Calculator if !isEActive { - feeCalculator = fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + feeCalculator = fees.NewStaticCalculator(e.Backend.Config, currentTimestamp) } else { feeCalculator = fees.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } @@ -289,7 +289,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { // Verify the flowcheck var feeCalculator *fees.Calculator if !isEActive { - feeCalculator = fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + feeCalculator = fees.NewStaticCalculator(e.Backend.Config, currentTimestamp) } else { feeCalculator = fees.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } @@ -492,7 +492,7 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error var feeCalculator *fees.Calculator if !isEActive { - feeCalculator = fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + feeCalculator = fees.NewStaticCalculator(e.Backend.Config, currentTimestamp) } else { feeCalculator = fees.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } @@ -635,7 +635,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { // Verify the flowcheck var feeCalculator *fees.Calculator if !isEActive { - feeCalculator = fees.NewStaticCalculator(e.Backend.Config, e.State.GetTimestamp()) + feeCalculator = fees.NewStaticCalculator(e.Backend.Config, currentTimestamp) } else { feeCalculator = fees.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } From f3b4936c95ef41570b2128c0255ece831deb4123 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 8 Apr 2024 14:53:15 +0200 Subject: [PATCH 080/120] nit --- vms/platformvm/txs/executor/standard_tx_executor_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 893812f1e7b5..7a48f8b20053 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -1658,7 +1658,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl) // Set dependency expectations. - env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes().AnyTimes() + 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) From f4d3bef9d9dbd814ebd1bbe0010cddb7c40fc063 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 9 Apr 2024 09:57:30 +0200 Subject: [PATCH 081/120] added block complexity UTs --- vms/platformvm/block/executor/helpers_test.go | 98 ++++- .../block/executor/verifier_test.go | 383 ++++++++++++++++++ 2 files changed, 470 insertions(+), 11 deletions(-) diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index cd9d5b669f02..02dbe732ea52 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -5,6 +5,7 @@ package executor import ( "fmt" + "math/rand" "testing" "time" @@ -35,6 +36,7 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "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/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/config" @@ -58,15 +60,14 @@ const ( pending stakerStatus = iota current - defaultWeight = 10000 - trackChecksum = false - apricotPhase3 fork = iota apricotPhase5 banff cortina durango eUpgrade + + latestFork = eUpgrade ) var ( @@ -75,17 +76,24 @@ var ( defaultGenesisTime = time.Date(1997, 1, 1, 0, 0, 0, 0, time.UTC) defaultValidateStartTime = defaultGenesisTime defaultValidateEndTime = defaultValidateStartTime.Add(10 * defaultMinStakingDuration) - defaultMinValidatorStake = 5 * units.MilliAvax - defaultBalance = 100 * defaultMinValidatorStake - preFundedKeys = secp256k1.TestKeys() - avaxAssetID = ids.ID{'y', 'e', 'e', 't'} - defaultTxFee = uint64(100) + + defaultMinValidatorStake = 5 * units.MilliAvax + defaultMaxValidatorStake = 500 * units.MilliAvax + defaultMinDelegatorStake = 1 * units.MilliAvax + defaultBalance = 100 * defaultMinValidatorStake + defaultWeight = defaultBalance / 2 + + preFundedKeys = secp256k1.TestKeys() + avaxAssetID = ids.ID{'y', 'e', 'e', 't'} + defaultTxFee = uint64(100) genesisBlkID ids.ID testSubnet1 *txs.Tx // Node IDs of genesis validators. Initialized in init function genesisNodeIDs []ids.NodeID + + fundedSharedMemoryCalls byte ) func init() { @@ -99,6 +107,10 @@ type stakerStatus uint type fork uint8 +type mutableSharedMemory struct { + atomic.SharedMemory +} + type staker struct { nodeID ids.NodeID rewardAddress ids.ShortID @@ -124,6 +136,7 @@ type environment struct { clk *mockable.Clock baseDB *versiondb.Database ctx *snow.Context + msm *mutableSharedMemory fx fx.Fx state state.State mockedState *state.MockState @@ -149,6 +162,12 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment res.ctx.AVAXAssetID = avaxAssetID res.ctx.SharedMemory = m.NewSharedMemory(res.ctx.ChainID) + msm := &mutableSharedMemory{ + SharedMemory: m.NewSharedMemory(res.ctx.ChainID), + } + res.ctx.SharedMemory = msm + res.msm = msm + res.fx = defaultFx(res.clk, res.ctx.Log, res.isBootstrapped.Get()) rewardsCalc := reward.NewCalculator(res.config.RewardConfig) @@ -297,6 +316,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( @@ -338,9 +360,9 @@ func defaultConfig(t *testing.T, f fork) *config.Config { TxFee: defaultTxFee, CreateSubnetTxFee: 100 * defaultTxFee, CreateBlockchainTxFee: 100 * defaultTxFee, - MinValidatorStake: 5 * units.MilliAvax, - MaxValidatorStake: 500 * units.MilliAvax, - MinDelegatorStake: 1 * units.MilliAvax, + MinValidatorStake: defaultMinValidatorStake, + MaxValidatorStake: defaultMaxValidatorStake, + MinDelegatorStake: defaultMinDelegatorStake, MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: reward.Config{ @@ -530,3 +552,57 @@ func addPendingValidator( } return addPendingValidatorTx, nil } + +// Returns a shared memory where GetDatabase returns a database +// where [recipientKey] has a balance of [amt] +func fundedSharedMemory( + t *testing.T, + env *environment, + sourceKey *secp256k1.PrivateKey, + peerChain ids.ID, + assets map[ids.ID]uint64, +) atomic.SharedMemory { + fundedSharedMemoryCalls++ + m := atomic.NewMemory(prefixdb.New([]byte{fundedSharedMemoryCalls}, env.baseDB)) + + sm := m.NewSharedMemory(env.ctx.ChainID) + peerSharedMemory := m.NewSharedMemory(peerChain) + + for assetID, amt := range assets { + // #nosec G404 + utxo := &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: ids.GenerateTestID(), + OutputIndex: rand.Uint32(), + }, + Asset: avax.Asset{ID: assetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: amt, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Addrs: []ids.ShortID{sourceKey.PublicKey().Address()}, + Threshold: 1, + }, + }, + } + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) + require.NoError(t, err) + + inputID := utxo.InputID() + require.NoError(t, peerSharedMemory.Apply(map[ids.ID]*atomic.Requests{ + env.ctx.ChainID: { + PutRequests: []*atomic.Element{ + { + Key: inputID[:], + Value: utxoBytes, + Traits: [][]byte{ + sourceKey.PublicKey().Address().Bytes(), + }, + }, + }, + }, + })) + } + + return sm +} diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index 1d77c50e6d12..db0eacba5265 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -15,19 +15,402 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "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/logging" "github.com/ava-labs/avalanchego/utils/set" "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/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/block" "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/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/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) +// Check that complexity of standard blocks is duly calculated once block is verified +// Only transactions active post E upgrade are considered and tested pre and post E upgrade. +func TestStandardBlockComplexity(t *testing.T) { + type test struct { + name string + setupTest func(env *environment) *txs.Tx + } + + tests := []test{ + { + name: "AddPermissionlessValidatorTx", + setupTest: func(env *environment) *txs.Tx { + var ( + nodeID = ids.GenerateTestNodeID() + chainTime = env.state.GetTimestamp() + endTime = chainTime.Add(defaultMaxStakingDuration) + ) + sk, err := bls.NewSecretKey() + require.NoError(t, err) + + tx, err := env.txBuilder.NewAddPermissionlessValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + End: uint64(endTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, + signer.NewProofOfPossession(sk), + env.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, + reward.PercentDenominator, + preFundedKeys, + ) + require.NoError(t, err) + + return tx + }, + }, + { + name: "AddPermissionlessDelegatorTx", + setupTest: func(env *environment) *txs.Tx { + var primaryValidator *state.Staker + it, err := env.state.GetCurrentStakerIterator() + require.NoError(t, err) + for it.Next() { + staker := it.Value() + if staker.Priority != txs.PrimaryNetworkValidatorCurrentPriority { + continue + } + primaryValidator = staker + break + } + it.Release() + + tx, err := env.txBuilder.NewAddPermissionlessDelegatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: primaryValidator.NodeID, + End: uint64(primaryValidator.EndTime.Unix()), + Wght: env.config.MinDelegatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, + env.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, + preFundedKeys, + ) + require.NoError(t, err) + + return tx + }, + }, + { + name: "AddSubnetValidatorTx", + setupTest: func(env *environment) *txs.Tx { + var primaryValidator *state.Staker + it, err := env.state.GetCurrentStakerIterator() + require.NoError(t, err) + for it.Next() { + staker := it.Value() + if staker.Priority != txs.PrimaryNetworkValidatorCurrentPriority { + continue + } + primaryValidator = staker + break + } + it.Release() + + tx, err := env.txBuilder.NewAddSubnetValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: primaryValidator.NodeID, + End: uint64(primaryValidator.EndTime.Unix()), + Wght: defaultMinValidatorStake, + }, + Subnet: testSubnet1.TxID, + }, + preFundedKeys, + ) + require.NoError(t, err) + + return tx + }, + }, + { + name: "CreateChainTx", + setupTest: func(env *environment) *txs.Tx { + createChainTx, err := env.txBuilder.NewCreateChainTx( + testSubnet1.TxID, + []byte{}, // genesisData + ids.GenerateTestID(), // vmID + []ids.ID{}, // fxIDs + "aaa", // chain name + preFundedKeys, + ) + require.NoError(t, err) + return createChainTx + }, + }, + { + name: "CreateSubnetTx", + setupTest: func(env *environment) *txs.Tx { + tx, err := env.txBuilder.NewCreateSubnetTx( + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + preFundedKeys, + ) + require.NoError(t, err) + return tx + }, + }, + { + name: "RemoveSubnetValidatorTx", + setupTest: func(env *environment) *txs.Tx { + var primaryValidator *state.Staker + it, err := env.state.GetCurrentStakerIterator() + require.NoError(t, err) + for it.Next() { + staker := it.Value() + if staker.Priority != txs.PrimaryNetworkValidatorCurrentPriority { + continue + } + primaryValidator = staker + break + } + it.Release() + + endTime := primaryValidator.EndTime + subnetValTx, err := env.txBuilder.NewAddSubnetValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: primaryValidator.NodeID, + Start: 0, + End: uint64(endTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, + []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, + ) + require.NoError(t, err) + + onAcceptState, err := state.NewDiffOn(env.state) + require.NoError(t, err) + + require.NoError(t, subnetValTx.Unsigned.Visit(&executor.StandardTxExecutor{ + Backend: env.backend, + State: onAcceptState, + Tx: subnetValTx, + })) + + require.NoError(t, onAcceptState.Apply(env.state)) + require.NoError(t, env.state.Commit()) + + tx, err := env.txBuilder.NewRemoveSubnetValidatorTx( + primaryValidator.NodeID, + testSubnet1.ID(), + preFundedKeys, + ) + require.NoError(t, err) + + return tx + }, + }, + { + name: "TransformSubnetTx", + setupTest: func(env *environment) *txs.Tx { + tx, err := env.txBuilder.NewTransformSubnetTx( + testSubnet1.TxID, // subnetID + ids.GenerateTestID(), // assetID + 10, // initial supply + 10, // max supply + 0, // min consumption rate + reward.PercentDenominator, // max consumption rate + 2, // min validator stake + 10, // max validator stake + time.Minute, // min stake duration + time.Hour, // max stake duration + 1, // min delegation fees + 10, // min delegator stake + 1, // max validator weight factor + 80, // uptime requirement + preFundedKeys, + ) + require.NoError(t, err) + + return tx + }, + }, + { + name: "TransferSubnetOwnershipTx", + setupTest: func(env *environment) *txs.Tx { + tx, err := env.txBuilder.NewTransferSubnetOwnershipTx( + testSubnet1.TxID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, + preFundedKeys, + ) + require.NoError(t, err) + + return tx + }, + }, + { + name: "ImportTx", + setupTest: func(env *environment) *txs.Tx { + // Skip shared memory checks + env.backend.Bootstrapped.Set(false) + + var ( + sourceChain = env.ctx.XChainID + sourceKey = preFundedKeys[1] + sourceAmount = 10 * units.Avax + ) + + sharedMemory := fundedSharedMemory( + t, + env, + sourceKey, + sourceChain, + map[ids.ID]uint64{ + env.ctx.AVAXAssetID: sourceAmount, + }, + ) + env.msm.SharedMemory = sharedMemory + + tx, err := env.txBuilder.NewImportTx( + sourceChain, + &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{sourceKey.PublicKey().Address()}, + }, + preFundedKeys, + ) + require.NoError(t, err) + + // reactivate checks + env.backend.Bootstrapped.Set(true) + return tx + }, + }, + { + name: "ExportTx", + setupTest: func(env *environment) *txs.Tx { + tx, err := env.txBuilder.NewExportTx( + env.ctx.XChainID, + []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: env.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: units.Avax, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + }, + }}, + preFundedKeys, + ) + require.NoError(t, err) + + return tx + }, + }, + { + name: "BaseTx", + setupTest: func(env *environment) *txs.Tx { + tx, err := env.txBuilder.NewBaseTx( + []*avax.TransferableOutput{ + { + Asset: avax.Asset{ID: env.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: 1, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, + }, + }, + }, + preFundedKeys, + ) + require.NoError(t, err) + + return tx + }, + }, + } + + for _, tt := range tests { + for _, dynamicFeesActive := range []bool{false, true} { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + + f := latestFork + if !dynamicFeesActive { + f = durango + } + env := newEnvironment(t, nil, f) + env.ctx.Lock.Lock() + defer env.ctx.Lock.Unlock() + + tx := tt.setupTest(env) + + nextBlkTime, _, err := executor.NextBlockTime(env.state, env.clk) + require.NoError(err) + + parentBlkID := env.state.GetLastAccepted() + parentBlk, err := env.state.GetStatelessBlock(parentBlkID) + require.NoError(err) + + statelessBlk, err := block.NewBanffStandardBlock( + nextBlkTime, + parentBlkID, + parentBlk.Height()+1, + []*txs.Tx{tx}, + ) + require.NoError(err) + + blk := env.blkManager.NewBlock(statelessBlk) + require.NoError(blk.Verify(context.Background())) + + // check that metered complexity is non-zero post E upgrade and zero pre E upgrade + blkState, found := env.blkManager.(*manager).blkIDToState[blk.ID()] + require.True(found) + + if dynamicFeesActive { + require.NotEqual(commonfees.Empty, blkState.blockComplexity) + } else { + require.Equal(commonfees.Empty, blkState.blockComplexity) + } + }) + } + } +} + func TestVerifierVisitProposalBlock(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) From a979da38b6ebe9192f0f65c889e35ece2c1d242a Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 23 Apr 2024 15:49:20 +0200 Subject: [PATCH 082/120] P chain meter fees fee config (#2961) Signed-off-by: Alberto Benegiamo --- node/node.go | 66 +- tests/e2e/p/workflow.go | 2 +- vms/platformvm/block/builder/helpers_test.go | 34 +- vms/platformvm/block/executor/helpers_test.go | 34 +- .../block/executor/verifier_test.go | 79 ++- vms/platformvm/config/config.go | 72 +- vms/platformvm/service_test.go | 13 +- vms/platformvm/txs/executor/helpers_test.go | 34 +- .../txs/executor/staker_tx_verification.go | 62 +- .../txs/executor/standard_tx_executor.go | 60 +- .../txs/executor/standard_tx_executor_test.go | 15 +- vms/platformvm/txs/fee/calculator.go | 53 +- vms/platformvm/txs/fee/calculator_test.go | 653 ++++++++++-------- vms/platformvm/txs/fee/static_config.go | 65 ++ vms/platformvm/txs/txstest/builder.go | 86 +-- vms/platformvm/txs/txstest/context.go | 36 +- vms/platformvm/upgrade/times.go | 50 ++ vms/platformvm/validator_set_property_test.go | 37 +- vms/platformvm/vm_regression_test.go | 11 +- vms/platformvm/vm_test.go | 129 ++-- wallet/chain/p/builder_test.go | 45 +- wallet/chain/p/wallet.go | 11 +- 22 files changed, 914 insertions(+), 733 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/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index bc615c3aaa6c..2c145f8cb509 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -62,7 +62,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { infoClient := info.NewClient(nodeURI.URI) staticFees, err := infoClient.GetTxFee(e2e.DefaultContext()) require.NoError(err) - pChainStaticFees := &config.Config{ + pChainStaticFees := fee.StaticConfig{ TxFee: uint64(staticFees.TxFee), CreateSubnetTxFee: uint64(staticFees.CreateSubnetTxFee), TransformSubnetTxFee: uint64(staticFees.TransformSubnetTxFee), diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index ca52470afc13..5a734e63776b 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -44,8 +44,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" @@ -313,26 +315,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 02dbe732ea52..95ec4ab77adb 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -47,8 +47,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" @@ -357,26 +359,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: defaultMinValidatorStake, - MaxValidatorStake: defaultMaxValidatorStake, - MinDelegatorStake: defaultMinDelegatorStake, - MinStakeDuration: defaultMinStakingDuration, - MaxStakeDuration: defaultMaxStakingDuration, + StaticConfig: fee.StaticConfig{ + TxFee: defaultTxFee, + CreateSubnetTxFee: 100 * defaultTxFee, + CreateBlockchainTxFee: 100 * defaultTxFee, + }, + MinValidatorStake: defaultMinValidatorStake, + MaxValidatorStake: defaultMaxValidatorStake, + MinDelegatorStake: defaultMinDelegatorStake, + 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 db0eacba5265..da82691bab69 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -33,6 +33,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" "github.com/ava-labs/avalanchego/vms/secp256k1fx" commonfees "github.com/ava-labs/avalanchego/vms/components/fees" @@ -441,7 +442,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{}, }, @@ -525,8 +528,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{}, }, @@ -612,11 +617,13 @@ 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 - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + ApricotPhase5Time: time.Now().Add(time.Hour), + BanffTime: mockable.MaxTime, // banff is not activated + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, }, Clk: &mockable.Clock{}, }, @@ -720,7 +727,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{}, }, @@ -791,7 +800,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{}, }, @@ -850,7 +861,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{}, }, @@ -922,7 +935,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{}, }, @@ -1018,7 +1033,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{}, }, @@ -1097,11 +1114,13 @@ 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 - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + Times: upgrade.Times{ + ApricotPhase5Time: time.Now().Add(time.Hour), + BanffTime: mockable.MaxTime, // banff is not activated + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EUpgradeTime: mockable.MaxTime, + }, }, Clk: &mockable.Clock{}, }, @@ -1189,7 +1208,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{}, }, @@ -1246,7 +1267,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{}, }, @@ -1283,7 +1306,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{}, }, @@ -1326,7 +1351,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{}, }, @@ -1370,7 +1397,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{}, }, @@ -1413,7 +1442,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 3c8626b8df29..9b68d09001e2 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -384,17 +384,18 @@ func TestGetBalance(t *testing.T) { // we use the first key to fund a subnet creation in [defaultGenesis]. // As such we need to account for the subnet creation fee var ( - chainTime = service.vm.state.GetTimestamp() - - feeCalc *fee.Calculator + chainTime = service.vm.state.GetTimestamp() + staticFeeCfg = service.vm.Config.StaticConfig + feeCalc *fee.Calculator ) if !service.vm.IsEActivated(chainTime) { - feeCalc = fee.NewStaticCalculator(&service.vm.Config, chainTime) + upgrades := service.vm.Config.Times + feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { feeCfg := config.GetDynamicFeesConfig(service.vm.Config.IsEActivated(chainTime)) feeMan := commonfees.NewManager(feeCfg.FeeRate) - feeCalc = fee.NewDynamicCalculator(&service.vm.Config, feeMan, feeCfg.BlockMaxComplexity, testSubnet1.Creds) + feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, testSubnet1.Creds) } require.NoError(testSubnet1.Unsigned.Visit(feeCalc)) @@ -768,7 +769,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 dd8276b50727..4ab65cc35491 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" @@ -284,26 +286,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 c12bc9d85b0d..2ae2dd1a3f72 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -168,7 +168,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 } @@ -264,11 +268,15 @@ func verifyAddSubnetValidatorTx( } // Verify the flowcheck - var feeCalculator *fee.Calculator + var ( + feeCalculator *fee.Calculator + staticFeesCfg = backend.Config.StaticConfig + ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(backend.Config, currentTimestamp) + upgrades := backend.Config.Times + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) } else { - feeCalculator = fee.NewDynamicCalculator(backend.Config, feeManager, maxComplexity, sTx.Creds) + feeCalculator = fee.NewDynamicCalculator(staticFeesCfg, feeManager, maxComplexity, sTx.Creds) } if err := tx.Visit(feeCalculator); err != nil { return err @@ -352,11 +360,15 @@ func verifyRemoveSubnetValidatorTx( } // Verify the flowcheck - var feeCalculator *fee.Calculator + var ( + feeCalculator *fee.Calculator + staticFeesCfg = backend.Config.StaticConfig + ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(backend.Config, currentTimestamp) + upgrades := backend.Config.Times + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) } else { - feeCalculator = fee.NewDynamicCalculator(backend.Config, feeManager, maxComplexity, sTx.Creds) + feeCalculator = fee.NewDynamicCalculator(staticFeesCfg, feeManager, maxComplexity, sTx.Creds) } if err := tx.Visit(feeCalculator); err != nil { @@ -481,7 +493,11 @@ func verifyAddDelegatorTx( } // 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 } @@ -606,11 +622,15 @@ func verifyAddPermissionlessValidatorTx( copy(outs[len(tx.Outs):], tx.StakeOuts) // Verify the flowcheck - var feeCalculator *fee.Calculator + var ( + feeCalculator *fee.Calculator + staticFeesCfg = backend.Config.StaticConfig + ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(backend.Config, currentTimestamp) + upgrades := backend.Config.Times + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) } else { - feeCalculator = fee.NewDynamicCalculator(backend.Config, feeManager, maxComplexity, sTx.Creds) + feeCalculator = fee.NewDynamicCalculator(staticFeesCfg, feeManager, maxComplexity, sTx.Creds) } if err := tx.Visit(feeCalculator); err != nil { @@ -762,11 +782,15 @@ func verifyAddPermissionlessDelegatorTx( } // Verify the flowcheck - var feeCalculator *fee.Calculator + var ( + feeCalculator *fee.Calculator + staticFeesCfg = backend.Config.StaticConfig + ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(backend.Config, currentTimestamp) + upgrades := backend.Config.Times + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) } else { - feeCalculator = fee.NewDynamicCalculator(backend.Config, feeManager, maxComplexity, sTx.Creds) + feeCalculator = fee.NewDynamicCalculator(staticFeesCfg, feeManager, maxComplexity, sTx.Creds) } if err := tx.Visit(feeCalculator); err != nil { @@ -833,11 +857,15 @@ func verifyTransferSubnetOwnershipTx( } // Verify the flowcheck - var feeCalculator *fee.Calculator + var ( + feeCalculator *fee.Calculator + staticFeesCfg = backend.Config.StaticConfig + ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(backend.Config, currentTimestamp) + upgrades := backend.Config.Times + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) } else { - feeCalculator = fee.NewDynamicCalculator(backend.Config, feeManager, maxComplexity, sTx.Creds) + feeCalculator = fee.NewDynamicCalculator(staticFeesCfg, feeManager, maxComplexity, sTx.Creds) } if err := tx.Visit(feeCalculator); err != nil { diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 1370b54daf9f..38714767b470 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -74,11 +74,15 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { } // Verify the flowcheck - var feeCalculator *fee.Calculator + var ( + feeCalculator *fee.Calculator + staticFeesCfg = e.Backend.Config.StaticConfig + ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(e.Backend.Config, currentTimestamp) + upgrades := e.Backend.Config.Times + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) } else { - feeCalculator = fee.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) + feeCalculator = fee.NewDynamicCalculator(staticFeesCfg, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } if err := tx.Visit(feeCalculator); err != nil { @@ -131,11 +135,15 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { } // Verify the flowcheck - var feeCalculator *fee.Calculator + var ( + feeCalculator *fee.Calculator + staticFeesCfg = e.Backend.Config.StaticConfig + ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(e.Backend.Config, currentTimestamp) + upgrades := e.Backend.Config.Times + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) } else { - feeCalculator = fee.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) + feeCalculator = fee.NewDynamicCalculator(staticFeesCfg, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } if err := tx.Visit(feeCalculator); err != nil { @@ -223,11 +231,15 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins[len(tx.Ins):], tx.ImportedInputs) // Verify the flowcheck - var feeCalculator *fee.Calculator + var ( + feeCalculator *fee.Calculator + staticFeesCfg = e.Backend.Config.StaticConfig + ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(e.Backend.Config, currentTimestamp) + upgrades := e.Backend.Config.Times + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) } else { - feeCalculator = fee.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) + feeCalculator = fee.NewDynamicCalculator(staticFeesCfg, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } if err := tx.Visit(feeCalculator); err != nil { @@ -287,11 +299,15 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } // Verify the flowcheck - var feeCalculator *fee.Calculator + var ( + feeCalculator *fee.Calculator + staticFeesCfg = e.Backend.Config.StaticConfig + ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(e.Backend.Config, currentTimestamp) + upgrades := e.Backend.Config.Times + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) } else { - feeCalculator = fee.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) + feeCalculator = fee.NewDynamicCalculator(staticFeesCfg, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } if err := tx.Visit(feeCalculator); err != nil { @@ -490,11 +506,15 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error return err } - var feeCalculator *fee.Calculator + var ( + feeCalculator *fee.Calculator + staticFeesCfg = e.Backend.Config.StaticConfig + ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(e.Backend.Config, currentTimestamp) + upgrades := e.Backend.Config.Times + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) } else { - feeCalculator = fee.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) + feeCalculator = fee.NewDynamicCalculator(staticFeesCfg, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } if err := tx.Visit(feeCalculator); err != nil { return err @@ -633,11 +653,15 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { } // Verify the flowcheck - var feeCalculator *fee.Calculator + var ( + feeCalculator *fee.Calculator + staticFeesCfg = e.Backend.Config.StaticConfig + ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(e.Backend.Config, currentTimestamp) + upgrades := e.Backend.Config.Times + feeCalculator = fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) } else { - feeCalculator = fee.NewDynamicCalculator(e.Backend.Config, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) + feeCalculator = fee.NewDynamicCalculator(staticFeesCfg, e.BlkFeeManager, e.BlockMaxComplexity, e.Tx.Creds) } if err := tx.Visit(feeCalculator); err != nil { diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 7a48f8b20053..000b2ebbbb1f 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/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" @@ -2218,12 +2219,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 4c6a70cc1b84..4b18f579df1e 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -14,8 +14,8 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -31,7 +31,8 @@ type Calculator struct { isEActive bool // Pre E-fork inputs - config *config.Config + upgrades upgrade.Times + staticCfg StaticConfig chainTime time.Time // Post E-fork inputs @@ -43,24 +44,24 @@ type Calculator struct { Fee uint64 } -// NewStaticCalculator must be used pre E upgrade activation -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, } } // NewDynamicCalculator must be used post E upgrade activation func NewDynamicCalculator( - cfg *config.Config, + cfg StaticConfig, feeManager *fees.Manager, blockMaxComplexity fees.Dimensions, creds []verify.Verifiable, ) *Calculator { return &Calculator{ isEActive: true, - config: cfg, + staticCfg: cfg, feeManager: feeManager, blockMaxComplexity: blockMaxComplexity, credentials: creds, @@ -70,13 +71,13 @@ func NewDynamicCalculator( func (fc *Calculator) AddValidatorTx(*txs.AddValidatorTx) error { // AddValidatorTx is banned following Durango activation, so we // only return the pre EUpgrade fee here - fc.Fee = fc.config.AddPrimaryNetworkValidatorFee + fc.Fee = fc.staticCfg.AddPrimaryNetworkValidatorFee return nil } func (fc *Calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { if !fc.isEActive { - fc.Fee = fc.config.AddSubnetValidatorFee + fc.Fee = fc.staticCfg.AddSubnetValidatorFee return nil } @@ -92,17 +93,13 @@ func (fc *Calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { func (fc *Calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { // AddValidatorTx is banned following Durango activation, so we // only return the pre EUpgrade fee here - fc.Fee = fc.config.AddPrimaryNetworkDelegatorFee + fc.Fee = fc.staticCfg.AddPrimaryNetworkDelegatorFee return nil } func (fc *Calculator) CreateChainTx(tx *txs.CreateChainTx) error { if !fc.isEActive { - 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 } @@ -117,11 +114,7 @@ func (fc *Calculator) CreateChainTx(tx *txs.CreateChainTx) error { func (fc *Calculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { if !fc.isEActive { - 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 } @@ -144,7 +137,7 @@ func (*Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { func (fc *Calculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { if !fc.isEActive { - fc.Fee = fc.config.TxFee + fc.Fee = fc.staticCfg.TxFee return nil } @@ -159,7 +152,7 @@ func (fc *Calculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) e func (fc *Calculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { if !fc.isEActive { - fc.Fee = fc.config.TransformSubnetTxFee + fc.Fee = fc.staticCfg.TransformSubnetTxFee return nil } @@ -174,7 +167,7 @@ func (fc *Calculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { func (fc *Calculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { if !fc.isEActive { - fc.Fee = fc.config.TxFee + fc.Fee = fc.staticCfg.TxFee return nil } @@ -190,9 +183,9 @@ func (fc *Calculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipT func (fc *Calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { if !fc.isEActive { 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 } @@ -213,9 +206,9 @@ func (fc *Calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessVali func (fc *Calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { if !fc.isEActive { 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 } @@ -235,7 +228,7 @@ func (fc *Calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDele func (fc *Calculator) BaseTx(tx *txs.BaseTx) error { if !fc.isEActive { - fc.Fee = fc.config.TxFee + fc.Fee = fc.staticCfg.TxFee return nil } @@ -250,7 +243,7 @@ func (fc *Calculator) BaseTx(tx *txs.BaseTx) error { func (fc *Calculator) ImportTx(tx *txs.ImportTx) error { if !fc.isEActive { - fc.Fee = fc.config.TxFee + fc.Fee = fc.staticCfg.TxFee return nil } @@ -269,7 +262,7 @@ func (fc *Calculator) ImportTx(tx *txs.ImportTx) error { func (fc *Calculator) ExportTx(tx *txs.ExportTx) error { if !fc.isEActive { - 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 c63a854175d9..6e2ce5613a92 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -19,11 +19,11 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/fees" - "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" ) @@ -41,7 +41,7 @@ var ( 2000, } - feeTestsDefaultCfg = config.Config{ + feeTestsDefaultCfg = StaticConfig{ TxFee: 1 * units.Avax, CreateAssetTxFee: 2 * units.Avax, CreateSubnetTxFee: 3 * units.Avax, @@ -61,7 +61,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) maxComplexityF func() fees.Dimensions expectedError error @@ -113,69 +113,73 @@ 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: "AddValidatorTx post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, expectedError: nil, unsignedAndSignedTx: addValidatorTx, 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: "AddSubnetValidatorTx post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, expectedError: nil, unsignedAndSignedTx: addSubnetValidatorTx, @@ -194,15 +198,16 @@ func TestTxFees(t *testing.T) { }, { description: "AddSubnetValidatorTx post EUpgrade, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, maxComplexityF: func() fees.Dimensions { caps := testBlockMaxComplexity @@ -215,88 +220,93 @@ func TestTxFees(t *testing.T) { }, { 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: "AddDelegatorTx post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - 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: "CreateChainTx post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: createChainTx, expectedError: nil, @@ -315,15 +325,16 @@ func TestTxFees(t *testing.T) { }, { description: "CreateChainTx post EUpgrade, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: createChainTx, maxComplexityF: func() fees.Dimensions { @@ -336,52 +347,55 @@ func TestTxFees(t *testing.T) { }, { 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: "CreateSubnetTx post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: createSubnetTx, expectedError: nil, @@ -400,15 +414,16 @@ func TestTxFees(t *testing.T) { }, { description: "CreateSubnetTx post EUpgrade, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, maxComplexityF: func() fees.Dimensions { caps := testBlockMaxComplexity @@ -421,33 +436,35 @@ func TestTxFees(t *testing.T) { }, { 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: "RemoveSubnetValidatorTx post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: removeSubnetValidatorTx, expectedError: nil, @@ -466,15 +483,16 @@ func TestTxFees(t *testing.T) { }, { description: "RemoveSubnetValidatorTx post EUpgrade, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, maxComplexityF: func() fees.Dimensions { caps := testBlockMaxComplexity @@ -487,33 +505,35 @@ func TestTxFees(t *testing.T) { }, { 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: "TransformSubnetTx post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: transformSubnetTx, expectedError: nil, @@ -532,15 +552,16 @@ func TestTxFees(t *testing.T) { }, { description: "TransformSubnetTx post EUpgrade, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, maxComplexityF: func() fees.Dimensions { caps := testBlockMaxComplexity @@ -553,33 +574,35 @@ func TestTxFees(t *testing.T) { }, { 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: "TransferSubnetOwnershipTx post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: transferSubnetOwnershipTx, expectedError: nil, @@ -598,15 +621,16 @@ func TestTxFees(t *testing.T) { }, { description: "TransferSubnetOwnershipTx post EUpgrade, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, maxComplexityF: func() fees.Dimensions { caps := testBlockMaxComplexity @@ -619,35 +643,37 @@ func TestTxFees(t *testing.T) { }, { 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() @@ -656,20 +682,21 @@ 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: "AddPermissionlessValidatorTx Primary Network post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - 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) @@ -690,15 +717,16 @@ func TestTxFees(t *testing.T) { }, { description: "AddPermissionlessValidatorTx Subnet post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - 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() @@ -721,15 +749,16 @@ func TestTxFees(t *testing.T) { }, { description: "AddPermissionlessValidatorTx post EUpgrade, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, maxComplexityF: func() fees.Dimensions { caps := testBlockMaxComplexity @@ -745,35 +774,37 @@ func TestTxFees(t *testing.T) { }, { 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() @@ -782,20 +813,21 @@ 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: "AddPermissionlessDelegatorTx Primary Network post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - 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) @@ -816,15 +848,16 @@ func TestTxFees(t *testing.T) { }, { description: "AddPermissionlessDelegatorTx Subnet post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - 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) @@ -845,15 +878,16 @@ func TestTxFees(t *testing.T) { }, { description: "AddPermissionlessDelegatorTx Subnet post EUpgrade, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, maxComplexityF: func() fees.Dimensions { caps := testBlockMaxComplexity @@ -870,33 +904,35 @@ func TestTxFees(t *testing.T) { }, { 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: "BaseTx post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: baseTx, expectedError: nil, @@ -915,15 +951,16 @@ func TestTxFees(t *testing.T) { }, { description: "BaseTx post EUpgrade, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, maxComplexityF: func() fees.Dimensions { caps := testBlockMaxComplexity @@ -936,33 +973,35 @@ func TestTxFees(t *testing.T) { }, { 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: "ImportTx post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: importTx, expectedError: nil, @@ -981,15 +1020,16 @@ func TestTxFees(t *testing.T) { }, { description: "ImportTx post EUpgrade, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, maxComplexityF: func() fees.Dimensions { caps := testBlockMaxComplexity @@ -1002,33 +1042,35 @@ func TestTxFees(t *testing.T) { }, { 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: "ExportTx post EUpgrade, success", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, unsignedAndSignedTx: exportTx, expectedError: nil, @@ -1047,15 +1089,16 @@ func TestTxFees(t *testing.T) { }, { description: "ExportTx post EUpgrade, utxos read cap breached", - cfgAndChainTimeF: func() (*config.Config, time.Time) { - eForkTime := time.Now().Truncate(time.Second) - chainTime := eForkTime.Add(time.Second) + cfgAndChainTimeF: func() (StaticConfig, upgrade.Times, time.Time) { + eUpgradeTime := time.Now().Truncate(time.Second) + chainTime := eUpgradeTime.Add(time.Second) cfg := feeTestsDefaultCfg - cfg.DurangoTime = durangoTime - cfg.EUpgradeTime = eForkTime - - return &cfg, chainTime + upgrade := upgrade.Times{ + DurangoTime: durangoTime, + EUpgradeTime: eUpgradeTime, + } + return cfg, upgrade, chainTime }, maxComplexityF: func() fees.Dimensions { caps := testBlockMaxComplexity @@ -1068,15 +1111,16 @@ func TestTxFees(t *testing.T) { }, { 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{ @@ -1090,15 +1134,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{ @@ -1114,7 +1159,7 @@ 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() maxComplexity := testBlockMaxComplexity if tt.maxComplexityF != nil { @@ -1124,8 +1169,8 @@ func TestTxFees(t *testing.T) { uTx, sTx := tt.unsignedAndSignedTx(t) var fc *Calculator - if !cfg.IsEActivated(chainTime) { - fc = NewStaticCalculator(cfg, chainTime) + if !upgrades.IsEActivated(chainTime) { + fc = NewStaticCalculator(cfg, upgrades, chainTime) } else { fc = NewDynamicCalculator(cfg, fees.NewManager(testFeeRates), maxComplexity, sTx.Creds) } 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 602052bbbc60..2d6a2cadafac 100644 --- a/vms/platformvm/txs/txstest/builder.go +++ b/vms/platformvm/txs/txstest/builder.go @@ -49,10 +49,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewImportTx( @@ -74,10 +71,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewExportTx( @@ -102,10 +96,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewCreateChainTx( @@ -129,10 +120,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewCreateSubnetTx( @@ -165,10 +153,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewTransformSubnetTx( @@ -203,10 +188,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewAddValidatorTx( @@ -233,10 +215,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewAddPermissionlessValidatorTx( @@ -262,10 +241,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewAddDelegatorTx( @@ -288,10 +264,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewAddPermissionlessDelegatorTx( @@ -313,10 +286,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewAddSubnetValidatorTx( @@ -337,10 +307,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewRemoveSubnetValidatorTx( @@ -362,10 +329,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewTransferSubnetOwnershipTx( @@ -386,10 +350,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) feeCalc := b.feeCalculator() utx, err := pBuilder.NewBaseTx( @@ -404,35 +365,34 @@ 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 } func (b *Builder) feeCalculator() *fee.Calculator { var ( - chainTime = b.state.GetTimestamp() - isEActive = b.cfg.IsEActivated(chainTime) + staticFeeCfg = b.cfg.StaticConfig + upgrades = b.cfg.Times + chainTime = b.state.GetTimestamp() + isEActive = upgrades.IsEActivated(chainTime) ) var feeCalculator *fee.Calculator if !isEActive { - feeCalculator = fee.NewStaticCalculator(b.cfg, chainTime) + feeCalculator = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { feeCfg := config.GetDynamicFeesConfig(isEActive) - feeCalculator = fee.NewDynamicCalculator(b.cfg, commonfees.NewManager(feeCfg.FeeRate), feeCfg.BlockMaxComplexity, nil) + feeMan := commonfees.NewManager(feeCfg.FeeRate) + feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, nil) } return feeCalculator } 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 a6c353211cc6..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,22 +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, - DurangoTime: 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 88c74c170cb7..2c79fc03bda0 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -59,6 +59,7 @@ import ( "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" @@ -246,22 +247,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() @@ -390,17 +395,18 @@ func TestGenesis(t *testing.T) { // we use the first key to fund a subnet creation in [defaultGenesis]. // As such we need to account for the subnet creation fee var ( - chainTime = vm.state.GetTimestamp() - - feeCalc *fee.Calculator + chainTime = vm.state.GetTimestamp() + staticFeeCfg = vm.Config.StaticConfig + feeCalc *fee.Calculator ) if !vm.IsEActivated(chainTime) { - feeCalc = fee.NewStaticCalculator(&vm.Config, chainTime) + upgrades := vm.Config.Times + feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { feeCfg := config.GetDynamicFeesConfig(vm.Config.IsEActivated(chainTime)) feeMan := commonfees.NewManager(feeCfg.FeeRate) - feeCalc = fee.NewDynamicCalculator(&vm.Config, feeMan, feeCfg.BlockMaxComplexity, testSubnet1.Creds) + feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, testSubnet1.Creds) } require.NoError(testSubnet1.Unsigned.Visit(feeCalc)) @@ -1197,10 +1203,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) @@ -1285,10 +1293,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) @@ -1334,10 +1344,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) @@ -1682,10 +1694,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) @@ -1843,10 +1857,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) @@ -1892,10 +1908,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) @@ -1992,10 +2010,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) @@ -2371,17 +2391,18 @@ func TestBaseTx(t *testing.T) { require.Equal(totalOutputAmt, key0OutputAmt+key1OutputAmt+changeAddrOutputAmt) var ( - chainTime = vm.state.GetTimestamp() - - feeCalc *fee.Calculator + chainTime = vm.state.GetTimestamp() + staticFeeCfg = vm.Config.StaticConfig + feeCalc *fee.Calculator ) if !vm.IsEActivated(chainTime) { - feeCalc = fee.NewStaticCalculator(&vm.Config, chainTime) + upgrades := vm.Config.Times + feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { feeCfg := config.GetDynamicFeesConfig(vm.Config.IsEActivated(chainTime)) feeMan := commonfees.NewManager(feeCfg.FeeRate) - feeCalc = fee.NewDynamicCalculator(&vm.Config, feeMan, feeCfg.BlockMaxComplexity, baseTx.Creds) + feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, baseTx.Creds) } require.NoError(baseTx.Unsigned.Visit(feeCalc)) diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index c38ab43054db..e5bc3bd95032 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -23,6 +23,7 @@ import ( "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/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/chain/p/builder" "github.com/ava-labs/avalanchego/wallet/chain/p/signer" @@ -126,14 +127,14 @@ func TestBaseTx(t *testing.T) { } { // Pre E-Upgrade - feeCalc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + feeCalc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) utx, err := builder.NewBaseTx( outputsToMove, feeCalc, ) require.NoError(err) - fc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + fc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) require.NoError(utx.Visit(fc)) require.Equal(testContext.BaseTxFee, fc.Fee) @@ -224,11 +225,11 @@ func TestAddSubnetValidatorTx(t *testing.T) { } { // Pre E-Upgrade - feeCalc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + feeCalc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) utx, err := builder.NewAddSubnetValidatorTx(subnetValidator, feeCalc) require.NoError(err) - fc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + fc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) require.NoError(utx.Visit(fc)) require.Equal(testContext.AddSubnetValidatorFee, fc.Fee) @@ -315,7 +316,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { } { // Pre E-Upgrade - feeCalc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + feeCalc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) utx, err := builder.NewRemoveSubnetValidatorTx( ids.GenerateTestNodeID(), subnetID, @@ -323,7 +324,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { ) require.NoError(err) - fc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + fc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) require.NoError(utx.Visit(fc)) require.Equal(testContext.BaseTxFee, fc.Fee) @@ -418,7 +419,7 @@ func TestCreateChainTx(t *testing.T) { } { // Pre E-Upgrade - feeCalc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + feeCalc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) utx, err := builder.NewCreateChainTx( subnetID, genesisBytes, @@ -429,7 +430,7 @@ func TestCreateChainTx(t *testing.T) { ) require.NoError(err) - fc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + fc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) require.NoError(utx.Visit(fc)) require.Equal(testContext.CreateBlockchainTxFee, fc.Fee) @@ -514,14 +515,14 @@ func TestCreateSubnetTx(t *testing.T) { } { // Pre E-Upgrade - feeCalc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + feeCalc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) utx, err := builder.NewCreateSubnetTx( subnetOwner, feeCalc, ) require.NoError(err) - fc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + fc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) require.NoError(utx.Visit(fc)) require.Equal(testContext.CreateSubnetTxFee, fc.Fee) @@ -607,7 +608,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { } { // Pre E-Upgrade - feeCalc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + feeCalc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) utx, err := builder.NewTransferSubnetOwnershipTx( subnetID, subnetOwner, @@ -615,7 +616,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { ) require.NoError(err) - fc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + fc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) require.NoError(utx.Visit(fc)) require.Equal(testContext.BaseTxFee, fc.Fee) @@ -697,7 +698,7 @@ func TestImportTx(t *testing.T) { } { // Pre E-Upgrade - feeCalc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + feeCalc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) utx, err := builder.NewImportTx( sourceChainID, importTo, @@ -705,7 +706,7 @@ func TestImportTx(t *testing.T) { ) require.NoError(err) - fc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + fc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) require.NoError(utx.Visit(fc)) require.Equal(testContext.BaseTxFee, fc.Fee) @@ -784,7 +785,7 @@ func TestExportTx(t *testing.T) { } { // Pre E-Upgrade - feeCalc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + feeCalc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) utx, err := builder.NewExportTx( subnetID, exportedOutputs, @@ -792,7 +793,7 @@ func TestExportTx(t *testing.T) { ) require.NoError(err) - fc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + fc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) require.NoError(utx.Visit(fc)) require.Equal(testContext.BaseTxFee, fc.Fee) @@ -898,7 +899,7 @@ func TestTransformSubnetTx(t *testing.T) { } { // Pre E-Upgrade - feeCalc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + feeCalc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) utx, err := builder.NewTransformSubnetTx( subnetID, subnetAssetID, @@ -918,7 +919,7 @@ func TestTransformSubnetTx(t *testing.T) { ) require.NoError(err) - fc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + fc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) require.NoError(utx.Visit(fc)) require.Equal(testContext.TransformSubnetTxFee, fc.Fee) @@ -1019,7 +1020,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { } { // Pre E-Upgrade - feeCalc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + feeCalc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1038,7 +1039,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { ) require.NoError(err) - fc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + fc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) require.NoError(utx.Visit(fc)) require.Equal(testContext.AddPrimaryNetworkValidatorFee, fc.Fee) @@ -1129,7 +1130,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { } { // Pre E-Upgrade - feeCalc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + feeCalc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) utx, err := builder.NewAddPermissionlessDelegatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1145,7 +1146,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { ) require.NoError(err) - fc := fee.NewStaticCalculator(testStaticConfig, time.Time{}) + fc := fee.NewStaticCalculator(testStaticConfig, upgrade.Times{}, time.Time{}) require.NoError(utx.Visit(fc)) require.Equal(testContext.AddPrimaryNetworkDelegatorFee, fc.Fee) diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index f6d0e12440d8..13b1d6dac51f 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -16,6 +16,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/fee" + "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "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" @@ -271,7 +272,7 @@ func NewWallet( builder: builder, signer: signer, client: client, - staticFeesConfig: &config.Config{ + staticFeesConfig: fee.StaticConfig{ TxFee: uint64(0), CreateAssetTxFee: uint64(0), CreateSubnetTxFee: uint64(0), @@ -292,7 +293,7 @@ type wallet struct { client platformvm.Client isEForkActive bool - staticFeesConfig *config.Config + staticFeesConfig fee.StaticConfig feeRates, blockMaxComplexity commonfees.Dimensions } @@ -630,7 +631,7 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( var feeCalculator *fee.Calculator if !w.isEForkActive { - feeCalculator = fee.NewStaticCalculator(w.staticFeesConfig, time.Time{}) + feeCalculator = fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Times{}, time.Time{}) } else { feeCfg := config.GetDynamicFeesConfig(w.isEForkActive) feeMan := commonfees.NewManager(w.feeRates) @@ -666,8 +667,8 @@ func (w *wallet) refreshFeesData(ctx *builder.Context, options ...common.Option) return nil } -func staticFeesConfigFromContext(ctx *builder.Context) *config.Config { - return &config.Config{ +func staticFeesConfigFromContext(ctx *builder.Context) fee.StaticConfig { + return fee.StaticConfig{ TxFee: ctx.BaseTxFee, CreateSubnetTxFee: ctx.CreateSubnetTxFee, TransformSubnetTxFee: ctx.TransformSubnetTxFee, From d90ee0f676aafa97e85bc06e02966b207647003a Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:23:26 -0400 Subject: [PATCH 083/120] nits Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- .../txs/executor/staker_tx_verification.go | 56 ++++----- .../txs/executor/standard_tx_executor.go | 48 +++----- vms/platformvm/txs/fee/calculator.go | 100 ++++++++++------- vms/platformvm/txs/fee/calculator_test.go | 106 ++++-------------- 4 files changed, 120 insertions(+), 190 deletions(-) diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 6a235a0fa011..ac78a8bf36b2 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -168,10 +168,8 @@ func verifyAddValidatorTx( staticFeesCfg = backend.Config.StaticConfig upgrades = backend.Config.Times ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return nil, err - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -180,7 +178,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) @@ -265,10 +263,8 @@ func verifyAddSubnetValidatorTx( staticFeesCfg = backend.Config.StaticConfig upgrades = backend.Config.Times ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -277,7 +273,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) @@ -349,10 +345,8 @@ func verifyRemoveSubnetValidatorTx( 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 - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -361,7 +355,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) @@ -473,10 +467,8 @@ func verifyAddDelegatorTx( staticFeesCfg = backend.Config.StaticConfig upgrades = backend.Config.Times ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return nil, err - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -485,7 +477,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) @@ -599,10 +591,8 @@ func verifyAddPermissionlessValidatorTx( staticFeesCfg = backend.Config.StaticConfig upgrades = backend.Config.Times ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -611,7 +601,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) @@ -750,10 +740,8 @@ func verifyAddPermissionlessDelegatorTx( staticFeesCfg = backend.Config.StaticConfig upgrades = backend.Config.Times ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) // Verify the flowcheck if err := backend.FlowChecker.VerifySpend( @@ -763,7 +751,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) @@ -812,10 +800,8 @@ func verifyTransferSubnetOwnershipTx( upgrades = backend.Config.Times currentTimestamp = chainState.GetTimestamp() ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) if err := backend.FlowChecker.VerifySpend( tx, @@ -824,7 +810,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 487420e1142a..48cc2e0217eb 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -73,10 +73,8 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error { 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 - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, @@ -85,7 +83,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 @@ -127,10 +125,8 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { 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 - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, @@ -139,7 +135,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 @@ -216,10 +212,8 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { 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 - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpendUTXOs( tx, @@ -228,7 +222,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 @@ -281,10 +275,8 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { 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 - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, @@ -293,7 +285,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) @@ -475,10 +467,8 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error 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 - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) totalRewardAmount := tx.MaximumSupply - tx.InitialSupply if err := e.Backend.FlowChecker.VerifySpend( @@ -491,7 +481,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 { @@ -605,10 +595,8 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { upgrades = e.Backend.Config.Times currentTimestamp = e.State.GetTimestamp() ) - feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades, currentTimestamp) - if err := tx.Visit(feeCalculator); err != nil { - return err - } + feeCalculator := fee.NewStaticCalculator(staticFeesCfg, upgrades) + fee := feeCalculator.GetFee(tx, currentTimestamp) if err := e.FlowChecker.VerifySpend( tx, @@ -617,7 +605,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 2b69dbff8478..b36065f069d5 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -11,103 +11,121 @@ 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.Times) Calculator { + return Calculator{ + config: config, + upgradeTimes: upgradeTimes, + } +} type Calculator struct { + config StaticConfig + upgradeTimes upgrade.Times +} + +func (c Calculator) GetFee(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.Times staticCfg StaticConfig - chainTime time.Time + time time.Time // outputs of visitor execution - Fee uint64 -} - -func NewStaticCalculator(cfg StaticConfig, ut upgrade.Times, 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 (*Calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { +func (*calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { return nil // no fees } -func (*Calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { +func (*calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { 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 c4424e3a2d4f..931f6210230b 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -49,13 +49,10 @@ type feeTests struct { description string cfgAndChainTimeF func() (StaticConfig, upgrade.Times, time.Time) unsignedAndSignedTx func(t *testing.T) (txs.UnsignedTx, *txs.Tx) - expectedError error - checksF func(*testing.T, *Calculator) + expected uint64 } func TestTxFees(t *testing.T) { - r := require.New(t) - tests := []feeTests{ { description: "AddValidatorTx pre EUpgrade", @@ -71,10 +68,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: addValidatorTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.AddPrimaryNetworkValidatorFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, }, { description: "AddSubnetValidatorTx pre EUpgrade", @@ -90,10 +84,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: addSubnetValidatorTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.AddSubnetValidatorFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.AddSubnetValidatorFee, }, { description: "AddDelegatorTx pre EUpgrade", @@ -109,10 +100,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: addDelegatorTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.AddPrimaryNetworkDelegatorFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, }, { description: "CreateChainTx pre ApricotPhase3", @@ -129,10 +117,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: createChainTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.CreateAssetTxFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.CreateAssetTxFee, }, { description: "CreateChainTx pre EUpgrade", @@ -148,10 +133,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: createChainTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.CreateBlockchainTxFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.CreateBlockchainTxFee, }, { description: "CreateSubnetTx pre ApricotPhase3", @@ -168,10 +150,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: createSubnetTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.CreateAssetTxFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.CreateAssetTxFee, }, { description: "CreateSubnetTx pre EUpgrade", @@ -187,10 +166,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: createSubnetTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.CreateSubnetTxFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.CreateSubnetTxFee, }, { description: "RemoveSubnetValidatorTx pre EUpgrade", @@ -206,10 +182,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: removeSubnetValidatorTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.TxFee, }, { description: "TransformSubnetTx pre EUpgrade", @@ -225,10 +198,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: transformSubnetTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TransformSubnetTxFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.TransformSubnetTxFee, }, { description: "TransferSubnetOwnershipTx pre EUpgrade", @@ -244,10 +214,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: transferSubnetOwnershipTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.TxFee, }, { description: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", @@ -265,10 +232,7 @@ func TestTxFees(t *testing.T) { 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.staticCfg.AddPrimaryNetworkValidatorFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, }, { description: "AddPermissionlessValidatorTx Subnet pre EUpgrade", @@ -288,10 +252,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, }, { description: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", @@ -309,10 +270,7 @@ func TestTxFees(t *testing.T) { 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.staticCfg.AddPrimaryNetworkDelegatorFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, }, { description: "AddPermissionlessDelegatorTx pre EUpgrade", @@ -332,10 +290,7 @@ 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, }, { description: "BaseTx pre EUpgrade", @@ -351,10 +306,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: baseTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.TxFee, }, { description: "ImportTx pre EUpgrade", @@ -370,10 +322,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: importTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.TxFee, }, { description: "ExportTx pre EUpgrade", @@ -389,10 +338,7 @@ func TestTxFees(t *testing.T) { return cfg, upgrade, chainTime }, unsignedAndSignedTx: exportTx, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.Fee) - }, + expected: feeTestsDefaultCfg.TxFee, }, { description: "RewardValidatorTx pre EUpgrade", @@ -412,10 +358,7 @@ func TestTxFees(t *testing.T) { TxID: ids.GenerateTestID(), }, nil }, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, uint64(0), fc.Fee) - }, + expected: 0, }, { description: "AdvanceTimeTx pre EUpgrade", @@ -435,10 +378,7 @@ func TestTxFees(t *testing.T) { Time: uint64(time.Now().Unix()), }, nil }, - expectedError: nil, - checksF: func(t *testing.T, fc *Calculator) { - require.Equal(t, uint64(0), fc.Fee) - }, + expected: 0, }, } @@ -447,11 +387,9 @@ func TestTxFees(t *testing.T) { cfg, upgrades, chainTime := tt.cfgAndChainTimeF() uTx, _ := tt.unsignedAndSignedTx(t) - fc := NewStaticCalculator(cfg, upgrades, chainTime) + fc := NewStaticCalculator(cfg, upgrades) - err := uTx.Visit(fc) - r.ErrorIs(err, tt.expectedError) - tt.checksF(t, fc) + require.Equal(t, tt.expected, fc.GetFee(uTx, chainTime)) }) } } From 09c615febf8f86dc8ce30487070b6d88e0de7fa5 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 26 Apr 2024 11:13:46 +0200 Subject: [PATCH 084/120] nits for wallet builder UTs --- wallet/chain/p/builder_test.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 3779db1f9fe7..f84aff75b5b4 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -313,7 +313,6 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { outs := utx.Outs require.Len(ins, 2) require.Len(outs, 1) - require.Equal(fee, ins[0].In.Amount()+ins[1].In.Amount()-outs[0].Out.Amount()) expectedConsumed := fee consumed := ins[0].In.Amount() + ins[1].In.Amount() - outs[0].Out.Amount() @@ -792,11 +791,11 @@ func TestExportTx(t *testing.T) { outs := utx.Outs require.Len(ins, 2) require.Len(outs, 1) + require.Equal(utx.ExportedOutputs, exportedOutputs) expectedConsumed := fee + exportedOutputs[0].Out.Amount() consumed := ins[0].In.Amount() + ins[1].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) - require.Equal(utx.ExportedOutputs, exportedOutputs) } { // Pre E-Upgrade @@ -1032,7 +1031,9 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { expectedConsumedSubnetAsset := utx.Validator.Weight() consumedSubnetAsset := staked[0].Out.Amount() + staked[1].Out.Amount() + require.Equal(ins[0].In.Amount()+ins[2].In.Amount()-outs[1].Out.Amount(), consumedSubnetAsset) require.Equal(expectedConsumedSubnetAsset, consumedSubnetAsset) + expectedConsumed := fee consumed := ins[1].In.Amount() + ins[3].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) @@ -1073,7 +1074,9 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { expectedConsumedSubnetAsset := utx.Validator.Weight() consumedSubnetAsset := staked[0].Out.Amount() + staked[1].Out.Amount() + require.Equal(ins[0].In.Amount()+ins[2].In.Amount()-outs[1].Out.Amount(), consumedSubnetAsset) require.Equal(expectedConsumedSubnetAsset, consumedSubnetAsset) + expectedConsumed := fee consumed := ins[1].In.Amount() + ins[3].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) @@ -1144,7 +1147,9 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { expectedConsumedSubnetAsset := utx.Validator.Weight() consumedSubnetAsset := staked[0].Out.Amount() + staked[1].Out.Amount() + require.Equal(ins[0].In.Amount()+ins[2].In.Amount()-outs[1].Out.Amount(), consumedSubnetAsset) require.Equal(expectedConsumedSubnetAsset, consumedSubnetAsset) + expectedConsumed := fee consumed := ins[1].In.Amount() + ins[3].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) @@ -1182,7 +1187,9 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { expectedConsumedSubnetAsset := utx.Validator.Weight() consumedSubnetAsset := staked[0].Out.Amount() + staked[1].Out.Amount() + require.Equal(ins[0].In.Amount()+ins[2].In.Amount()-outs[1].Out.Amount(), consumedSubnetAsset) require.Equal(expectedConsumedSubnetAsset, consumedSubnetAsset) + expectedConsumed := fee consumed := ins[1].In.Amount() + ins[3].In.Amount() - outs[0].Out.Amount() require.Equal(expectedConsumed, consumed) From 7c05c64f2b4ee3487a423dc84abe1b25fd0521b2 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 20 May 2024 09:54:03 -0400 Subject: [PATCH 085/120] 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 beef89007e8332c758474e9b483c35e4b9b068dc Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 20 May 2024 10:04:10 -0400 Subject: [PATCH 086/120] 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 e96657917933d039652dce86bc39f7039b8f047f Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 20 May 2024 14:19:59 -0400 Subject: [PATCH 087/120] nit --- vms/platformvm/txs/fee/calculator.go | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 9c2181ad9d16..a6dcca39bc26 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -26,6 +26,34 @@ var ( errFailedComplexityCumulation = errors.New("failed cumulating complexity") ) +func NewStaticCalculator(cfg StaticConfig, ut upgrade.Config, chainTime time.Time) *Calculator { + return &Calculator{ + c: &calculator{ + upgrades: ut, + staticCfg: cfg, + time: chainTime, + }, + } +} + +// NewDynamicCalculator must be used post E upgrade activation +func NewDynamicCalculator( + cfg StaticConfig, + feeManager *fees.Manager, + blockMaxComplexity fees.Dimensions, + creds []verify.Verifiable, +) *Calculator { + return &Calculator{ + c: &calculator{ + isEActive: true, + staticCfg: cfg, + feeManager: feeManager, + blockMaxComplexity: blockMaxComplexity, + credentials: creds, + }, + } +} + type Calculator struct { c *calculator } @@ -69,34 +97,6 @@ type calculator struct { fee uint64 } -func NewStaticCalculator(cfg StaticConfig, ut upgrade.Config, chainTime time.Time) *Calculator { - return &Calculator{ - c: &calculator{ - upgrades: ut, - staticCfg: cfg, - time: chainTime, - }, - } -} - -// NewDynamicCalculator must be used post E upgrade activation -func NewDynamicCalculator( - cfg StaticConfig, - feeManager *fees.Manager, - blockMaxComplexity fees.Dimensions, - creds []verify.Verifiable, -) *Calculator { - return &Calculator{ - c: &calculator{ - isEActive: true, - staticCfg: cfg, - feeManager: feeManager, - blockMaxComplexity: blockMaxComplexity, - credentials: creds, - }, - } -} - func (c *calculator) AddValidatorTx(*txs.AddValidatorTx) error { // AddValidatorTx is banned following Durango activation, so we // only return the pre EUpgrade fee here From 6d2003d4df52682d054c421ba947c7537b272022 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 20 May 2024 19:00:45 -0400 Subject: [PATCH 088/120] introduced config.PickFeeCalculator --- vms/platformvm/block/builder/builder.go | 14 +--- vms/platformvm/block/builder/helpers_test.go | 17 +--- vms/platformvm/block/executor/helpers_test.go | 17 +--- vms/platformvm/block/executor/manager.go | 17 +--- vms/platformvm/block/executor/verifier.go | 30 +------ .../block/executor/verifier_test.go | 17 +--- vms/platformvm/config/config.go | 20 +++++ vms/platformvm/service_test.go | 18 +---- .../txs/executor/create_chain_test.go | 80 ++----------------- .../txs/executor/create_subnet_test.go | 18 +---- vms/platformvm/txs/txstest/builder.go | 19 +---- vms/platformvm/vm_test.go | 33 +------- 12 files changed, 38 insertions(+), 262 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 6fd096183272..4afc4c7064ec 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -18,13 +18,11 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/config" "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" @@ -337,19 +335,9 @@ func packBlockTxs( var ( blockTxs []*txs.Tx inputs set.Set[ids.ID] - isEActive = backend.Config.UpgradeConfig.IsEActivated(timestamp) - staticFeeCfg = backend.Config.StaticFeeConfig - feeCalculator *fee.Calculator + feeCalculator = config.PickFeeCalculator(backend.Config, timestamp) ) - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, backend.Config.UpgradeConfig, timestamp) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } - 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 1be18628421a..3a452d21654c 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -34,7 +34,6 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" @@ -265,21 +264,7 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(genesisID, env.blkManager) require.NoError(err) - var ( - chainTime = stateDiff.GetTimestamp() - isEActive = env.backend.Config.UpgradeConfig.IsEActivated(chainTime) - staticFeeCfg = env.backend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, env.backend.Config.UpgradeConfig, chainTime) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } - + feeCalculator := config.PickFeeCalculator(env.backend.Config, 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 d6f8982d8eb8..5d74dd1c012a 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -37,7 +37,6 @@ 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/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" @@ -300,21 +299,7 @@ func addSubnet(env *environment) { panic(err) } - var ( - chainTime = stateDiff.GetTimestamp() - isEActive = env.backend.Config.UpgradeConfig.IsEActivated(chainTime) - staticFeeCfg = env.backend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, env.backend.Config.UpgradeConfig, chainTime) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } - + feeCalculator := config.PickFeeCalculator(env.backend.Config, 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 5fbb6fbff4d2..633d6191780e 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -9,14 +9,12 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" "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" ) @@ -145,20 +143,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - var ( - isEActive = m.txExecutorBackend.Config.UpgradeConfig.IsEActivated(nextBlkTime) - staticFeeCfg = m.txExecutorBackend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, m.txExecutorBackend.Config.UpgradeConfig, nextBlkTime) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } - + feeCalculator := config.PickFeeCalculator(m.txExecutorBackend.Config, 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 977d199aef8e..53319ebc37ce 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -69,20 +69,7 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { return err } - var ( - isEActive = v.txExecutorBackend.Config.UpgradeConfig.IsEActivated(nextChainTime) - staticFeeCfg = v.txExecutorBackend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, v.txExecutorBackend.Config.UpgradeConfig, nextChainTime) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } - + feeCalculator := config.PickFeeCalculator(v.txExecutorBackend.Config, b.Timestamp()) inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, feeCalculator, onDecisionState, b.Parent()) if err != nil { return err @@ -137,20 +124,7 @@ func (v *verifier) BanffStandardBlock(b *block.BanffStandardBlock) error { return errBanffStandardBlockWithoutChanges } - var ( - isEActive = v.txExecutorBackend.Config.UpgradeConfig.IsEActivated(b.Timestamp()) - staticFeeCfg = v.txExecutorBackend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, v.txExecutorBackend.Config.UpgradeConfig, b.Timestamp()) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } - + feeCalculator := config.PickFeeCalculator(v.txExecutorBackend.Config, b.Timestamp()) return v.standardBlock(&b.ApricotStandardBlock, feeCalculator, onAcceptState) } diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index d7e81df88c5d..fe396bef07da 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -32,7 +32,6 @@ 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/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -219,21 +218,7 @@ func TestStandardBlockComplexity(t *testing.T) { onAcceptState, err := state.NewDiffOn(env.state) require.NoError(t, err) - var ( - chainTime = onAcceptState.GetTimestamp() - isEActive = env.backend.Config.UpgradeConfig.IsEActivated(chainTime) - staticFeeCfg = env.backend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, env.backend.Config.UpgradeConfig, chainTime) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := commonfees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } - + feeCalculator := config.PickFeeCalculator(env.backend.Config, onAcceptState.GetTimestamp()) require.NoError(t, subnetValTx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: env.backend, State: onAcceptState, diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 731b079ca425..30096553057d 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -16,6 +16,8 @@ import ( "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" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) // Struct collecting all foundational parameters of PlatformVM @@ -102,3 +104,21 @@ func (c *Config) CreateChain(chainID ids.ID, tx *txs.CreateChainTx) { c.Chains.QueueChainCreation(chainParams) } + +// helper to create either a static or a dynamic fee calculator, depending on the active upgrade +func PickFeeCalculator(cfg *Config, time time.Time) *fee.Calculator { + var ( + isEActive = cfg.UpgradeConfig.IsEActivated(time) + staticFeeCfg = cfg.StaticFeeConfig + feeCalculator *fee.Calculator + ) + + if !isEActive { + feeCalculator = fee.NewStaticCalculator(staticFeeCfg, cfg.UpgradeConfig, time) + } else { + feesCfg := GetDynamicFeesConfig(isEActive) + feesMan := commonfees.NewManager(feesCfg.FeeRate) + feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) + } + return feeCalculator +} diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 30097a9afe68..0eaa898c2325 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -40,13 +40,11 @@ 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" avajson "github.com/ava-labs/avalanchego/utils/json" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" vmkeystore "github.com/ava-labs/avalanchego/vms/components/keystore" pchainapi "github.com/ava-labs/avalanchego/vms/platformvm/api" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" @@ -384,21 +382,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 - var ( - chainTime = service.vm.state.GetTimestamp() - staticFeeCfg = service.vm.Config.StaticFeeConfig - upgrades = service.vm.Config.UpgradeConfig - feeCalc *fee.Calculator - ) - - if !upgrades.IsEActivated(chainTime) { - feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) - } else { - feeCfg := config.GetDynamicFeesConfig(true) - feeMan := commonfees.NewManager(feeCfg.FeeRate) - feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity) - } - + feeCalc := config.PickFeeCalculator(&service.vm.Config, service.vm.state.GetTimestamp()) fee, err := feeCalc.ComputeFee(testSubnet1.Unsigned, testSubnet1.Creds) require.NoError(err) balance = defaultBalance - fee diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index de85478b5c03..6ce9e5165dcc 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -16,11 +16,9 @@ import ( "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/fees" "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/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -49,21 +47,7 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - var ( - chainTime = stateDiff.GetTimestamp() - isEActive = env.backend.Config.UpgradeConfig.IsEActivated(chainTime) - staticFeeCfg = env.backend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, env.backend.Config.UpgradeConfig, chainTime) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } - + feeCalculator := config.PickFeeCalculator(env.backend.Config, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -103,21 +87,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - var ( - chainTime = stateDiff.GetTimestamp() - isEActive = env.backend.Config.UpgradeConfig.IsEActivated(chainTime) - staticFeeCfg = env.backend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, env.backend.Config.UpgradeConfig, chainTime) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } - + feeCalculator := config.PickFeeCalculator(env.backend.Config, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -151,21 +121,7 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - var ( - chainTime = stateDiff.GetTimestamp() - isEActive = env.backend.Config.UpgradeConfig.IsEActivated(chainTime) - staticFeeCfg = env.backend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, env.backend.Config.UpgradeConfig, chainTime) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } - + feeCalculator := config.PickFeeCalculator(env.backend.Config, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -196,20 +152,7 @@ func TestCreateChainTxValid(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - var ( - chainTime = stateDiff.GetTimestamp() - isEActive = env.backend.Config.UpgradeConfig.IsEActivated(chainTime) - staticFeeCfg = env.backend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, env.backend.Config.UpgradeConfig, chainTime) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } + feeCalculator := config.PickFeeCalculator(env.backend.Config, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -278,20 +221,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - var ( - chainTime = stateDiff.GetTimestamp() - isEActive = env.backend.Config.UpgradeConfig.IsEActivated(chainTime) - staticFeeCfg = env.backend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, env.backend.Config.UpgradeConfig, chainTime) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } + feeCalculator := config.PickFeeCalculator(env.backend.Config, 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 abd8d6acc3cc..7d9aa6e8f277 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -12,10 +12,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/config" "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" @@ -78,21 +76,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - var ( - chainTime = stateDiff.GetTimestamp() - isEActive = env.backend.Config.UpgradeConfig.IsEActivated(chainTime) - staticFeeCfg = env.backend.Config.StaticFeeConfig - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, env.backend.Config.UpgradeConfig, chainTime) - } else { - feesCfg := config.GetDynamicFeesConfig(isEActive) - feesMan := fees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) - } - + feeCalculator := config.PickFeeCalculator(env.backend.Config, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/txstest/builder.go b/vms/platformvm/txs/txstest/builder.go index 2d0e8c108c06..0a7f8bc5ed69 100644 --- a/vms/platformvm/txs/txstest/builder.go +++ b/vms/platformvm/txs/txstest/builder.go @@ -20,7 +20,6 @@ import ( "github.com/ava-labs/avalanchego/wallet/chain/p/builder" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" vmsigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) @@ -379,20 +378,6 @@ func (b *Builder) builders(keys []*secp256k1.PrivateKey) (builder.Builder, walle } func (b *Builder) feeCalculator() *fee.Calculator { - var ( - staticFeeCfg = b.cfg.StaticFeeConfig - upgrades = b.cfg.UpgradeConfig - chainTime = b.state.GetTimestamp() - isEActive = upgrades.IsEActivated(chainTime) - ) - - var feeCalculator *fee.Calculator - if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) - } else { - feeCfg := config.GetDynamicFeesConfig(isEActive) - feeMan := commonfees.NewManager(feeCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity) - } - return feeCalculator + chainTime := b.state.GetTimestamp() + return config.PickFeeCalculator(b.cfg, chainTime) } diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index b0b23fef03e0..b0fddd1eefcf 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -67,7 +67,6 @@ import ( smeng "github.com/ava-labs/avalanchego/snow/engine/snowman" snowgetter "github.com/ava-labs/avalanchego/snow/engine/snowman/getter" timetracker "github.com/ava-labs/avalanchego/snow/networking/tracker" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" blockbuilder "github.com/ava-labs/avalanchego/vms/platformvm/block/builder" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" @@ -394,21 +393,7 @@ func TestGenesis(t *testing.T) { // we use the first key to fund a subnet creation in [defaultGenesis]. // As such we need to account for the subnet creation fee - var ( - chainTime = vm.state.GetTimestamp() - staticFeeCfg = vm.Config.StaticFeeConfig - upgrades = vm.Config.UpgradeConfig - feeCalc *fee.Calculator - ) - - if !upgrades.IsEActivated(chainTime) { - feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) - } else { - feeCfg := config.GetDynamicFeesConfig(upgrades.IsEActivated(chainTime)) - feeMan := commonfees.NewManager(feeCfg.FeeRate) - feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity) - } - + feeCalc := config.PickFeeCalculator(&vm.Config, vm.state.GetTimestamp()) fee, err := feeCalc.ComputeFee(testSubnet1.Unsigned, testSubnet1.Creds) require.NoError(err) require.Equal(uint64(utxo.Amount)-fee, out.Amount()) @@ -2390,21 +2375,7 @@ func TestBaseTx(t *testing.T) { } require.Equal(totalOutputAmt, key0OutputAmt+key1OutputAmt+changeAddrOutputAmt) - var ( - chainTime = vm.state.GetTimestamp() - staticFeeCfg = vm.Config.StaticFeeConfig - upgrades = vm.Config.UpgradeConfig - feeCalc *fee.Calculator - ) - - if !upgrades.IsEActivated(chainTime) { - feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) - } else { - feeCfg := config.GetDynamicFeesConfig(upgrades.IsEActivated(chainTime)) - feeMan := commonfees.NewManager(feeCfg.FeeRate) - feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity) - } - + feeCalc := config.PickFeeCalculator(&vm.Config, vm.state.GetTimestamp()) fee, err := feeCalc.ComputeFee(baseTx.Unsigned, baseTx.Creds) require.NoError(err) require.Equal(fee, totalInputAmt-totalOutputAmt) From 6e03a1692c02ff341a5af341b2216fb474a94c8a Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 20 May 2024 19:15:32 -0400 Subject: [PATCH 089/120] reusing PickFeeCalculator --- .../txs/executor/advance_time_test.go | 22 +++--- vms/platformvm/txs/executor/export_test.go | 4 +- vms/platformvm/txs/executor/helpers_test.go | 2 +- vms/platformvm/txs/executor/import_test.go | 4 +- .../txs/executor/proposal_tx_executor_test.go | 34 ++++----- .../txs/executor/reward_validator_test.go | 14 ++-- .../executor/staker_tx_verification_test.go | 3 +- .../txs/executor/standard_tx_executor_test.go | 69 +++++++++---------- 8 files changed, 75 insertions(+), 77 deletions(-) diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index a4fecaa4c94c..d2d3cc817a2f 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -15,11 +15,11 @@ 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/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "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" ) @@ -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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index 829ad71b9b7a..c81b318339f1 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -12,8 +12,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -73,7 +73,7 @@ func TestNewExportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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..b062bd5e1a79 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, env.state.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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..e38324be8782 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -15,9 +15,9 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/components/avax" + "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/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) @@ -156,7 +156,7 @@ func TestNewImportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, stateDiff.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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 51f4c7ea1ee8..c375048ebac5 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -14,11 +14,11 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/hashing" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "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" ) @@ -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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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 0c22fac99838..6cc17a9d6a02 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -17,11 +17,11 @@ import ( "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/set" "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/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" ) @@ -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, onAbortState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onAbortState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, delOnCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, 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, onCommitState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) 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 eba3e4ba54df..417f3bc79302 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" ) @@ -512,7 +511,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, state.GetTimestamp()) + feeCalculator = config.PickFeeCalculator(backend.Config, state.GetTimestamp()) ) err := verifyAddPermissionlessValidatorTx(backend, feeCalculator, state, sTx, tx) diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index a5e269b65d0e..3d03ef4104ad 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -32,7 +32,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" @@ -94,7 +93,7 @@ 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 := config.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: stateDiff, @@ -346,7 +345,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { env.config.UpgradeConfig.BanffTime = onAcceptState.GetTimestamp() - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -389,7 +388,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -422,7 +421,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -473,7 +472,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -521,7 +520,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -552,7 +551,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -583,7 +582,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -616,7 +615,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -680,7 +679,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -722,7 +721,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -760,7 +759,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -796,7 +795,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -842,7 +841,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -883,7 +882,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -928,7 +927,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -970,7 +969,7 @@ 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 := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1011,7 +1010,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.DeleteUTXO(utxoID) } - feeCalculator := fee.NewStaticCalculator(env.backend.Config.StaticFeeConfig, env.backend.Config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -1111,7 +1110,7 @@ func TestDurangoDisabledTransactions(t *testing.T) { tx := tt.buildTx(env) - feeCalculator := fee.NewStaticCalculator(env.config.StaticFeeConfig, env.config.UpgradeConfig, onAcceptState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) err = tx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1309,7 +1308,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, onAcceptState.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) require.NoError(t, subnetValTx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1498,7 +1497,7 @@ 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 := config.PickFeeCalculator(env.config, env.state.GetTimestamp()) // Populated memo field should error tx, onAcceptState := tt.setupTest(env, []byte{'m', 'e', 'm', 'o'}) @@ -1646,7 +1645,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, env.state.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1673,7 +1672,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.latestForkTime) + feeCalculator := config.PickFeeCalculator(cfg, env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1701,7 +1700,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { 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 := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1732,7 +1731,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { 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 := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1761,7 +1760,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { 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 := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1789,7 +1788,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { 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 := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1819,7 +1818,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) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1852,7 +1851,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { ).Return(errTest) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2009,7 +2008,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.latestForkTime) + feeCalculator := config.PickFeeCalculator(cfg, env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2036,7 +2035,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, env.state.GetTimestamp()) + feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2066,7 +2065,7 @@ 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 := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2101,7 +2100,7 @@ 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 := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2141,7 +2140,7 @@ 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 := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, From fe206db9f14474d0ab9433c2c1bf46f09af27edb Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 21 May 2024 09:44:30 -0400 Subject: [PATCH 090/120] reset fees when ComputeFees is called --- vms/platformvm/txs/fee/calculator.go | 7 ++-- wallet/chain/p/builder/builder.go | 50 ++++++++++++++-------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 7f35ebd57eb8..74b9c448f472 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -67,6 +67,7 @@ func (c *Calculator) ResetFee(newFee uint64) { func (c *Calculator) ComputeFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) { c.c.credentials = creds + c.c.fee = 0 // zero fee among different ComputeFee invocations (unlike Complexity which gets cumulated) err := tx.Visit(c.c) return c.c.fee, err } @@ -89,11 +90,11 @@ func (c *Calculator) GetCumulatedComplexity() fees.Dimensions { type calculator struct { // setup isEActive bool + staticCfg StaticConfig // Pre E-upgrade inputs - upgrades upgrade.Config - staticCfg StaticConfig - time time.Time + upgrades upgrade.Config + time time.Time // Post E-upgrade inputs feeManager *fees.Manager diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index 600b5d1c2eeb..4f712cc119c1 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -438,16 +438,16 @@ func (b *builder) NewAddSubnetValidatorTx( toStake := map[ids.ID]uint64{} toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - // update fees to account for the auth credentials to be added upon tx signing - if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { - return nil, fmt.Errorf("account for credential fees: %w", err) - } - // feesMan cumulates complexity. Let's init it with utx filled so far if _, err := feeCalc.ComputeFee(utx, nil); err != nil { return nil, err } + // update fees to account for the auth credentials to be added upon tx signing + if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) if err != nil { return nil, err @@ -486,16 +486,16 @@ func (b *builder) NewRemoveSubnetValidatorTx( toStake := map[ids.ID]uint64{} toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - // update fees to account for the auth credentials to be added upon tx signing - if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { - return nil, fmt.Errorf("account for credential fees: %w", err) - } - // feesMan cumulates complexity. Let's init it with utx filled so far if _, err := feeCalc.ComputeFee(utx, nil); err != nil { return nil, err } + // update fees to account for the auth credentials to be added upon tx signing + if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) if err != nil { return nil, err @@ -585,16 +585,16 @@ func (b *builder) NewCreateChainTx( toStake := map[ids.ID]uint64{} toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - // update fees to account for the auth credentials to be added upon tx signing - if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { - return nil, fmt.Errorf("account for credential fees: %w", err) - } - // feesMan cumulates complexity. Let's init it with utx filled so far if _, err := feeCalc.ComputeFee(utx, nil); err != nil { return nil, err } + // update fees to account for the auth credentials to be added upon tx signing + if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) if err != nil { return nil, err @@ -673,16 +673,16 @@ func (b *builder) NewTransferSubnetOwnershipTx( toStake := map[ids.ID]uint64{} toBurn := map[ids.ID]uint64{} // fees are calculated in financeTx - // update fees to account for the auth credentials to be added upon tx signing - if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { - return nil, fmt.Errorf("account for credential fees: %w", err) - } - // feesMan cumulates complexity. Let's init it with utx filled so far if _, err := feeCalc.ComputeFee(utx, nil); err != nil { return nil, err } + // update fees to account for the auth credentials to be added upon tx signing + if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) if err != nil { return nil, err @@ -961,16 +961,16 @@ func (b *builder) NewTransformSubnetTx( assetID: maxSupply - initialSupply, } // fees are calculated in financeTx - // update fees to account for the auth credentials to be added upon tx signing - if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { - return nil, fmt.Errorf("account for credential fees: %w", err) - } - // feesMan cumulates complexity. Let's init it with utx filled so far if _, err := feeCalc.ComputeFee(utx, nil); err != nil { return nil, err } + // update fees to account for the auth credentials to be added upon tx signing + if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + return nil, fmt.Errorf("account for credential fees: %w", err) + } + inputs, outputs, _, err := b.financeTx(toBurn, toStake, feeCalc, ops) if err != nil { return nil, err From 5f224f9f34761015844afbd2cf8e9d2032ea5d82 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 21 May 2024 10:20:10 -0400 Subject: [PATCH 091/120] moved dynamic fee config to fee package --- tests/e2e/p/workflow.go | 3 +-- vms/platformvm/config/config.go | 2 +- .../dynamic_fees_config.go => txs/fee/dynamic_config.go} | 2 +- vms/platformvm/vm.go | 3 ++- wallet/chain/p/wallet.go | 5 ++--- 5 files changed, 7 insertions(+), 8 deletions(-) rename vms/platformvm/{config/dynamic_fees_config.go => txs/fee/dynamic_config.go} (99%) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 966b6732dec3..41512d3d35fd 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -18,7 +18,6 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" @@ -167,7 +166,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { require.NoError(err) // retrieve fees paid for the tx - feeCfg := config.GetDynamicFeesConfig(true /*isEActive*/) + feeCfg := fee.GetDynamicFeesConfig(true /*isEActive*/) feeCalc := fee.NewDynamicCalculator(pChainStaticFees, commonfees.NewManager(feeCfg.FeeRate), feeCfg.BlockMaxComplexity) pChainExportFee, err = feeCalc.ComputeFee(tx.Unsigned, tx.Creds) require.NoError(err) diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 30096553057d..05c0f0006be4 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -116,7 +116,7 @@ func PickFeeCalculator(cfg *Config, time time.Time) *fee.Calculator { if !isEActive { feeCalculator = fee.NewStaticCalculator(staticFeeCfg, cfg.UpgradeConfig, time) } else { - feesCfg := GetDynamicFeesConfig(isEActive) + feesCfg := fee.GetDynamicFeesConfig(isEActive) feesMan := commonfees.NewManager(feesCfg.FeeRate) feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) } diff --git a/vms/platformvm/config/dynamic_fees_config.go b/vms/platformvm/txs/fee/dynamic_config.go similarity index 99% rename from vms/platformvm/config/dynamic_fees_config.go rename to vms/platformvm/txs/fee/dynamic_config.go index a9cf48e99242..7fd371189e82 100644 --- a/vms/platformvm/config/dynamic_fees_config.go +++ b/vms/platformvm/txs/fee/dynamic_config.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package config +package fee import ( "fmt" diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index f9279dc2359a..101c70938331 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -40,6 +40,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" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/vms/txs/mempool" @@ -113,7 +114,7 @@ func (vm *VM) Initialize( } chainCtx.Log.Info("retrieved VM execution config", zap.Reflect("config", execConfig)) - if err := config.ResetDynamicFeesConfig(chainCtx, execConfig.DynamicFeesConfig); err != nil { + if err := fee.ResetDynamicFeesConfig(chainCtx, execConfig.DynamicFeesConfig); err != nil { return fmt.Errorf("failed resetting dynamic fees config: %w", err) } diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 097282488328..c5f8816ae88c 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -12,7 +12,6 @@ import ( "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "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" @@ -633,7 +632,7 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( if !w.isEForkActive { feeCalculator = fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Config{}, time.Time{}) } else { - feeCfg := config.GetDynamicFeesConfig(w.isEForkActive) + feeCfg := fee.GetDynamicFeesConfig(w.isEForkActive) feeMan := commonfees.NewManager(w.feeRates) feeCalculator = fee.NewDynamicCalculator(w.staticFeesConfig, feeMan, feeCfg.BlockMaxComplexity) } @@ -661,7 +660,7 @@ func (w *wallet) refreshFeesData(ctx *builder.Context, options ...common.Option) w.staticFeesConfig = staticFeesConfigFromContext(ctx) w.isEForkActive = !chainTime.Before(eForkTime) - feeCfg := config.GetDynamicFeesConfig(w.isEForkActive) + feeCfg := fee.GetDynamicFeesConfig(w.isEForkActive) w.feeRates = feeCfg.FeeRate w.blockMaxComplexity = feeCfg.BlockMaxComplexity return nil From 1a317a3d20a899e16522b9e41722b06a429eddc9 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 21 May 2024 10:20:10 -0400 Subject: [PATCH 092/120] moved dynamic fee config to fee package --- tests/e2e/p/workflow.go | 3 +- vms/platformvm/block/builder/builder.go | 4 +- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/block/executor/manager.go | 4 +- vms/platformvm/block/executor/verifier.go | 4 +- vms/platformvm/service_test.go | 3 +- .../txs/executor/atomic_tx_executor.go | 4 +- .../txs/executor/create_chain_test.go | 12 ++-- .../txs/executor/create_subnet_test.go | 4 +- vms/platformvm/txs/executor/helpers_test.go | 2 +- .../txs/executor/standard_tx_executor_test.go | 63 ++++++++++--------- .../fee/dynamic_config.go} | 2 +- vms/platformvm/txs/txstest/builder.go | 2 +- vms/platformvm/vm.go | 3 +- vms/platformvm/vm_test.go | 4 +- wallet/chain/p/wallet.go | 5 +- 17 files changed, 61 insertions(+), 62 deletions(-) rename vms/platformvm/{config/dynamic_fees_config.go => txs/fee/dynamic_config.go} (99%) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index f86d6e29d607..df62cf751744 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -18,7 +18,6 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" @@ -167,7 +166,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { require.NoError(err) // retrieve fees paid for the tx - feeCfg := config.GetDynamicFeesConfig(true /*isEActive*/) + feeCfg := fee.GetDynamicFeesConfig(true /*isEActive*/) feeCalc := fee.NewDynamicCalculator(pChainStaticFees, commonfees.NewManager(feeCfg.FeeRate), feeCfg.BlockMaxComplexity, tx.Creds) pChainExportFee, err = feeCalc.ComputeFee(tx.Unsigned) require.NoError(err) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index bf132f0d4592..dadda534d9f1 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -20,10 +20,10 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "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" @@ -335,7 +335,7 @@ func packBlockTxs( var ( isEActivated = backend.Config.UpgradeConfig.IsEActivated(timestamp) - feeCfg = config.GetDynamicFeesConfig(isEActivated) + feeCfg = fee.GetDynamicFeesConfig(isEActivated) feeMan = fees.NewManager(feeCfg.FeeRate) blockTxs []*txs.Tx diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 30727b1ff5a4..dd2dc34b7eba 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -266,7 +266,7 @@ func addSubnet(t *testing.T, env *environment) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := txexecutor.StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index b831306df92c..4f4aab9c20a3 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -301,7 +301,7 @@ func addSubnet(env *environment) { } chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := executor.StandardTxExecutor{ Backend: env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index 07a69d91a5ee..a336c9bb3f79 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -11,11 +11,11 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" "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" ) @@ -145,7 +145,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { } isEActive := m.txExecutorBackend.Config.UpgradeConfig.IsEActivated(stateDiff.GetTimestamp()) - feesCfg := config.GetDynamicFeesConfig(isEActive) + feesCfg := fee.GetDynamicFeesConfig(isEActive) return tx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: m.txExecutorBackend, BlkFeeManager: fees.NewManager(feesCfg.FeeRate), diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index ab689edcdc5f..81bfbd4baf97 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -12,11 +12,11 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "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/executor" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) var ( @@ -448,7 +448,7 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID ) { var ( isEActive = v.txExecutorBackend.Config.UpgradeConfig.IsEActivated(state.GetTimestamp()) - feesCfg = config.GetDynamicFeesConfig(isEActive) + feesCfg = fee.GetDynamicFeesConfig(isEActive) feesMan = fees.NewManager(feesCfg.FeeRate) onAcceptFunc func() diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index f9bfa580f79a..09abfcaa389a 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -35,7 +35,6 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/block/builder" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" @@ -394,7 +393,7 @@ func TestGetBalance(t *testing.T) { if !upgrades.IsEActivated(chainTime) { feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { - feeCfg := config.GetDynamicFeesConfig(true) + feeCfg := fee.GetDynamicFeesConfig(true) feeMan := commonfees.NewManager(feeCfg.FeeRate) feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, testSubnet1.Creds) } diff --git a/vms/platformvm/txs/executor/atomic_tx_executor.go b/vms/platformvm/txs/executor/atomic_tx_executor.go index c301d4fe7453..96174c9cda21 100644 --- a/vms/platformvm/txs/executor/atomic_tx_executor.go +++ b/vms/platformvm/txs/executor/atomic_tx_executor.go @@ -7,9 +7,9 @@ import ( "github.com/ava-labs/avalanchego/chains/atomic" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" - "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" commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) @@ -101,7 +101,7 @@ func (e *AtomicTxExecutor) atomicTx(tx txs.UnsignedTx) error { } e.OnAccept = onAccept - feesCfg := config.GetDynamicFeesConfig(false /*isEActive*/) + feesCfg := fee.GetDynamicFeesConfig(false /*isEActive*/) executor := StandardTxExecutor{ Backend: e.Backend, BlkFeeManager: commonfees.NewManager(feesCfg.FeeRate), diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index fba0de43631c..c315b28fcc5c 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -16,9 +16,9 @@ import ( "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" - "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/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -50,7 +50,7 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), @@ -92,7 +92,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { require.NoError(err) chainTime := stateDiff.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), @@ -128,7 +128,7 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { require.NoError(err) currentTime := stateDiff.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), @@ -161,7 +161,7 @@ func TestCreateChainTxValid(t *testing.T) { require.NoError(err) currentTime := stateDiff.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), @@ -232,7 +232,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) currentTime := stateDiff.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 2c69f9f5eae7..8661a6dcc76e 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -12,8 +12,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "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" @@ -79,7 +79,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) chainTime := stateDiff.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 58009092da31..14ca3897220f 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -235,7 +235,7 @@ func addSubnet(t *testing.T, env *environment) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 65d604a0d028..a0681fc6fe8a 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -33,6 +33,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" @@ -95,7 +96,7 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -349,7 +350,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { env.config.UpgradeConfig.BanffTime = onAcceptState.GetTimestamp() chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -394,7 +395,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -429,7 +430,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -482,7 +483,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -532,7 +533,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -565,7 +566,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -598,7 +599,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -633,7 +634,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -699,7 +700,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -743,7 +744,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -783,7 +784,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -821,7 +822,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -869,7 +870,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -912,7 +913,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -959,7 +960,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.AddTx(tx, status.Committed) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -1003,7 +1004,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.AddTx(tx, status.Committed) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -1046,7 +1047,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { } chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -1675,7 +1676,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1702,7 +1703,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.tx.Unsigned.(*txs.RemoveSubnetValidatorTx).Subnet = constants.PrimaryNetworkID env.state = state.NewMockDiff(ctrl) - feeCfg := config.GetDynamicFeesConfig(false /*isEActive*/) + feeCfg := fee.GetDynamicFeesConfig(false /*isEActive*/) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1732,7 +1733,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1765,7 +1766,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1796,7 +1797,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1826,7 +1827,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1858,7 +1859,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1893,7 +1894,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -2050,7 +2051,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.tx.Unsigned = (*txs.TransformSubnetTx)(nil) env.state = state.NewMockDiff(ctrl) - feeCfg := config.GetDynamicFeesConfig(false /*isEActive*/) + feeCfg := fee.GetDynamicFeesConfig(false /*isEActive*/) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -2079,7 +2080,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -2110,7 +2111,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg.MaxStakeDuration = math.MaxInt64 env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2146,7 +2147,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2187,7 +2188,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 chainTime := env.state.GetTimestamp() - feeCfg := config.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, diff --git a/vms/platformvm/config/dynamic_fees_config.go b/vms/platformvm/txs/fee/dynamic_config.go similarity index 99% rename from vms/platformvm/config/dynamic_fees_config.go rename to vms/platformvm/txs/fee/dynamic_config.go index a9cf48e99242..7fd371189e82 100644 --- a/vms/platformvm/config/dynamic_fees_config.go +++ b/vms/platformvm/txs/fee/dynamic_config.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package config +package fee import ( "fmt" diff --git a/vms/platformvm/txs/txstest/builder.go b/vms/platformvm/txs/txstest/builder.go index 774cecf0a367..45c663ab4dfe 100644 --- a/vms/platformvm/txs/txstest/builder.go +++ b/vms/platformvm/txs/txstest/builder.go @@ -390,7 +390,7 @@ func (b *Builder) feeCalculator() *fee.Calculator { if !isEActive { feeCalculator = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { - feeCfg := config.GetDynamicFeesConfig(isEActive) + feeCfg := fee.GetDynamicFeesConfig(isEActive) feeMan := commonfees.NewManager(feeCfg.FeeRate) feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, nil) } diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index f9279dc2359a..101c70938331 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -40,6 +40,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" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/vms/txs/mempool" @@ -113,7 +114,7 @@ func (vm *VM) Initialize( } chainCtx.Log.Info("retrieved VM execution config", zap.Reflect("config", execConfig)) - if err := config.ResetDynamicFeesConfig(chainCtx, execConfig.DynamicFeesConfig); err != nil { + if err := fee.ResetDynamicFeesConfig(chainCtx, execConfig.DynamicFeesConfig); err != nil { return fmt.Errorf("failed resetting dynamic fees config: %w", err) } diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 0363da1677b9..ab8288b53728 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -404,7 +404,7 @@ func TestGenesis(t *testing.T) { if !upgrades.IsEActivated(chainTime) { feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { - feeCfg := config.GetDynamicFeesConfig(upgrades.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(upgrades.IsEActivated(chainTime)) feeMan := commonfees.NewManager(feeCfg.FeeRate) feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, testSubnet1.Creds) } @@ -2400,7 +2400,7 @@ func TestBaseTx(t *testing.T) { if !upgrades.IsEActivated(chainTime) { feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { - feeCfg := config.GetDynamicFeesConfig(upgrades.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicFeesConfig(upgrades.IsEActivated(chainTime)) feeMan := commonfees.NewManager(feeCfg.FeeRate) feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, baseTx.Creds) } diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index c10e1da1ea49..30cf19214a19 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -12,7 +12,6 @@ import ( "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "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" @@ -633,7 +632,7 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( if !w.isEForkActive { feeCalculator = fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Config{}, time.Time{}) } else { - feeCfg := config.GetDynamicFeesConfig(w.isEForkActive) + feeCfg := fee.GetDynamicFeesConfig(w.isEForkActive) feeMan := commonfees.NewManager(w.feeRates) feeCalculator = fee.NewDynamicCalculator(w.staticFeesConfig, feeMan, feeCfg.BlockMaxComplexity, nil) } @@ -661,7 +660,7 @@ func (w *wallet) refreshFeesData(ctx *builder.Context, options ...common.Option) w.staticFeesConfig = staticFeesConfigFromContext(ctx) w.isEForkActive = !chainTime.Before(eForkTime) - feeCfg := config.GetDynamicFeesConfig(w.isEForkActive) + feeCfg := fee.GetDynamicFeesConfig(w.isEForkActive) w.feeRates = feeCfg.FeeRate w.blockMaxComplexity = feeCfg.BlockMaxComplexity return nil From 04e18ba6e68df80c15a64bf939135f507bb24eaa Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 21 May 2024 10:49:25 -0400 Subject: [PATCH 093/120] minor renaming --- tests/e2e/p/workflow.go | 2 +- 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 | 2 +- vms/platformvm/service_test.go | 2 +- .../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/helpers_test.go | 2 +- .../txs/executor/standard_tx_executor_test.go | 62 +++++++++---------- vms/platformvm/txs/fee/dynamic_config.go | 4 +- vms/platformvm/txs/txstest/builder.go | 2 +- vms/platformvm/vm.go | 2 +- vms/platformvm/vm_test.go | 4 +- wallet/chain/p/wallet.go | 4 +- 17 files changed, 54 insertions(+), 54 deletions(-) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index df62cf751744..22919ba427d2 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -166,7 +166,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { require.NoError(err) // retrieve fees paid for the tx - feeCfg := fee.GetDynamicFeesConfig(true /*isEActive*/) + feeCfg := fee.GetDynamicConfig(true /*isEActive*/) feeCalc := fee.NewDynamicCalculator(pChainStaticFees, commonfees.NewManager(feeCfg.FeeRate), feeCfg.BlockMaxComplexity, tx.Creds) pChainExportFee, err = feeCalc.ComputeFee(tx.Unsigned) require.NoError(err) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index dadda534d9f1..98f15a186df6 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -335,7 +335,7 @@ func packBlockTxs( var ( isEActivated = backend.Config.UpgradeConfig.IsEActivated(timestamp) - feeCfg = fee.GetDynamicFeesConfig(isEActivated) + feeCfg = fee.GetDynamicConfig(isEActivated) feeMan = fees.NewManager(feeCfg.FeeRate) blockTxs []*txs.Tx diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index dd2dc34b7eba..b9947099bce6 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -266,7 +266,7 @@ func addSubnet(t *testing.T, env *environment) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := txexecutor.StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 4f4aab9c20a3..8ff50a4a73f0 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -301,7 +301,7 @@ func addSubnet(env *environment) { } chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := executor.StandardTxExecutor{ Backend: env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index a336c9bb3f79..f291d6b72ca0 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -145,7 +145,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { } isEActive := m.txExecutorBackend.Config.UpgradeConfig.IsEActivated(stateDiff.GetTimestamp()) - feesCfg := fee.GetDynamicFeesConfig(isEActive) + feesCfg := fee.GetDynamicConfig(isEActive) return tx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: m.txExecutorBackend, BlkFeeManager: fees.NewManager(feesCfg.FeeRate), diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 81bfbd4baf97..cd8edafe15c0 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -448,7 +448,7 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID ) { var ( isEActive = v.txExecutorBackend.Config.UpgradeConfig.IsEActivated(state.GetTimestamp()) - feesCfg = fee.GetDynamicFeesConfig(isEActive) + feesCfg = fee.GetDynamicConfig(isEActive) feesMan = fees.NewManager(feesCfg.FeeRate) onAcceptFunc func() diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 09abfcaa389a..776a0706a152 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -393,7 +393,7 @@ func TestGetBalance(t *testing.T) { if !upgrades.IsEActivated(chainTime) { feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { - feeCfg := fee.GetDynamicFeesConfig(true) + feeCfg := fee.GetDynamicConfig(true) feeMan := commonfees.NewManager(feeCfg.FeeRate) feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, testSubnet1.Creds) } diff --git a/vms/platformvm/txs/executor/atomic_tx_executor.go b/vms/platformvm/txs/executor/atomic_tx_executor.go index 96174c9cda21..6279f4cd6446 100644 --- a/vms/platformvm/txs/executor/atomic_tx_executor.go +++ b/vms/platformvm/txs/executor/atomic_tx_executor.go @@ -101,7 +101,7 @@ func (e *AtomicTxExecutor) atomicTx(tx txs.UnsignedTx) error { } e.OnAccept = onAccept - feesCfg := fee.GetDynamicFeesConfig(false /*isEActive*/) + feesCfg := fee.GetDynamicConfig(false /*isEActive*/) executor := StandardTxExecutor{ Backend: e.Backend, BlkFeeManager: commonfees.NewManager(feesCfg.FeeRate), diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index c315b28fcc5c..8de3f781275a 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -50,7 +50,7 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), @@ -92,7 +92,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { require.NoError(err) chainTime := stateDiff.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), @@ -128,7 +128,7 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { require.NoError(err) currentTime := stateDiff.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), @@ -161,7 +161,7 @@ func TestCreateChainTxValid(t *testing.T) { require.NoError(err) currentTime := stateDiff.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), @@ -232,7 +232,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) currentTime := stateDiff.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(currentTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 8661a6dcc76e..82047c7ca3df 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -79,7 +79,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) chainTime := stateDiff.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 14ca3897220f..bb045d1a35ec 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -235,7 +235,7 @@ func addSubnet(t *testing.T, env *environment) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: commonfees.NewManager(feeCfg.FeeRate), diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index a0681fc6fe8a..464b87be5de5 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -96,7 +96,7 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -350,7 +350,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { env.config.UpgradeConfig.BanffTime = onAcceptState.GetTimestamp() chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -395,7 +395,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -430,7 +430,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -483,7 +483,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -533,7 +533,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -566,7 +566,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -599,7 +599,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -634,7 +634,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -700,7 +700,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -744,7 +744,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -784,7 +784,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -822,7 +822,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -870,7 +870,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -913,7 +913,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { require.NoError(err) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -960,7 +960,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.AddTx(tx, status.Committed) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -1004,7 +1004,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.AddTx(tx, status.Committed) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -1047,7 +1047,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { } chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(env.config.UpgradeConfig.IsEActivated(chainTime)) executor := StandardTxExecutor{ Backend: &env.backend, BlkFeeManager: fees.NewManager(feeCfg.FeeRate), @@ -1676,7 +1676,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1703,7 +1703,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.tx.Unsigned.(*txs.RemoveSubnetValidatorTx).Subnet = constants.PrimaryNetworkID env.state = state.NewMockDiff(ctrl) - feeCfg := fee.GetDynamicFeesConfig(false /*isEActive*/) + feeCfg := fee.GetDynamicConfig(false /*isEActive*/) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1733,7 +1733,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1766,7 +1766,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1797,7 +1797,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1827,7 +1827,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1859,7 +1859,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -1894,7 +1894,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -2051,7 +2051,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.tx.Unsigned = (*txs.TransformSubnetTx)(nil) env.state = state.NewMockDiff(ctrl) - feeCfg := fee.GetDynamicFeesConfig(false /*isEActive*/) + feeCfg := fee.GetDynamicConfig(false /*isEActive*/) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -2080,7 +2080,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: defaultTestConfig(t, durango, env.latestForkTime), @@ -2111,7 +2111,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg.MaxStakeDuration = math.MaxInt64 env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes() chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2147,7 +2147,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2188,7 +2188,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 chainTime := env.state.GetTimestamp() - feeCfg := fee.GetDynamicFeesConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(cfg.UpgradeConfig.IsEActivated(chainTime)) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, diff --git a/vms/platformvm/txs/fee/dynamic_config.go b/vms/platformvm/txs/fee/dynamic_config.go index 7fd371189e82..6280ed0a8582 100644 --- a/vms/platformvm/txs/fee/dynamic_config.go +++ b/vms/platformvm/txs/fee/dynamic_config.go @@ -34,7 +34,7 @@ var ( customDynamicFeesConfig *commonfees.DynamicFeesConfig ) -func GetDynamicFeesConfig(isEActive bool) commonfees.DynamicFeesConfig { +func GetDynamicConfig(isEActive bool) commonfees.DynamicFeesConfig { if !isEActive { return preEUpgradeDynamicFeesConfig } @@ -45,7 +45,7 @@ func GetDynamicFeesConfig(isEActive bool) commonfees.DynamicFeesConfig { return eUpgradeDynamicFeesConfig } -func ResetDynamicFeesConfig(ctx *snow.Context, customFeesConfig *commonfees.DynamicFeesConfig) error { +func ResetDynamicConfig(ctx *snow.Context, customFeesConfig *commonfees.DynamicFeesConfig) error { if customFeesConfig == nil { return nil // nothing to do } diff --git a/vms/platformvm/txs/txstest/builder.go b/vms/platformvm/txs/txstest/builder.go index 45c663ab4dfe..ae669a0f2609 100644 --- a/vms/platformvm/txs/txstest/builder.go +++ b/vms/platformvm/txs/txstest/builder.go @@ -390,7 +390,7 @@ func (b *Builder) feeCalculator() *fee.Calculator { if !isEActive { feeCalculator = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { - feeCfg := fee.GetDynamicFeesConfig(isEActive) + feeCfg := fee.GetDynamicConfig(isEActive) feeMan := commonfees.NewManager(feeCfg.FeeRate) feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, nil) } diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 101c70938331..96f41d144e81 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -114,7 +114,7 @@ func (vm *VM) Initialize( } chainCtx.Log.Info("retrieved VM execution config", zap.Reflect("config", execConfig)) - if err := fee.ResetDynamicFeesConfig(chainCtx, execConfig.DynamicFeesConfig); err != nil { + if err := fee.ResetDynamicConfig(chainCtx, execConfig.DynamicFeesConfig); err != nil { return fmt.Errorf("failed resetting dynamic fees config: %w", err) } diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index ab8288b53728..fa666d142916 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -404,7 +404,7 @@ func TestGenesis(t *testing.T) { if !upgrades.IsEActivated(chainTime) { feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { - feeCfg := fee.GetDynamicFeesConfig(upgrades.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(upgrades.IsEActivated(chainTime)) feeMan := commonfees.NewManager(feeCfg.FeeRate) feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, testSubnet1.Creds) } @@ -2400,7 +2400,7 @@ func TestBaseTx(t *testing.T) { if !upgrades.IsEActivated(chainTime) { feeCalc = fee.NewStaticCalculator(staticFeeCfg, upgrades, chainTime) } else { - feeCfg := fee.GetDynamicFeesConfig(upgrades.IsEActivated(chainTime)) + feeCfg := fee.GetDynamicConfig(upgrades.IsEActivated(chainTime)) feeMan := commonfees.NewManager(feeCfg.FeeRate) feeCalc = fee.NewDynamicCalculator(staticFeeCfg, feeMan, feeCfg.BlockMaxComplexity, baseTx.Creds) } diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 30cf19214a19..4bba4e1d545c 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -632,7 +632,7 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( if !w.isEForkActive { feeCalculator = fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Config{}, time.Time{}) } else { - feeCfg := fee.GetDynamicFeesConfig(w.isEForkActive) + feeCfg := fee.GetDynamicConfig(w.isEForkActive) feeMan := commonfees.NewManager(w.feeRates) feeCalculator = fee.NewDynamicCalculator(w.staticFeesConfig, feeMan, feeCfg.BlockMaxComplexity, nil) } @@ -660,7 +660,7 @@ func (w *wallet) refreshFeesData(ctx *builder.Context, options ...common.Option) w.staticFeesConfig = staticFeesConfigFromContext(ctx) w.isEForkActive = !chainTime.Before(eForkTime) - feeCfg := fee.GetDynamicFeesConfig(w.isEForkActive) + feeCfg := fee.GetDynamicConfig(w.isEForkActive) w.feeRates = feeCfg.FeeRate w.blockMaxComplexity = feeCfg.BlockMaxComplexity return nil From 6b3b23e3600729726ee44f9a1c4e12318782afe1 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 21 May 2024 10:49:25 -0400 Subject: [PATCH 094/120] minor renaming --- tests/e2e/p/workflow.go | 2 +- vms/platformvm/config/config.go | 2 +- vms/platformvm/txs/fee/dynamic_config.go | 4 ++-- vms/platformvm/vm.go | 2 +- wallet/chain/p/wallet.go | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 41512d3d35fd..96e98a3c5335 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -166,7 +166,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { require.NoError(err) // retrieve fees paid for the tx - feeCfg := fee.GetDynamicFeesConfig(true /*isEActive*/) + feeCfg := fee.GetDynamicConfig(true /*isEActive*/) feeCalc := fee.NewDynamicCalculator(pChainStaticFees, commonfees.NewManager(feeCfg.FeeRate), feeCfg.BlockMaxComplexity) pChainExportFee, err = feeCalc.ComputeFee(tx.Unsigned, tx.Creds) require.NoError(err) diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 05c0f0006be4..1046d29faeec 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -116,7 +116,7 @@ func PickFeeCalculator(cfg *Config, time time.Time) *fee.Calculator { if !isEActive { feeCalculator = fee.NewStaticCalculator(staticFeeCfg, cfg.UpgradeConfig, time) } else { - feesCfg := fee.GetDynamicFeesConfig(isEActive) + feesCfg := fee.GetDynamicConfig(isEActive) feesMan := commonfees.NewManager(feesCfg.FeeRate) feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) } diff --git a/vms/platformvm/txs/fee/dynamic_config.go b/vms/platformvm/txs/fee/dynamic_config.go index 7fd371189e82..6280ed0a8582 100644 --- a/vms/platformvm/txs/fee/dynamic_config.go +++ b/vms/platformvm/txs/fee/dynamic_config.go @@ -34,7 +34,7 @@ var ( customDynamicFeesConfig *commonfees.DynamicFeesConfig ) -func GetDynamicFeesConfig(isEActive bool) commonfees.DynamicFeesConfig { +func GetDynamicConfig(isEActive bool) commonfees.DynamicFeesConfig { if !isEActive { return preEUpgradeDynamicFeesConfig } @@ -45,7 +45,7 @@ func GetDynamicFeesConfig(isEActive bool) commonfees.DynamicFeesConfig { return eUpgradeDynamicFeesConfig } -func ResetDynamicFeesConfig(ctx *snow.Context, customFeesConfig *commonfees.DynamicFeesConfig) error { +func ResetDynamicConfig(ctx *snow.Context, customFeesConfig *commonfees.DynamicFeesConfig) error { if customFeesConfig == nil { return nil // nothing to do } diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 101c70938331..96f41d144e81 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -114,7 +114,7 @@ func (vm *VM) Initialize( } chainCtx.Log.Info("retrieved VM execution config", zap.Reflect("config", execConfig)) - if err := fee.ResetDynamicFeesConfig(chainCtx, execConfig.DynamicFeesConfig); err != nil { + if err := fee.ResetDynamicConfig(chainCtx, execConfig.DynamicFeesConfig); err != nil { return fmt.Errorf("failed resetting dynamic fees config: %w", err) } diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index c5f8816ae88c..7778e1e3558e 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -632,7 +632,7 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( if !w.isEForkActive { feeCalculator = fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Config{}, time.Time{}) } else { - feeCfg := fee.GetDynamicFeesConfig(w.isEForkActive) + feeCfg := fee.GetDynamicConfig(w.isEForkActive) feeMan := commonfees.NewManager(w.feeRates) feeCalculator = fee.NewDynamicCalculator(w.staticFeesConfig, feeMan, feeCfg.BlockMaxComplexity) } @@ -660,7 +660,7 @@ func (w *wallet) refreshFeesData(ctx *builder.Context, options ...common.Option) w.staticFeesConfig = staticFeesConfigFromContext(ctx) w.isEForkActive = !chainTime.Before(eForkTime) - feeCfg := fee.GetDynamicFeesConfig(w.isEForkActive) + feeCfg := fee.GetDynamicConfig(w.isEForkActive) w.feeRates = feeCfg.FeeRate w.blockMaxComplexity = feeCfg.BlockMaxComplexity return nil From 7dc89009ea4396deeae3ae69a9eac6789afd6efb Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 11 Jun 2024 17:35:22 +0200 Subject: [PATCH 095/120] simplified Dynamic fee calculator ctor --- tests/e2e/p/workflow.go | 12 +------ vms/platformvm/config/config.go | 5 ++- vms/platformvm/service_test.go | 22 ++++++------ vms/platformvm/txs/fee/calculator.go | 22 ++++++------ vms/platformvm/txs/fee/calculator_test.go | 2 +- wallet/chain/p/builder_test.go | 44 +++++++++++------------ wallet/chain/p/wallet.go | 2 +- 7 files changed, 50 insertions(+), 59 deletions(-) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 96e98a3c5335..11caefedde2c 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -61,16 +61,6 @@ var _ = e2e.DescribePChain("[Workflow]", func() { infoClient := info.NewClient(nodeURI.URI) staticFees, err := infoClient.GetTxFee(e2e.DefaultContext()) require.NoError(err) - pChainStaticFees := fee.StaticConfig{ - TxFee: uint64(staticFees.TxFee), - CreateSubnetTxFee: uint64(staticFees.CreateSubnetTxFee), - TransformSubnetTxFee: uint64(staticFees.TransformSubnetTxFee), - CreateBlockchainTxFee: uint64(staticFees.CreateBlockchainTxFee), - AddPrimaryNetworkValidatorFee: uint64(staticFees.AddPrimaryNetworkValidatorFee), - AddPrimaryNetworkDelegatorFee: uint64(staticFees.AddPrimaryNetworkDelegatorFee), - AddSubnetValidatorFee: uint64(staticFees.AddSubnetValidatorFee), - AddSubnetDelegatorFee: uint64(staticFees.AddSubnetDelegatorFee), - } xChainTxFees := uint64(staticFees.TxFee) tests.Outf("{{green}} X-chain TxFee: %d {{/}}\n", xChainTxFees) @@ -167,7 +157,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { // retrieve fees paid for the tx feeCfg := fee.GetDynamicConfig(true /*isEActive*/) - feeCalc := fee.NewDynamicCalculator(pChainStaticFees, commonfees.NewManager(feeCfg.FeeRate), feeCfg.BlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(feeCfg.FeeRate), feeCfg.BlockMaxComplexity) pChainExportFee, err = feeCalc.ComputeFee(tx.Unsigned, tx.Creds) require.NoError(err) }) diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 1046d29faeec..b04b6d03ab55 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -109,16 +109,15 @@ func (c *Config) CreateChain(chainID ids.ID, tx *txs.CreateChainTx) { func PickFeeCalculator(cfg *Config, time time.Time) *fee.Calculator { var ( isEActive = cfg.UpgradeConfig.IsEActivated(time) - staticFeeCfg = cfg.StaticFeeConfig feeCalculator *fee.Calculator ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(staticFeeCfg, cfg.UpgradeConfig, time) + feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, time) } else { feesCfg := fee.GetDynamicConfig(isEActive) feesMan := commonfees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(staticFeeCfg, feesMan, feesCfg.BlockMaxComplexity) + feeCalculator = fee.NewDynamicCalculator(feesMan, feesCfg.BlockMaxComplexity) } return feeCalculator } diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 1809385d1a3e..4bccbc0899bb 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -76,8 +76,8 @@ var ( } ) -func defaultService(t *testing.T) (*Service, *mutableSharedMemory, *txstest.WalletFactory) { - vm, factory, _, mutableSharedMemory := defaultVM(t, latestFork) +func defaultService(t *testing.T, f fork) (*Service, *mutableSharedMemory, *txstest.WalletFactory) { + vm, factory, _, mutableSharedMemory := defaultVM(t, f) return &Service{ vm: vm, @@ -91,7 +91,7 @@ func defaultService(t *testing.T) (*Service, *mutableSharedMemory, *txstest.Wall func TestExportKey(t *testing.T) { require := require.New(t) - service, _, _ := defaultService(t) + service, _, _ := defaultService(t, latestFork) service.vm.ctx.Lock.Lock() ks := keystore.New(logging.NoLog{}, memdb.New()) @@ -121,7 +121,7 @@ func TestExportKey(t *testing.T) { // Test issuing a tx and accepted func TestGetTxStatus(t *testing.T) { require := require.New(t) - service, mutableSharedMemory, factory := defaultService(t) + service, mutableSharedMemory, factory := defaultService(t, latestFork) service.vm.ctx.Lock.Lock() recipientKey, err := secp256k1.NewPrivateKey() @@ -314,7 +314,7 @@ func TestGetTx(t *testing.T) { ) t.Run(testName, func(t *testing.T) { require := require.New(t) - service, _, txBuilder := defaultService(t) + service, _, txBuilder := defaultService(t, latestFork) service.vm.ctx.Lock.Lock() tx, err := test.createTx(service, txBuilder) @@ -378,7 +378,7 @@ func TestGetTx(t *testing.T) { func TestGetBalance(t *testing.T) { require := require.New(t) - service, _, _ := defaultService(t) + service, _, _ := defaultService(t, latestFork) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) @@ -409,7 +409,7 @@ func TestGetBalance(t *testing.T) { func TestGetStake(t *testing.T) { require := require.New(t) - service, _, factory := defaultService(t) + service, _, factory := defaultService(t, durango) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) @@ -600,7 +600,7 @@ func TestGetStake(t *testing.T) { func TestGetCurrentValidators(t *testing.T) { require := require.New(t) - service, _, factory := defaultService(t) + service, _, factory := defaultService(t, durango) genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) @@ -736,7 +736,7 @@ func TestGetCurrentValidators(t *testing.T) { func TestGetTimestamp(t *testing.T) { require := require.New(t) - service, _, _ := defaultService(t) + service, _, _ := defaultService(t, latestFork) reply := GetTimestampReply{} require.NoError(service.GetTimestamp(nil, nil, &reply)) @@ -772,7 +772,7 @@ func TestGetBlock(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { require := require.New(t) - service, _, factory := defaultService(t) + service, _, factory := defaultService(t, latestFork) service.vm.ctx.Lock.Lock() service.vm.StaticFeeConfig.CreateAssetTxFee = 100 * defaultTxFee @@ -1065,7 +1065,7 @@ func TestServiceGetBlockByHeight(t *testing.T) { func TestServiceGetSubnets(t *testing.T) { require := require.New(t) - service, _, _ := defaultService(t) + service, _, _ := defaultService(t, latestFork) testSubnet1ID := testSubnet1.ID() diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 74b9c448f472..fba73f6987a8 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -38,14 +38,12 @@ func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config, chain // NewDynamicCalculator must be used post E upgrade activation func NewDynamicCalculator( - cfg StaticConfig, feeManager *fees.Manager, blockMaxComplexity fees.Dimensions, ) *Calculator { return &Calculator{ c: &calculator{ isEActive: true, - staticCfg: cfg, feeManager: feeManager, blockMaxComplexity: blockMaxComplexity, // credentials are set when CalculateFee is called @@ -106,10 +104,12 @@ type calculator struct { } func (c *calculator) AddValidatorTx(*txs.AddValidatorTx) error { - // AddValidatorTx is banned following Durango activation, so we - // only return the pre EUpgrade fee here - c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee - return nil + // AddValidatorTx is banned following Durango activation + if !c.isEActive { + c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee + return nil + } + return errFailedFeeCalculation } func (c *calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { @@ -128,10 +128,12 @@ func (c *calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { } func (c *calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { - // AddValidatorTx is banned following Durango activation, so we - // only return the pre EUpgrade fee here - c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee - return nil + // AddDelegatorTx is banned following Durango activation + if !c.isEActive { + c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee + return nil + } + return errFailedFeeCalculation } func (c *calculator) CreateChainTx(tx *txs.CreateChainTx) error { diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 6cd518a33ab4..e62eb858da15 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -693,7 +693,7 @@ func TestTxFees(t *testing.T) { if !upgrades.IsEActivated(tt.chainTime) { fc = NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) } else { - fc = NewDynamicCalculator(feeTestsDefaultCfg, fees.NewManager(testFeeRates), maxComplexity) + fc = NewDynamicCalculator(fees.NewManager(testFeeRates), maxComplexity) } var creds []verify.Verifiable diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 0cea1cabda1e..c39b8cf8b7ff 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -100,7 +100,7 @@ func TestBaseTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) utx, err := builder.NewBaseTx( outputsToMove, feeCalc, @@ -110,7 +110,7 @@ func TestBaseTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9930*units.MicroAvax, fee) @@ -204,14 +204,14 @@ func TestAddSubnetValidatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) utx, err := builder.NewAddSubnetValidatorTx(subnetValidator, feeCalc) require.NoError(err) tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9765*units.MicroAvax, fee) @@ -292,7 +292,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) utx, err := builder.NewRemoveSubnetValidatorTx( ids.GenerateTestNodeID(), subnetID, @@ -303,7 +303,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9741*units.MicroAvax, fee) @@ -394,7 +394,7 @@ func TestCreateChainTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) utx, err := builder.NewCreateChainTx( subnetID, genesisBytes, @@ -408,7 +408,7 @@ func TestCreateChainTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9808*units.MicroAvax, fee) @@ -496,7 +496,7 @@ func TestCreateSubnetTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) utx, err := builder.NewCreateSubnetTx( subnetOwner, feeCalc, @@ -506,7 +506,7 @@ func TestCreateSubnetTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9644*units.MicroAvax, fee) @@ -590,7 +590,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) utx, err := builder.NewTransferSubnetOwnershipTx( subnetID, subnetOwner, @@ -601,7 +601,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9761*units.MicroAvax, fee) @@ -680,7 +680,7 @@ func TestImportTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) utx, err := builder.NewImportTx( sourceChainID, importTo, @@ -691,7 +691,7 @@ func TestImportTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(14251*units.MicroAvax, fee) @@ -770,7 +770,7 @@ func TestExportTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) utx, err := builder.NewExportTx( subnetID, exportedOutputs, @@ -781,7 +781,7 @@ func TestExportTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9966*units.MicroAvax, fee) @@ -872,7 +872,7 @@ func TestTransformSubnetTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) utx, err := builder.NewTransformSubnetTx( subnetID, subnetAssetID, @@ -895,7 +895,7 @@ func TestTransformSubnetTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(14763*units.MicroAvax, fee) @@ -994,7 +994,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { require.NoError(err) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1016,7 +1016,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(20404*units.MicroAvax, fee) @@ -1113,7 +1113,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) utx, err := builder.NewAddPermissionlessDelegatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1132,7 +1132,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(testStaticConfig, commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(20212*units.MicroAvax, fee) diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 7778e1e3558e..086eb411b4c1 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -634,7 +634,7 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( } else { feeCfg := fee.GetDynamicConfig(w.isEForkActive) feeMan := commonfees.NewManager(w.feeRates) - feeCalculator = fee.NewDynamicCalculator(w.staticFeesConfig, feeMan, feeCfg.BlockMaxComplexity) + feeCalculator = fee.NewDynamicCalculator(feeMan, feeCfg.BlockMaxComplexity) } return feeCalculator, nil } From 227b677c302fea7aec6c0925b4695bd3a7ea5632 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 11 Jun 2024 17:55:05 +0200 Subject: [PATCH 096/120] =?UTF-8?q?simplified=20GetDynamicConfig=C3=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/e2e/p/workflow.go | 4 +++- vms/platformvm/config/config.go | 2 +- vms/platformvm/txs/fee/dynamic_config.go | 17 +++++++---------- wallet/chain/p/wallet.go | 7 +++++-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 11caefedde2c..ad6e3f6e3b3f 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -156,7 +156,9 @@ var _ = e2e.DescribePChain("[Workflow]", func() { require.NoError(err) // retrieve fees paid for the tx - feeCfg := fee.GetDynamicConfig(true /*isEActive*/) + feeCfg, err := fee.GetDynamicConfig(true /*isEActive*/) + require.NoError(err) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(feeCfg.FeeRate), feeCfg.BlockMaxComplexity) pChainExportFee, err = feeCalc.ComputeFee(tx.Unsigned, tx.Creds) require.NoError(err) diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index b04b6d03ab55..44825bd41c9a 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -115,7 +115,7 @@ func PickFeeCalculator(cfg *Config, time time.Time) *fee.Calculator { if !isEActive { feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, time) } else { - feesCfg := fee.GetDynamicConfig(isEActive) + feesCfg, _ := fee.GetDynamicConfig(isEActive) feesMan := commonfees.NewManager(feesCfg.FeeRate) feeCalculator = fee.NewDynamicCalculator(feesMan, feesCfg.BlockMaxComplexity) } diff --git a/vms/platformvm/txs/fee/dynamic_config.go b/vms/platformvm/txs/fee/dynamic_config.go index 6280ed0a8582..113f55b68bd7 100644 --- a/vms/platformvm/txs/fee/dynamic_config.go +++ b/vms/platformvm/txs/fee/dynamic_config.go @@ -4,6 +4,7 @@ package fee import ( + "errors" "fmt" "github.com/ava-labs/avalanchego/snow" @@ -13,8 +14,9 @@ import ( commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) -// eUpgradeDynamicFeesConfig to be tuned TODO ABENEGIA var ( + errDynamicFeeConfigNotAvailable = errors.New("dynamic fee config not available") + eUpgradeDynamicFeesConfig = commonfees.DynamicFeesConfig{ FeeRate: commonfees.Dimensions{ 1 * units.NanoAvax, @@ -26,23 +28,18 @@ var ( BlockMaxComplexity: commonfees.Max, } - preEUpgradeDynamicFeesConfig = commonfees.DynamicFeesConfig{ - FeeRate: commonfees.Empty, - BlockMaxComplexity: commonfees.Max, - } - customDynamicFeesConfig *commonfees.DynamicFeesConfig ) -func GetDynamicConfig(isEActive bool) commonfees.DynamicFeesConfig { +func GetDynamicConfig(isEActive bool) (commonfees.DynamicFeesConfig, error) { if !isEActive { - return preEUpgradeDynamicFeesConfig + return commonfees.DynamicFeesConfig{}, errDynamicFeeConfigNotAvailable } if customDynamicFeesConfig != nil { - return *customDynamicFeesConfig + return *customDynamicFeesConfig, nil } - return eUpgradeDynamicFeesConfig + return eUpgradeDynamicFeesConfig, nil } func ResetDynamicConfig(ctx *snow.Context, customFeesConfig *commonfees.DynamicFeesConfig) error { diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 086eb411b4c1..be63498bc766 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -632,7 +632,7 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( if !w.isEForkActive { feeCalculator = fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Config{}, time.Time{}) } else { - feeCfg := fee.GetDynamicConfig(w.isEForkActive) + feeCfg, _ := fee.GetDynamicConfig(w.isEForkActive) feeMan := commonfees.NewManager(w.feeRates) feeCalculator = fee.NewDynamicCalculator(feeMan, feeCfg.BlockMaxComplexity) } @@ -660,7 +660,10 @@ func (w *wallet) refreshFeesData(ctx *builder.Context, options ...common.Option) w.staticFeesConfig = staticFeesConfigFromContext(ctx) w.isEForkActive = !chainTime.Before(eForkTime) - feeCfg := fee.GetDynamicConfig(w.isEForkActive) + if !w.isEForkActive { + return nil // nothing else to update + } + feeCfg, _ := fee.GetDynamicConfig(w.isEForkActive) w.feeRates = feeCfg.FeeRate w.blockMaxComplexity = feeCfg.BlockMaxComplexity return nil From f31f1ac625e2aff6d353c858bddde6970cff0872 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 11 Jun 2024 19:21:26 +0200 Subject: [PATCH 097/120] wip: consolidating fee dimensions into single gas scalar --- tests/e2e/p/workflow.go | 2 +- vms/components/fees/config.go | 15 +- vms/components/fees/dimensions.go | 23 ++- vms/components/fees/manager.go | 81 ++++------- vms/platformvm/block/executor/acceptor.go | 8 +- vms/platformvm/block/executor/block_state.go | 8 +- vms/platformvm/block/executor/verifier.go | 22 +-- .../block/executor/verifier_test.go | 4 +- vms/platformvm/config/config.go | 4 +- vms/platformvm/metrics/metrics.go | 37 ++--- vms/platformvm/metrics/no_op.go | 2 +- vms/platformvm/txs/fee/calculator.go | 49 ++++--- vms/platformvm/txs/fee/calculator_test.go | 131 +++++++----------- vms/platformvm/txs/fee/dynamic_config.go | 15 +- wallet/chain/p/builder_test.go | 53 ++++--- wallet/chain/p/wallet.go | 15 +- 16 files changed, 213 insertions(+), 256 deletions(-) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index ad6e3f6e3b3f..3e4643c4c14c 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -159,7 +159,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { feeCfg, err := fee.GetDynamicConfig(true /*isEActive*/) require.NoError(err) - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(feeCfg.FeeRate), feeCfg.BlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(feeCfg.GasPrice), feeCfg.TempBlockMaxGas) pChainExportFee, err = feeCalc.ComputeFee(tx.Unsigned, tx.Creds) require.NoError(err) }) diff --git a/vms/components/fees/config.go b/vms/components/fees/config.go index 20b528703866..d141c033993d 100644 --- a/vms/components/fees/config.go +++ b/vms/components/fees/config.go @@ -4,12 +4,11 @@ package fees type DynamicFeesConfig struct { - // FeeRate contains, per each fee dimension, the fee rate, - // i.e. the fee per unit of complexity. Fee rates are - // valid as soon as fork introducing dynamic fees activates. - FeeRate Dimensions `json:"fee-rate"` - - // BlockMaxComplexity contains, per each fee dimension, the - // maximal complexity a valid block can host. - BlockMaxComplexity Dimensions `json:"block-max-complexity"` + GasPrice GasPrice `json:"gas-price"` + + // weights to merge fees dimensions complexities into a single gas value + FeeDimensionWeights Dimensions `json:"fee-dimension-weights"` + + // TODO ABENEGIA: replace with leaky bucket implementation + TempBlockMaxGas Gas } diff --git a/vms/components/fees/dimensions.go b/vms/components/fees/dimensions.go index 8184c242768f..dafa38a0f776 100644 --- a/vms/components/fees/dimensions.go +++ b/vms/components/fees/dimensions.go @@ -27,6 +27,8 @@ const ( var ( errUnknownDimension = errors.New("unknown dimension") + ZeroGas = Gas(0) + Empty = Dimensions{} Max = Dimensions{ math.MaxUint64, @@ -44,7 +46,11 @@ var ( ) type ( - Dimension int + Dimension int + + GasPrice uint64 + Gas uint64 + Dimensions [FeeDimensions]uint64 ) @@ -67,3 +73,18 @@ func Add(lhs, rhs Dimensions) (Dimensions, error) { } return res, nil } + +func ScalarProd(lhs, rhs Dimensions) (Gas, error) { + var res uint64 + for i := 0; i < FeeDimensions; i++ { + v, err := safemath.Mul64(lhs[i], rhs[i]) + if err != nil { + return ZeroGas, err + } + res, err = safemath.Add64(res, v) + if err != nil { + return ZeroGas, err + } + } + return Gas(res), nil +} diff --git a/vms/components/fees/manager.go b/vms/components/fees/manager.go index cf18276c1938..59b3de4f0024 100644 --- a/vms/components/fees/manager.go +++ b/vms/components/fees/manager.go @@ -4,89 +4,66 @@ package fees import ( + "errors" "fmt" safemath "github.com/ava-labs/avalanchego/utils/math" ) +var errGasBoundBreached = errors.New("gas bound breached") + type Manager struct { - // Avax denominated fee rates, i.e. fees per unit of complexity. - feeRates Dimensions + // Avax denominated gas price, i.e. fee per unit of complexity. + gasPrice GasPrice - // cumulatedComplexity helps aggregating the units of complexity consumed + // cumulatedGas helps aggregating the gas consumed // by a block so that we can verify it's not too big/build it properly. - cumulatedComplexity Dimensions + cumulatedGas Gas } -func NewManager(feeRate Dimensions) *Manager { +func NewManager(gasPrice GasPrice) *Manager { return &Manager{ - feeRates: feeRate, + gasPrice: gasPrice, } } -func (m *Manager) GetFeeRates() Dimensions { - return m.feeRates +func (m *Manager) GetGasPrice() GasPrice { + return m.gasPrice } -func (m *Manager) GetCumulatedComplexity() Dimensions { - return m.cumulatedComplexity +func (m *Manager) GetGas() Gas { + return m.cumulatedGas } // CalculateFee must be a stateless method -func (m *Manager) CalculateFee(units Dimensions) (uint64, error) { - fee := uint64(0) - - for i := Dimension(0); i < FeeDimensions; i++ { - contribution, err := safemath.Mul64(m.feeRates[i], units[i]) - if err != nil { - return 0, err - } - fee, err = safemath.Add64(contribution, fee) - if err != nil { - return 0, err - } - } - return fee, nil +func (m *Manager) CalculateFee(g Gas) (uint64, error) { + return safemath.Mul64(uint64(m.gasPrice), uint64(g)) } // CumulateComplexity tries to cumulate the consumed complexity [units]. Before // actually cumulating them, it checks whether the result would breach [bounds]. // If so, it returns the first dimension to breach bounds. -func (m *Manager) CumulateComplexity(units, bounds Dimensions) (bool, Dimension) { +func (m *Manager) CumulateComplexity(gas, bound Gas) error { // Ensure we can consume (don't want partial update of values) - for i := Dimension(0); i < FeeDimensions; i++ { - consumed, err := safemath.Add64(m.cumulatedComplexity[i], units[i]) - if err != nil { - return true, i - } - if consumed > bounds[i] { - return true, i - } + consumed, err := safemath.Add64(uint64(m.gasPrice), uint64(gas)) + if err != nil { + return fmt.Errorf("%w: %w", errGasBoundBreached, err) } - - // Commit to consumption - for i := Dimension(0); i < FeeDimensions; i++ { - consumed, err := safemath.Add64(m.cumulatedComplexity[i], units[i]) - if err != nil { - return true, i - } - m.cumulatedComplexity[i] = consumed + if Gas(consumed) > bound { + return errGasBoundBreached } - return false, 0 + + m.cumulatedGas = Gas(consumed) + return nil } // Sometimes, e.g. while building a tx, we'd like freedom to speculatively add complexity // and to remove it later on. [RemoveComplexity] grants this freedom -func (m *Manager) RemoveComplexity(unitsToRm Dimensions) error { - var revertedUnits Dimensions - for i := Dimension(0); i < FeeDimensions; i++ { - prev, err := safemath.Sub(m.cumulatedComplexity[i], unitsToRm[i]) - if err != nil { - return fmt.Errorf("%w: dimension %d", err, i) - } - revertedUnits[i] = prev +func (m *Manager) RemoveComplexity(gasToRm Gas) error { + revertedGas, err := safemath.Sub(m.cumulatedGas, gasToRm) + if err != nil { + return fmt.Errorf("%w: current Gas %d, gas to revert %d", err, m.cumulatedGas, gasToRm) } - - m.cumulatedComplexity = revertedUnits + m.cumulatedGas = revertedGas return nil } diff --git a/vms/platformvm/block/executor/acceptor.go b/vms/platformvm/block/executor/acceptor.go index 0cca4435f257..a3bc81fa6d95 100644 --- a/vms/platformvm/block/executor/acceptor.go +++ b/vms/platformvm/block/executor/acceptor.go @@ -79,7 +79,7 @@ func (a *acceptor) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { return fmt.Errorf("%w %s", errMissingBlockState, blkID) } - a.metrics.SetBlockComplexity(blkState.blockComplexity) + a.metrics.SetBlockGas(blkState.blockGas) // Update the state to reflect the changes made in [onAcceptState]. if err := blkState.onAcceptState.Apply(a.state); err != nil { @@ -138,7 +138,7 @@ func (a *acceptor) optionBlock(b block.Block, blockType string) error { return err } - a.metrics.SetBlockComplexity(parentState.blockComplexity) + a.metrics.SetBlockGas(parentState.blockGas) if err := a.commonAccept(b); err != nil { return err @@ -156,7 +156,7 @@ func (a *acceptor) optionBlock(b block.Block, blockType string) error { } // we set option complexity at its parent block's one. - a.metrics.SetBlockComplexity(parentState.blockComplexity) + a.metrics.SetBlockGas(parentState.blockGas) if err := blkState.onAcceptState.Apply(a.state); err != nil { return err @@ -236,7 +236,7 @@ func (a *acceptor) standardBlock(b block.Block, blockType string) error { return fmt.Errorf("%w %s", errMissingBlockState, blkID) } - a.metrics.SetBlockComplexity(blkState.blockComplexity) + a.metrics.SetBlockGas(blkState.blockGas) // Update the state to reflect the changes made in [onAcceptState]. if err := blkState.onAcceptState.Apply(a.state); err != nil { diff --git a/vms/platformvm/block/executor/block_state.go b/vms/platformvm/block/executor/block_state.go index f0e3989a7856..cdb3c7c8d2b7 100644 --- a/vms/platformvm/block/executor/block_state.go +++ b/vms/platformvm/block/executor/block_state.go @@ -30,8 +30,8 @@ type blockState struct { onAcceptState state.Diff onAcceptFunc func() - inputs set.Set[ids.ID] - timestamp time.Time - blockComplexity commonfees.Dimensions - atomicRequests map[ids.ID]*atomic.Requests + inputs set.Set[ids.ID] + timestamp time.Time + blockGas commonfees.Gas + atomicRequests map[ids.ID]*atomic.Requests } diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 035a00d44d20..bd7bb5c4a4f4 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -232,10 +232,10 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { onAcceptState: atomicExecutor.OnAccept, - inputs: atomicExecutor.Inputs, - timestamp: atomicExecutor.OnAccept.GetTimestamp(), - blockComplexity: fees.Empty, - atomicRequests: atomicExecutor.AtomicRequests, + inputs: atomicExecutor.Inputs, + timestamp: atomicExecutor.OnAccept.GetTimestamp(), + blockGas: fees.ZeroGas, + atomicRequests: atomicExecutor.AtomicRequests, } return nil } @@ -421,9 +421,9 @@ func (v *verifier) proposalBlock( // It is safe to use [b.onAbortState] here because the timestamp will // never be modified by an Apricot Abort block and the timestamp will // always be the same as the Banff Proposal Block. - timestamp: onAbortState.GetTimestamp(), - blockComplexity: feeCalculator.GetCumulatedComplexity(), - atomicRequests: atomicRequests, + timestamp: onAbortState.GetTimestamp(), + blockGas: feeCalculator.GetGas(), + atomicRequests: atomicRequests, } return nil } @@ -448,10 +448,10 @@ func (v *verifier) standardBlock( onAcceptState: onAcceptState, onAcceptFunc: onAcceptFunc, - timestamp: onAcceptState.GetTimestamp(), - blockComplexity: feeCalculator.GetCumulatedComplexity(), - inputs: inputs, - atomicRequests: atomicRequests, + timestamp: onAcceptState.GetTimestamp(), + blockGas: feeCalculator.GetGas(), + inputs: inputs, + atomicRequests: atomicRequests, } return nil } diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index d58d8e87465f..068dbcfe172b 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -512,9 +512,9 @@ func TestStandardBlockComplexity(t *testing.T) { require.True(found) if dynamicFeesActive { - require.NotEqual(commonfees.Empty, blkState.blockComplexity) + require.NotEqual(commonfees.Empty, blkState.blockGas) } else { - require.Equal(commonfees.Empty, blkState.blockComplexity) + require.Equal(commonfees.Empty, blkState.blockGas) } }) } diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 44825bd41c9a..f63814d66286 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -116,8 +116,8 @@ func PickFeeCalculator(cfg *Config, time time.Time) *fee.Calculator { feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, time) } else { feesCfg, _ := fee.GetDynamicConfig(isEActive) - feesMan := commonfees.NewManager(feesCfg.FeeRate) - feeCalculator = fee.NewDynamicCalculator(feesMan, feesCfg.BlockMaxComplexity) + feesMan := commonfees.NewManager(feesCfg.GasPrice) + feeCalculator = fee.NewDynamicCalculator(feesMan, feesCfg.TempBlockMaxGas) } return feeCalculator } diff --git a/vms/platformvm/metrics/metrics.go b/vms/platformvm/metrics/metrics.go index dbaadc86eb18..3a3773708562 100644 --- a/vms/platformvm/metrics/metrics.go +++ b/vms/platformvm/metrics/metrics.go @@ -42,7 +42,7 @@ type Metrics interface { SetTimeUntilSubnetUnstake(subnetID ids.ID, timeUntilUnstake time.Duration) // Mark cumulated complexity of the latest accepted block - SetBlockComplexity(commonfees.Dimensions) + SetBlockGas(commonfees.Gas) } func New(registerer prometheus.Registerer) (Metrics, error) { @@ -85,21 +85,9 @@ func New(registerer prometheus.Registerer) (Metrics, error) { Name: "validator_sets_duration_sum", Help: "Total amount of time generating validator sets in nanoseconds", }), - blockBandwitdhComplexity: prometheus.NewGauge(prometheus.GaugeOpts{ - Name: "block_bandwidth_complexity", - Help: "Cumulated bandwidth complexity over last accepted block", - }), - blockUTXOsReadComplexity: prometheus.NewGauge(prometheus.GaugeOpts{ - Name: "block_utxos_read_complexity", - Help: "Cumulated utxos read complexity over last accepted block", - }), - blockUTXOsWriteComplexity: prometheus.NewGauge(prometheus.GaugeOpts{ - Name: "block_utxos_write_complexity", - Help: "Cumulated utxos write complexity over last accepted block", - }), - blockComputeComplexity: prometheus.NewGauge(prometheus.GaugeOpts{ - Name: "block_compute_complexity", - Help: "Cumulated compute complexity over last accepted block", + blockGas: prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "block_gas", + Help: "Cumulated gas over last accepted block", }), } @@ -117,10 +105,7 @@ func New(registerer prometheus.Registerer) (Metrics, error) { registerer.Register(m.validatorSetsCached), registerer.Register(m.validatorSetsHeightDiff), registerer.Register(m.validatorSetsDuration), - registerer.Register(m.blockBandwitdhComplexity), - registerer.Register(m.blockUTXOsReadComplexity), - registerer.Register(m.blockUTXOsWriteComplexity), - registerer.Register(m.blockComputeComplexity), + registerer.Register(m.blockGas), ) return m, errs.Err @@ -141,10 +126,7 @@ type metrics struct { validatorSetsHeightDiff prometheus.Gauge validatorSetsDuration prometheus.Gauge - blockBandwitdhComplexity prometheus.Gauge - blockUTXOsReadComplexity prometheus.Gauge - blockUTXOsWriteComplexity prometheus.Gauge - blockComputeComplexity prometheus.Gauge + blockGas prometheus.Gauge } func (m *metrics) MarkAccepted(b block.Block) error { @@ -183,9 +165,6 @@ func (m *metrics) SetTimeUntilSubnetUnstake(subnetID ids.ID, timeUntilUnstake ti m.timeUntilSubnetUnstake.WithLabelValues(subnetID.String()).Set(float64(timeUntilUnstake)) } -func (m *metrics) SetBlockComplexity(units commonfees.Dimensions) { - m.blockBandwitdhComplexity.Set(float64(units[commonfees.Bandwidth])) - m.blockUTXOsReadComplexity.Set(float64(units[commonfees.UTXORead])) - m.blockUTXOsWriteComplexity.Set(float64(units[commonfees.UTXOWrite])) - m.blockComputeComplexity.Set(float64(units[commonfees.Compute])) +func (m *metrics) SetBlockGas(g commonfees.Gas) { + m.blockGas.Set(float64(g)) } diff --git a/vms/platformvm/metrics/no_op.go b/vms/platformvm/metrics/no_op.go index 22cc5defc8ad..f01c6458d74e 100644 --- a/vms/platformvm/metrics/no_op.go +++ b/vms/platformvm/metrics/no_op.go @@ -53,4 +53,4 @@ func (noopMetrics) SetSubnetPercentConnected(ids.ID, float64) {} func (noopMetrics) SetPercentConnected(float64) {} -func (noopMetrics) SetBlockComplexity(commonfees.Dimensions) {} +func (noopMetrics) SetBlockGas(commonfees.Gas) {} diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index fba73f6987a8..1edc2a8df934 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -39,13 +39,13 @@ func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config, chain // NewDynamicCalculator must be used post E upgrade activation func NewDynamicCalculator( feeManager *fees.Manager, - blockMaxComplexity fees.Dimensions, + maxGas fees.Gas, ) *Calculator { return &Calculator{ c: &calculator{ - isEActive: true, - feeManager: feeManager, - blockMaxComplexity: blockMaxComplexity, + isEActive: true, + feeManager: feeManager, + maxGas: maxGas, // credentials are set when CalculateFee is called }, } @@ -78,11 +78,11 @@ func (c *Calculator) RemoveFeesFor(unitsToRm fees.Dimensions) (uint64, error) { return c.c.removeFeesFor(unitsToRm) } -func (c *Calculator) GetCumulatedComplexity() fees.Dimensions { +func (c *Calculator) GetGas() fees.Gas { if c.c.feeManager != nil { - return c.c.feeManager.GetCumulatedComplexity() + return c.c.feeManager.GetGas() } - return fees.Empty + return 0 } type calculator struct { @@ -95,9 +95,9 @@ type calculator struct { time time.Time // Post E-upgrade inputs - feeManager *fees.Manager - blockMaxComplexity fees.Dimensions - credentials []verify.Verifiable + feeManager *fees.Manager + maxGas fees.Gas + credentials []verify.Verifiable // outputs of visitor execution fee uint64 @@ -392,12 +392,19 @@ func (c *calculator) addFeesFor(complexity fees.Dimensions) (uint64, error) { return 0, nil } - boundBreached, dimension := c.feeManager.CumulateComplexity(complexity, c.blockMaxComplexity) - if boundBreached { - return 0, fmt.Errorf("%w: breached dimension %d", errFailedComplexityCumulation, dimension) + feeCfg, err := GetDynamicConfig(c.isEActive) + if err != nil { + return 0, fmt.Errorf("failed adding fees: %w", err) + } + txGas, err := fees.ScalarProd(complexity, feeCfg.FeeDimensionWeights) + if err != nil { + return 0, fmt.Errorf("failed adding fees: %w", err) } - fee, err := c.feeManager.CalculateFee(complexity) + if err := c.feeManager.CumulateComplexity(txGas, c.maxGas); err != nil { + return 0, fmt.Errorf("failed cumulating complexity: %w", err) + } + fee, err := c.feeManager.CalculateFee(txGas) if err != nil { return 0, fmt.Errorf("%w: %w", errFailedFeeCalculation, err) } @@ -411,11 +418,19 @@ func (c *calculator) removeFeesFor(unitsToRm fees.Dimensions) (uint64, error) { return 0, nil } - if err := c.feeManager.RemoveComplexity(unitsToRm); err != nil { - return 0, fmt.Errorf("failed removing units: %w", err) + feeCfg, err := GetDynamicConfig(c.isEActive) + if err != nil { + return 0, fmt.Errorf("failed adding fees: %w", err) + } + txGas, err := fees.ScalarProd(unitsToRm, feeCfg.FeeDimensionWeights) + if err != nil { + return 0, fmt.Errorf("failed adding fees: %w", err) } - fee, err := c.feeManager.CalculateFee(unitsToRm) + if err := c.feeManager.RemoveComplexity(txGas); err != nil { + return 0, fmt.Errorf("failed removing units: %w", err) + } + fee, err := c.feeManager.CalculateFee(txGas) if err != nil { return 0, fmt.Errorf("%w: %w", errFailedFeeCalculation, err) } diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index e62eb858da15..8f04e37497fa 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -28,18 +28,9 @@ import ( ) var ( - testFeeRates = fees.Dimensions{ - 1 * units.MicroAvax, - 2 * units.MicroAvax, - 3 * units.MicroAvax, - 4 * units.MicroAvax, - } - testBlockMaxComplexity = fees.Dimensions{ - 3000, - 3500, - 1000, - 2000, - } + testGasPrice = fees.GasPrice(10 * units.NanoAvax) + + testBlockMaxGas = fees.Gas(100_000) preFundedKeys = secp256k1.TestKeys() feeTestSigners = [][]*secp256k1.PrivateKey{preFundedKeys} @@ -51,9 +42,9 @@ func TestAddAndRemoveFees(t *testing.T) { fc := &Calculator{ c: &calculator{ - isEActive: true, - feeManager: fees.NewManager(testFeeRates), - blockMaxComplexity: testBlockMaxComplexity, + isEActive: true, + feeManager: fees.NewManager(testGasPrice), + maxGas: testBlockMaxGas, }, } @@ -64,25 +55,25 @@ func TestAddAndRemoveFees(t *testing.T) { feeDelta, err := fc.AddFeesFor(units) r.NoError(err) - r.Equal(units, fc.c.feeManager.GetCumulatedComplexity()) + r.Equal(units, fc.c.feeManager.GetGas()) r.NotZero(feeDelta) r.Equal(feeDelta, fc.c.fee) feeDelta2, err := fc.AddFeesFor(units) r.NoError(err) - r.Equal(doubleUnits, fc.c.feeManager.GetCumulatedComplexity()) + r.Equal(doubleUnits, fc.c.feeManager.GetGas()) r.Equal(feeDelta, feeDelta2) r.Equal(feeDelta+feeDelta2, fc.c.fee) feeDelta3, err := fc.RemoveFeesFor(units) r.NoError(err) - r.Equal(units, fc.c.feeManager.GetCumulatedComplexity()) + r.Equal(units, fc.c.feeManager.GetGas()) r.Equal(feeDelta, feeDelta3) r.Equal(feeDelta, fc.c.fee) feeDelta4, err := fc.RemoveFeesFor(units) r.NoError(err) - r.Zero(fc.c.feeManager.GetCumulatedComplexity()) + r.Zero(fc.c.feeManager.GetGas()) r.Equal(feeDelta, feeDelta4) r.Zero(fc.c.fee) } @@ -119,7 +110,7 @@ func TestTxFees(t *testing.T) { name string chainTime time.Time unsignedAndSignedTx func(t *testing.T) (txs.UnsignedTx, *txs.Tx) - maxComplexityF func() fees.Dimensions + maxGasF func() fees.Gas expectedError error checksF func(*testing.T, *calculator) }{ @@ -153,17 +144,15 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, { name: "AddSubnetValidatorTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxComplexity - caps[fees.UTXORead] = 90 - 1 - return caps + maxGasF: func() fees.Gas { + return testBlockMaxGas - 1 }, unsignedAndSignedTx: addSubnetValidatorTx, expectedError: errFailedComplexityCumulation, @@ -207,7 +196,7 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, @@ -215,10 +204,8 @@ func TestTxFees(t *testing.T) { name: "CreateChainTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, unsignedAndSignedTx: createChainTx, - maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxComplexity - caps[fees.UTXORead] = 90 - 1 - return caps + maxGasF: func() fees.Gas { + return testBlockMaxGas - 1 }, expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *calculator) {}, @@ -253,7 +240,7 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, @@ -261,10 +248,8 @@ func TestTxFees(t *testing.T) { name: "CreateSubnetTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, unsignedAndSignedTx: createSubnetTx, - maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxComplexity - caps[fees.UTXORead] = 90 - 1 - return caps + maxGasF: func() fees.Gas { + return testBlockMaxGas - 1 }, expectedError: errFailedComplexityCumulation, checksF: func(*testing.T, *calculator) {}, @@ -291,17 +276,15 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, { name: "RemoveSubnetValidatorTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxComplexity - caps[fees.UTXORead] = 90 - 1 - return caps + maxGasF: func() fees.Gas { + return testBlockMaxGas - 1 }, unsignedAndSignedTx: removeSubnetValidatorTx, expectedError: errFailedComplexityCumulation, @@ -329,17 +312,15 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, { name: "TransformSubnetTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxComplexity - caps[fees.UTXORead] = 90 - 1 - return caps + maxGasF: func() fees.Gas { + return testBlockMaxGas - 1 }, unsignedAndSignedTx: transformSubnetTx, expectedError: errFailedComplexityCumulation, @@ -367,17 +348,15 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, { name: "TransferSubnetOwnershipTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxComplexity - caps[fees.UTXORead] = 90 - 1 - return caps + maxGasF: func() fees.Gas { + return testBlockMaxGas - 1 }, unsignedAndSignedTx: transferSubnetOwnershipTx, expectedError: errFailedComplexityCumulation, @@ -421,7 +400,7 @@ func TestTxFees(t *testing.T) { 266, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, @@ -443,17 +422,15 @@ func TestTxFees(t *testing.T) { 266, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, { name: "AddPermissionlessValidatorTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxComplexity - caps[fees.UTXORead] = 90 - 1 - return caps + maxGasF: func() fees.Gas { + return testBlockMaxGas - 1 }, unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { subnetID := ids.GenerateTestID() @@ -500,7 +477,7 @@ func TestTxFees(t *testing.T) { 266, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, @@ -520,17 +497,15 @@ func TestTxFees(t *testing.T) { 266, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, { name: "AddPermissionlessDelegatorTx Subnet post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxComplexity - caps[fees.UTXORead] = 90 - 1 - return caps + maxGasF: func() fees.Gas { + return testBlockMaxGas - 1 }, unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { subnetID := ids.GenerateTestID() @@ -562,17 +537,15 @@ func TestTxFees(t *testing.T) { 172, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, { name: "BaseTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxComplexity - caps[fees.UTXORead] = 90 - 1 - return caps + maxGasF: func() fees.Gas { + return testBlockMaxGas - 1 }, unsignedAndSignedTx: baseTx, expectedError: errFailedComplexityCumulation, @@ -600,17 +573,15 @@ func TestTxFees(t *testing.T) { 262, 2000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, { name: "ImportTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxComplexity - caps[fees.UTXORead] = 180 - 1 - return caps + maxGasF: func() fees.Gas { + return testBlockMaxGas - 1 }, unsignedAndSignedTx: importTx, expectedError: errFailedComplexityCumulation, @@ -638,17 +609,15 @@ func TestTxFees(t *testing.T) { 266, 1000, }, - fc.feeManager.GetCumulatedComplexity(), + fc.feeManager.GetGas(), ) }, }, { name: "ExportTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxComplexityF: func() fees.Dimensions { - caps := testBlockMaxComplexity - caps[fees.UTXORead] = 90 - 1 - return caps + maxGasF: func() fees.Gas { + return testBlockMaxGas - 1 }, unsignedAndSignedTx: exportTx, expectedError: errFailedComplexityCumulation, @@ -682,9 +651,9 @@ func TestTxFees(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - maxComplexity := testBlockMaxComplexity - if tt.maxComplexityF != nil { - maxComplexity = tt.maxComplexityF() + maxComplexity := testBlockMaxGas + if tt.maxGasF != nil { + maxComplexity = tt.maxGasF() } uTx, sTx := tt.unsignedAndSignedTx(t) @@ -693,7 +662,7 @@ func TestTxFees(t *testing.T) { if !upgrades.IsEActivated(tt.chainTime) { fc = NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) } else { - fc = NewDynamicCalculator(fees.NewManager(testFeeRates), maxComplexity) + fc = NewDynamicCalculator(fees.NewManager(testGasPrice), maxComplexity) } var creds []verify.Verifiable diff --git a/vms/platformvm/txs/fee/dynamic_config.go b/vms/platformvm/txs/fee/dynamic_config.go index 113f55b68bd7..64c3c9ca9aa1 100644 --- a/vms/platformvm/txs/fee/dynamic_config.go +++ b/vms/platformvm/txs/fee/dynamic_config.go @@ -6,6 +6,7 @@ package fee import ( "errors" "fmt" + "math" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/constants" @@ -18,14 +19,14 @@ var ( errDynamicFeeConfigNotAvailable = errors.New("dynamic fee config not available") eUpgradeDynamicFeesConfig = commonfees.DynamicFeesConfig{ - FeeRate: commonfees.Dimensions{ - 1 * units.NanoAvax, - 2 * units.NanoAvax, - 3 * units.NanoAvax, - 4 * units.NanoAvax, + GasPrice: commonfees.GasPrice(10 * units.NanoAvax), + FeeDimensionWeights: commonfees.Dimensions{ + 1000, + 1000, + 1000, + 1, }, - - BlockMaxComplexity: commonfees.Max, + TempBlockMaxGas: commonfees.Gas(math.MaxUint64), } customDynamicFeesConfig *commonfees.DynamicFeesConfig diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index c39b8cf8b7ff..466c7f350c1b 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -56,13 +56,8 @@ var ( } testStaticConfig = staticFeesConfigFromContext(testContext) - testFeeRates = commonfees.Dimensions{ - 1 * units.MicroAvax, - 2 * units.MicroAvax, - 3 * units.MicroAvax, - 4 * units.MicroAvax, - } - testBlockMaxComplexity = commonfees.Max + testGasPrice = commonfees.GasPrice(10 * units.MicroAvax) + testBlockMaxGas = commonfees.Gas(100_000) ) // These tests create a tx, then verify that utxos included in the tx are @@ -100,7 +95,7 @@ func TestBaseTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewBaseTx( outputsToMove, feeCalc, @@ -110,7 +105,7 @@ func TestBaseTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9930*units.MicroAvax, fee) @@ -204,14 +199,14 @@ func TestAddSubnetValidatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewAddSubnetValidatorTx(subnetValidator, feeCalc) require.NoError(err) tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9765*units.MicroAvax, fee) @@ -292,7 +287,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewRemoveSubnetValidatorTx( ids.GenerateTestNodeID(), subnetID, @@ -303,7 +298,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9741*units.MicroAvax, fee) @@ -394,7 +389,7 @@ func TestCreateChainTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewCreateChainTx( subnetID, genesisBytes, @@ -408,7 +403,7 @@ func TestCreateChainTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9808*units.MicroAvax, fee) @@ -496,7 +491,7 @@ func TestCreateSubnetTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewCreateSubnetTx( subnetOwner, feeCalc, @@ -506,7 +501,7 @@ func TestCreateSubnetTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9644*units.MicroAvax, fee) @@ -590,7 +585,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewTransferSubnetOwnershipTx( subnetID, subnetOwner, @@ -601,7 +596,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9761*units.MicroAvax, fee) @@ -680,7 +675,7 @@ func TestImportTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewImportTx( sourceChainID, importTo, @@ -691,7 +686,7 @@ func TestImportTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(14251*units.MicroAvax, fee) @@ -770,7 +765,7 @@ func TestExportTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewExportTx( subnetID, exportedOutputs, @@ -781,7 +776,7 @@ func TestExportTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(9966*units.MicroAvax, fee) @@ -872,7 +867,7 @@ func TestTransformSubnetTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewTransformSubnetTx( subnetID, subnetAssetID, @@ -895,7 +890,7 @@ func TestTransformSubnetTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(14763*units.MicroAvax, fee) @@ -994,7 +989,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { require.NoError(err) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1016,7 +1011,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(20404*units.MicroAvax, fee) @@ -1113,7 +1108,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewAddPermissionlessDelegatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1132,7 +1127,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testFeeRates), testBlockMaxComplexity) + fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(20212*units.MicroAvax, fee) diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index be63498bc766..e2e4ff347a0b 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -291,9 +291,10 @@ type wallet struct { signer walletsigner.Signer client platformvm.Client - isEForkActive bool - staticFeesConfig fee.StaticConfig - feeRates, blockMaxComplexity commonfees.Dimensions + isEForkActive bool + staticFeesConfig fee.StaticConfig + gasPrice commonfees.GasPrice + maxComplexity commonfees.Gas } func (w *wallet) Builder() builder.Builder { @@ -633,8 +634,8 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( feeCalculator = fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Config{}, time.Time{}) } else { feeCfg, _ := fee.GetDynamicConfig(w.isEForkActive) - feeMan := commonfees.NewManager(w.feeRates) - feeCalculator = fee.NewDynamicCalculator(feeMan, feeCfg.BlockMaxComplexity) + feeMan := commonfees.NewManager(w.gasPrice) + feeCalculator = fee.NewDynamicCalculator(feeMan, feeCfg.TempBlockMaxGas) } return feeCalculator, nil } @@ -664,8 +665,8 @@ func (w *wallet) refreshFeesData(ctx *builder.Context, options ...common.Option) return nil // nothing else to update } feeCfg, _ := fee.GetDynamicConfig(w.isEForkActive) - w.feeRates = feeCfg.FeeRate - w.blockMaxComplexity = feeCfg.BlockMaxComplexity + w.gasPrice = feeCfg.GasPrice + w.maxComplexity = feeCfg.TempBlockMaxGas return nil } From 69e46c67c25502d0bdf754081b26e6673179bd04 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 12 Jun 2024 10:45:26 +0200 Subject: [PATCH 098/120] wip: fixing gas in UTs --- vms/components/fees/manager.go | 2 +- .../block/executor/verifier_test.go | 4 +- vms/platformvm/txs/fee/calculator_test.go | 167 ++++-------------- vms/platformvm/txs/fee/dynamic_config.go | 11 +- wallet/chain/p/builder_test.go | 22 +-- 5 files changed, 49 insertions(+), 157 deletions(-) diff --git a/vms/components/fees/manager.go b/vms/components/fees/manager.go index 59b3de4f0024..aad7ffbd6bfd 100644 --- a/vms/components/fees/manager.go +++ b/vms/components/fees/manager.go @@ -45,7 +45,7 @@ func (m *Manager) CalculateFee(g Gas) (uint64, error) { // If so, it returns the first dimension to breach bounds. func (m *Manager) CumulateComplexity(gas, bound Gas) error { // Ensure we can consume (don't want partial update of values) - consumed, err := safemath.Add64(uint64(m.gasPrice), uint64(gas)) + consumed, err := safemath.Add64(uint64(m.cumulatedGas), uint64(gas)) if err != nil { return fmt.Errorf("%w: %w", errGasBoundBreached, err) } diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index 068dbcfe172b..e9f13f8dc5c7 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -512,9 +512,9 @@ func TestStandardBlockComplexity(t *testing.T) { require.True(found) if dynamicFeesActive { - require.NotEqual(commonfees.Empty, blkState.blockGas) + require.NotEqual(commonfees.ZeroGas, blkState.blockGas) } else { - require.Equal(commonfees.Empty, blkState.blockGas) + require.Equal(commonfees.ZeroGas, blkState.blockGas) } }) } diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 8f04e37497fa..899c83ee0008 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -49,25 +49,26 @@ func TestAddAndRemoveFees(t *testing.T) { } var ( - units = fees.Dimensions{1, 2, 3, 4} - doubleUnits = fees.Dimensions{2, 4, 6, 8} + units = fees.Dimensions{1, 2, 3, 4} + gas = fees.Gas(10) + doubleGas = fees.Gas(20) ) feeDelta, err := fc.AddFeesFor(units) r.NoError(err) - r.Equal(units, fc.c.feeManager.GetGas()) + r.Equal(gas, fc.c.feeManager.GetGas()) r.NotZero(feeDelta) r.Equal(feeDelta, fc.c.fee) feeDelta2, err := fc.AddFeesFor(units) r.NoError(err) - r.Equal(doubleUnits, fc.c.feeManager.GetGas()) + r.Equal(doubleGas, fc.c.feeManager.GetGas()) r.Equal(feeDelta, feeDelta2) r.Equal(feeDelta+feeDelta2, fc.c.fee) feeDelta3, err := fc.RemoveFeesFor(units) r.NoError(err) - r.Equal(units, fc.c.feeManager.GetGas()) + r.Equal(gas, fc.c.feeManager.GetGas()) r.Equal(feeDelta, feeDelta3) r.Equal(feeDelta, fc.c.fee) @@ -136,16 +137,8 @@ func TestTxFees(t *testing.T) { expectedError: nil, unsignedAndSignedTx: addSubnetValidatorTx, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5345*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 649, - 90, - 172, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 19_110*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(1911), fc.feeManager.GetGas()) }, }, { @@ -188,16 +181,8 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: createChainTx, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5388*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 692, - 90, - 172, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 19_540*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(1_954), fc.feeManager.GetGas()) }, }, { @@ -232,16 +217,8 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: createSubnetTx, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5293*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 597, - 90, - 172, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 18_590*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(1_859), fc.feeManager.GetGas()) }, }, { @@ -268,16 +245,8 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: removeSubnetValidatorTx, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5321*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 625, - 90, - 172, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 18_870*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(1_887), fc.feeManager.GetGas()) }, }, { @@ -304,16 +273,8 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: transformSubnetTx, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5406*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 710, - 90, - 172, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 19_720*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(1_972), fc.feeManager.GetGas()) }, }, { @@ -340,16 +301,8 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: transferSubnetOwnershipTx, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5337*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 641, - 90, - 172, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 19_030*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(1_903), fc.feeManager.GetGas()) }, }, { @@ -392,16 +345,8 @@ func TestTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5939*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 961, - 90, - 266, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 23_170*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(2_317), fc.feeManager.GetGas()) }, }, { @@ -414,16 +359,8 @@ func TestTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5939*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 961, - 90, - 266, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 23_170*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(2_317), fc.feeManager.GetGas()) }, }, { @@ -469,16 +406,8 @@ func TestTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5747*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 769, - 90, - 266, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 21_250*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(2_125), fc.feeManager.GetGas()) }, }, { @@ -489,16 +418,8 @@ func TestTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5747*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 769, - 90, - 266, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 21_250*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(2_125), fc.feeManager.GetGas()) }, }, { @@ -529,16 +450,8 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: baseTx, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5253*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 557, - 90, - 172, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 18_190*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(1_819), fc.feeManager.GetGas()) }, }, { @@ -565,16 +478,8 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: importTx, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 9827*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 681, - 180, - 262, - 2000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 31_230*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(3_123), fc.feeManager.GetGas()) }, }, { @@ -601,16 +506,8 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: exportTx, expectedError: nil, checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 5663*units.MicroAvax, fc.fee) - require.Equal(t, - fees.Dimensions{ - 685, - 90, - 266, - 1000, - }, - fc.feeManager.GetGas(), - ) + require.Equal(t, 20_410*units.NanoAvax, fc.fee) + require.Equal(t, fees.Gas(2_041), fc.feeManager.GetGas()) }, }, { diff --git a/vms/platformvm/txs/fee/dynamic_config.go b/vms/platformvm/txs/fee/dynamic_config.go index 64c3c9ca9aa1..f16ce9b27d8f 100644 --- a/vms/platformvm/txs/fee/dynamic_config.go +++ b/vms/platformvm/txs/fee/dynamic_config.go @@ -19,14 +19,9 @@ var ( errDynamicFeeConfigNotAvailable = errors.New("dynamic fee config not available") eUpgradeDynamicFeesConfig = commonfees.DynamicFeesConfig{ - GasPrice: commonfees.GasPrice(10 * units.NanoAvax), - FeeDimensionWeights: commonfees.Dimensions{ - 1000, - 1000, - 1000, - 1, - }, - TempBlockMaxGas: commonfees.Gas(math.MaxUint64), + GasPrice: commonfees.GasPrice(10 * units.NanoAvax), + FeeDimensionWeights: commonfees.Dimensions{1, 1, 1, 1}, + TempBlockMaxGas: commonfees.Gas(math.MaxUint64), } customDynamicFeesConfig *commonfees.DynamicFeesConfig diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 466c7f350c1b..ca8855148d6b 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -108,7 +108,7 @@ func TestBaseTx(t *testing.T) { fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(9930*units.MicroAvax, fee) + require.Equal(30_620*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -209,7 +209,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(9765*units.MicroAvax, fee) + require.Equal(30_610*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -301,7 +301,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(9741*units.MicroAvax, fee) + require.Equal(30_370*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -406,7 +406,7 @@ func TestCreateChainTx(t *testing.T) { fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(9808*units.MicroAvax, fee) + require.Equal(31_040*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -504,7 +504,7 @@ func TestCreateSubnetTx(t *testing.T) { fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(9644*units.MicroAvax, fee) + require.Equal(29_400*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -599,7 +599,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(9761*units.MicroAvax, fee) + require.Equal(30_570*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -689,7 +689,7 @@ func TestImportTx(t *testing.T) { fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(14251*units.MicroAvax, fee) + require.Equal(42_770*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -779,7 +779,7 @@ func TestExportTx(t *testing.T) { fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(9966*units.MicroAvax, fee) + require.Equal(30_980*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -893,7 +893,7 @@ func TestTransformSubnetTx(t *testing.T) { fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(14763*units.MicroAvax, fee) + require.Equal(46_250*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -1014,7 +1014,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(20404*units.MicroAvax, fee) + require.Equal(65_240*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -1130,7 +1130,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(20212*units.MicroAvax, fee) + require.Equal(63_320*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins From c398294609c174b3eee79fe0a43d0b11695d5014 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 12 Jun 2024 16:34:51 +0200 Subject: [PATCH 099/120] nit --- vms/platformvm/txs/fee/calculator.go | 3 +-- vms/platformvm/txs/fee/calculator_test.go | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 1edc2a8df934..d2efc7610035 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -22,8 +22,7 @@ import ( var ( _ txs.Visitor = (*calculator)(nil) - errFailedFeeCalculation = errors.New("failed fee calculation") - errFailedComplexityCumulation = errors.New("failed cumulating complexity") + errFailedFeeCalculation = errors.New("failed fee calculation") ) func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config, chainTime time.Time) *Calculator { diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 899c83ee0008..ac5c150482c5 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -4,6 +4,7 @@ package fee import ( + "errors" "testing" "time" @@ -35,6 +36,8 @@ var ( preFundedKeys = secp256k1.TestKeys() feeTestSigners = [][]*secp256k1.PrivateKey{preFundedKeys} feeTestDefaultStakeWeight = uint64(2024) + + errFailedComplexityCumulation = errors.New("failed cumulating complexity") ) func TestAddAndRemoveFees(t *testing.T) { From b0edb2ae3167f3e56a01a879891dbf625188579f Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 12 Jun 2024 16:34:51 +0200 Subject: [PATCH 100/120] nit --- vms/platformvm/txs/fee/calculator.go | 9 ++++++--- vms/platformvm/txs/fee/calculator_test.go | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 1edc2a8df934..0c85df173c69 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -22,11 +22,14 @@ import ( var ( _ txs.Visitor = (*calculator)(nil) - errFailedFeeCalculation = errors.New("failed fee calculation") - errFailedComplexityCumulation = errors.New("failed cumulating complexity") + errFailedFeeCalculation = errors.New("failed fee calculation") ) -func NewStaticCalculator(config StaticConfig, upgradeTimes upgrade.Config, chainTime time.Time) *Calculator { +func NewStaticCalculator( + config StaticConfig, + upgradeTimes upgrade.Config, + chainTime time.Time, +) *Calculator { return &Calculator{ c: &calculator{ upgrades: upgradeTimes, diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 899c83ee0008..ac5c150482c5 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -4,6 +4,7 @@ package fee import ( + "errors" "testing" "time" @@ -35,6 +36,8 @@ var ( preFundedKeys = secp256k1.TestKeys() feeTestSigners = [][]*secp256k1.PrivateKey{preFundedKeys} feeTestDefaultStakeWeight = uint64(2024) + + errFailedComplexityCumulation = errors.New("failed cumulating complexity") ) func TestAddAndRemoveFees(t *testing.T) { From 48f5e5afdbf75e606c32309007a0e6cdba09f9f5 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 12 Jun 2024 17:24:39 +0200 Subject: [PATCH 101/120] nit --- vms/components/fees/dimensions.go | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/vms/components/fees/dimensions.go b/vms/components/fees/dimensions.go index dafa38a0f776..e8e3f0922838 100644 --- a/vms/components/fees/dimensions.go +++ b/vms/components/fees/dimensions.go @@ -5,7 +5,6 @@ package fees import ( "errors" - "math" safemath "github.com/ava-labs/avalanchego/utils/math" ) @@ -28,14 +27,7 @@ var ( errUnknownDimension = errors.New("unknown dimension") ZeroGas = Gas(0) - - Empty = Dimensions{} - Max = Dimensions{ - math.MaxUint64, - math.MaxUint64, - math.MaxUint64, - math.MaxUint64, - } + Empty = Dimensions{} DimensionStrings = []string{ bandwidthString, @@ -46,11 +38,10 @@ var ( ) type ( - Dimension int - GasPrice uint64 Gas uint64 + Dimension int Dimensions [FeeDimensions]uint64 ) From ec918b3f5b7b0626de88956d107fb330f7403503 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 14 Jun 2024 12:16:51 +0200 Subject: [PATCH 102/120] repackaged some txexecutor functions to state package --- vms/platformvm/block/builder/builder.go | 7 +- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/block/executor/manager.go | 5 +- .../block/executor/proposal_block_test.go | 2 +- vms/platformvm/block/executor/verifier.go | 7 +- .../block/executor/verifier_test.go | 4 +- vms/platformvm/config/config.go | 19 ---- vms/platformvm/service_test.go | 3 +- vms/platformvm/state/block_helpers.go | 91 +++++++++++++++++++ .../txs/executor/advance_time_test.go | 21 ++--- .../txs/executor/create_chain_test.go | 7 +- .../txs/executor/create_subnet_test.go | 3 +- vms/platformvm/txs/executor/import_test.go | 3 +- .../txs/executor/proposal_tx_executor.go | 2 +- .../txs/executor/proposal_tx_executor_test.go | 33 ++++--- .../txs/executor/reward_validator_test.go | 13 ++- .../staker_tx_verification_helpers.go | 34 ------- .../executor/staker_tx_verification_test.go | 6 +- .../txs/executor/standard_tx_executor_test.go | 68 +++++++------- vms/platformvm/txs/executor/state_changes.go | 25 ----- vms/platformvm/txs/txstest/builder.go | 2 +- vms/platformvm/vm_test.go | 5 +- 23 files changed, 184 insertions(+), 180 deletions(-) create mode 100644 vms/platformvm/state/block_helpers.go diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 4afc4c7064ec..259b0b6422cc 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -19,7 +19,6 @@ import ( "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/block" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -172,7 +171,7 @@ func (b *builder) durationToSleep() (time.Duration, error) { return 0, fmt.Errorf("%w: %s", errMissingPreferredState, preferredID) } - nextStakerChangeTime, err := txexecutor.GetNextStakerChangeTime(preferredState) + nextStakerChangeTime, err := state.GetNextStakerChangeTime(preferredState) if err != nil { return 0, fmt.Errorf("%w of %s: %w", errCalculatingNextStakerTime, preferredID, err) } @@ -217,7 +216,7 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { return nil, fmt.Errorf("%w: %s", state.ErrMissingParentState, preferredID) } - timestamp, timeWasCapped, err := txexecutor.NextBlockTime(preferredState, b.txExecutorBackend.Clk) + timestamp, timeWasCapped, err := state.NextBlockTime(preferredState, b.txExecutorBackend.Clk) if err != nil { return nil, fmt.Errorf("could not calculate next staker change time: %w", err) } @@ -335,7 +334,7 @@ func packBlockTxs( var ( blockTxs []*txs.Tx inputs set.Set[ids.ID] - feeCalculator = config.PickFeeCalculator(backend.Config, timestamp) + feeCalculator = state.PickFeeCalculator(backend.Config, timestamp) ) for { diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 24da4ffef822..7ce806474c60 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -260,7 +260,7 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(genesisID, env.blkManager) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, 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 7931908eb932..b18ede7a43d6 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -302,7 +302,7 @@ func addSubnet(env *environment) { panic(err) } - feeCalculator := config.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, 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 633d6191780e..1c2f8dffdc14 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -10,7 +10,6 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/block" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -133,7 +132,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - nextBlkTime, _, err := executor.NextBlockTime(stateDiff, m.txExecutorBackend.Clk) + nextBlkTime, _, err := state.NextBlockTime(stateDiff, m.txExecutorBackend.Clk) if err != nil { return err } @@ -143,7 +142,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - feeCalculator := config.PickFeeCalculator(m.txExecutorBackend.Config, nextBlkTime) + feeCalculator := state.PickFeeCalculator(m.txExecutorBackend.Config, nextBlkTime) return tx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: m.txExecutorBackend, State: stateDiff, diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 85427f0d484b..5c056a69a3d9 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -1451,7 +1451,7 @@ func TestAddValidatorProposalBlock(t *testing.T) { // Advance time until next staker change time is [validatorEndTime] for { - nextStakerChangeTime, err := executor.GetNextStakerChangeTime(env.state) + nextStakerChangeTime, err := state.GetNextStakerChangeTime(env.state) require.NoError(err) if nextStakerChangeTime.Equal(validatorEndTime) { break diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index bd7bb5c4a4f4..7bbed416b6f9 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -12,7 +12,6 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -69,7 +68,7 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { return err } - feeCalculator := config.PickFeeCalculator(v.txExecutorBackend.Config, b.Timestamp()) + feeCalculator := state.PickFeeCalculator(v.txExecutorBackend.Config, b.Timestamp()) inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, feeCalculator, onDecisionState, b.Parent()) if err != nil { return err @@ -124,7 +123,7 @@ func (v *verifier) BanffStandardBlock(b *block.BanffStandardBlock) error { return errBanffStandardBlockWithoutChanges } - feeCalculator := config.PickFeeCalculator(v.txExecutorBackend.Config, b.Timestamp()) + feeCalculator := state.PickFeeCalculator(v.txExecutorBackend.Config, b.Timestamp()) return v.standardBlock(&b.ApricotStandardBlock, feeCalculator, onAcceptState) } @@ -285,7 +284,7 @@ func (v *verifier) banffNonOptionBlock(b block.BanffBlock) error { ) } - nextStakerChangeTime, err := executor.GetNextStakerChangeTime(parentState) + nextStakerChangeTime, err := state.GetNextStakerChangeTime(parentState) if err != nil { return fmt.Errorf("could not verify block timestamp: %w", err) } diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index e9f13f8dc5c7..392099a3a635 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -274,7 +274,7 @@ func TestStandardBlockComplexity(t *testing.T) { onAcceptState, err := state.NewDiffOn(env.state) require.NoError(t, err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) require.NoError(t, subnetValTx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: env.backend, State: onAcceptState, @@ -489,7 +489,7 @@ func TestStandardBlockComplexity(t *testing.T) { tx := tt.setupTest(env) - nextBlkTime, _, err := executor.NextBlockTime(env.state, env.clk) + nextBlkTime, _, err := state.NextBlockTime(env.state, env.clk) require.NoError(err) parentBlkID := env.state.GetLastAccepted() diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index f63814d66286..731b079ca425 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -16,8 +16,6 @@ import ( "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" - - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) // Struct collecting all foundational parameters of PlatformVM @@ -104,20 +102,3 @@ func (c *Config) CreateChain(chainID ids.ID, tx *txs.CreateChainTx) { c.Chains.QueueChainCreation(chainParams) } - -// helper to create either a static or a dynamic fee calculator, depending on the active upgrade -func PickFeeCalculator(cfg *Config, time time.Time) *fee.Calculator { - var ( - isEActive = cfg.UpgradeConfig.IsEActivated(time) - feeCalculator *fee.Calculator - ) - - if !isEActive { - feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, time) - } else { - feesCfg, _ := fee.GetDynamicConfig(isEActive) - feesMan := commonfees.NewManager(feesCfg.GasPrice) - feeCalculator = fee.NewDynamicCalculator(feesMan, feesCfg.TempBlockMaxGas) - } - return feeCalculator -} diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 4bccbc0899bb..3336b47e5665 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -34,7 +34,6 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/block" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" @@ -395,7 +394,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 - feeCalc := config.PickFeeCalculator(&service.vm.Config, service.vm.state.GetTimestamp()) + feeCalc := state.PickFeeCalculator(&service.vm.Config, service.vm.state.GetTimestamp()) fee, err := feeCalc.ComputeFee(testSubnet1.Unsigned, testSubnet1.Creds) require.NoError(err) balance = defaultBalance - fee diff --git a/vms/platformvm/state/block_helpers.go b/vms/platformvm/state/block_helpers.go new file mode 100644 index 000000000000..e4074da28197 --- /dev/null +++ b/vms/platformvm/state/block_helpers.go @@ -0,0 +1,91 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package state + +import ( + "fmt" + "time" + + "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" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" +) + +func NextBlockTime(state Chain, clk *mockable.Clock) (time.Time, bool, error) { + var ( + timestamp = clk.Time() + parentTime = state.GetTimestamp() + ) + if parentTime.After(timestamp) { + timestamp = parentTime + } + // [timestamp] = max(now, parentTime) + + nextStakerChangeTime, err := GetNextStakerChangeTime(state) + if err != nil { + return time.Time{}, false, fmt.Errorf("failed getting next staker change time: %w", err) + } + + // timeWasCapped means that [timestamp] was reduced to [nextStakerChangeTime] + timeWasCapped := !timestamp.Before(nextStakerChangeTime) + if timeWasCapped { + timestamp = nextStakerChangeTime + } + // [timestamp] = min(max(now, parentTime), nextStakerChangeTime) + return timestamp, timeWasCapped, nil +} + +// GetNextStakerChangeTime returns the next time a staker will be either added +// or removed to/from the current validator set. +func GetNextStakerChangeTime(state Chain) (time.Time, error) { + currentStakerIterator, err := state.GetCurrentStakerIterator() + if err != nil { + return time.Time{}, err + } + defer currentStakerIterator.Release() + + pendingStakerIterator, err := state.GetPendingStakerIterator() + if err != nil { + return time.Time{}, err + } + defer pendingStakerIterator.Release() + + hasCurrentStaker := currentStakerIterator.Next() + hasPendingStaker := pendingStakerIterator.Next() + switch { + case hasCurrentStaker && hasPendingStaker: + nextCurrentTime := currentStakerIterator.Value().NextTime + nextPendingTime := pendingStakerIterator.Value().NextTime + if nextCurrentTime.Before(nextPendingTime) { + return nextCurrentTime, nil + } + return nextPendingTime, nil + case hasCurrentStaker: + return currentStakerIterator.Value().NextTime, nil + case hasPendingStaker: + return pendingStakerIterator.Value().NextTime, nil + default: + return time.Time{}, database.ErrNotFound + } +} + +// [PickFeeCalculator] creates either a static or a dynamic fee calculator, depending on the active upgrade +func PickFeeCalculator(cfg *config.Config, time time.Time) *fee.Calculator { + var ( + isEActive = cfg.UpgradeConfig.IsEActivated(time) + feeCalculator *fee.Calculator + ) + + if !isEActive { + feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, time) + } else { + feesCfg, _ := fee.GetDynamicConfig(isEActive) + feesMan := commonfees.NewManager(feesCfg.GasPrice) + feeCalculator = fee.NewDynamicCalculator(feesMan, feesCfg.TempBlockMaxGas) + } + return feeCalculator +} diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index e94f8a6419fa..e608f0d2ed0b 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -16,7 +16,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/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" @@ -67,7 +66,7 @@ func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -115,7 +114,7 @@ func TestAdvanceTimeTxTimestampTooEarly(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -152,7 +151,7 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -183,7 +182,7 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -428,7 +427,7 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -566,7 +565,7 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -648,7 +647,7 @@ func TestTrackedSubnet(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -698,7 +697,7 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -803,7 +802,7 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -904,7 +903,7 @@ func TestAdvanceTimeTxAfterBanff(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) 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 531cfb30d55d..087e152b5b4d 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" - "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/txstest" @@ -131,7 +130,7 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -165,7 +164,7 @@ func TestCreateChainTxValid(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -238,7 +237,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCalculator := config.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, 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 07b4a1fb3996..7016796501ce 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -13,7 +13,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" @@ -82,7 +81,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCalculator := config.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, stateDiff.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 ae23a8f0e5d2..d6a99c73d3cb 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -16,7 +16,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/components/avax" - "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/secp256k1fx" @@ -162,7 +161,7 @@ func TestNewImportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) - feeCalculator := config.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) verifier := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, diff --git a/vms/platformvm/txs/executor/proposal_tx_executor.go b/vms/platformvm/txs/executor/proposal_tx_executor.go index b5f195ef5d24..b62b8e059f20 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor.go @@ -274,7 +274,7 @@ func (e *ProposalTxExecutor) AdvanceTimeTx(tx *txs.AdvanceTimeTx) error { // Only allow timestamp to move forward as far as the time of next staker // set change time - nextStakerChangeTime, err := GetNextStakerChangeTime(e.OnCommitState) + nextStakerChangeTime, err := state.GetNextStakerChangeTime(e.OnCommitState) if err != nil { return err } diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index de6e4edbd0a5..c0166c47e4bb 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -15,7 +15,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/hashing" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" @@ -275,7 +274,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -323,7 +322,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -363,7 +362,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -424,7 +423,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -479,7 +478,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -517,7 +516,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -555,7 +554,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -595,7 +594,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -668,7 +667,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -716,7 +715,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -758,7 +757,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -810,7 +809,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -859,7 +858,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -900,7 +899,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -955,7 +954,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -1002,7 +1001,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, 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 6a0e29a76c19..13688149e651 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/set" "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/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" @@ -62,7 +61,7 @@ func TestRewardValidatorTxExecuteOnCommit(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAbortState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAbortState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -166,7 +165,7 @@ func TestRewardValidatorTxExecuteOnAbort(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAbortState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAbortState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -328,7 +327,7 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -475,7 +474,7 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -703,7 +702,7 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * delOnAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, delOnCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, delOnCommitState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: delOnCommitState, OnAbortState: delOnAbortState, @@ -870,7 +869,7 @@ func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, diff --git a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go index 3a74cea28696..eb18c6609299 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go @@ -94,40 +94,6 @@ func getDelegatorRules( }, nil } -// GetNextStakerChangeTime returns the next time a staker will be either added -// or removed to/from the current validator set. -func GetNextStakerChangeTime(state state.Chain) (time.Time, error) { - currentStakerIterator, err := state.GetCurrentStakerIterator() - if err != nil { - return time.Time{}, err - } - defer currentStakerIterator.Release() - - pendingStakerIterator, err := state.GetPendingStakerIterator() - if err != nil { - return time.Time{}, err - } - defer pendingStakerIterator.Release() - - hasCurrentStaker := currentStakerIterator.Next() - hasPendingStaker := pendingStakerIterator.Next() - switch { - case hasCurrentStaker && hasPendingStaker: - nextCurrentTime := currentStakerIterator.Value().NextTime - nextPendingTime := pendingStakerIterator.Value().NextTime - if nextCurrentTime.Before(nextPendingTime) { - return nextCurrentTime, nil - } - return nextPendingTime, nil - case hasCurrentStaker: - return currentStakerIterator.Value().NextTime, nil - case hasPendingStaker: - return pendingStakerIterator.Value().NextTime, nil - default: - return time.Time{}, database.ErrNotFound - } -} - // GetValidator returns information about the given validator, which may be a // current validator or pending validator. func GetValidator(state state.Chain, subnetID ids.ID, nodeID ids.NodeID) (*state.Staker, error) { diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index 417f3bc79302..e0191ded789b 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -508,13 +508,13 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { var ( backend = tt.backendF(ctrl) - state = tt.stateF(ctrl) + chain = tt.stateF(ctrl) sTx = tt.sTxF() tx = tt.txF() - feeCalculator = config.PickFeeCalculator(backend.Config, state.GetTimestamp()) + feeCalculator = state.PickFeeCalculator(backend.Config, chain.GetTimestamp()) ) - err := verifyAddPermissionlessValidatorTx(backend, feeCalculator, state, sTx, tx) + 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 7229724a318e..6970bc9b9d78 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -99,7 +99,7 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: stateDiff, @@ -360,7 +360,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { env.config.UpgradeConfig.BanffTime = onAcceptState.GetTimestamp() - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -406,7 +406,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -442,7 +442,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -499,7 +499,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -550,7 +550,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -584,7 +584,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -618,7 +618,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -654,7 +654,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -724,7 +724,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -769,7 +769,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -810,7 +810,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -849,7 +849,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -898,7 +898,7 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -942,7 +942,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -990,7 +990,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutCurrentValidator(staker) onAcceptState.AddTx(tx, status.Committed) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1035,7 +1035,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutPendingValidator(staker) onAcceptState.AddTx(tx, status.Committed) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1079,7 +1079,7 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.DeleteUTXO(utxoID) } - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -1185,7 +1185,7 @@ func TestDurangoDisabledTransactions(t *testing.T) { tx := tt.buildTx(env) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) err = tx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1401,7 +1401,7 @@ func TestDurangoMemoField(t *testing.T) { onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - feeCalculator := config.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) require.NoError(t, subnetValTx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1609,7 +1609,7 @@ func TestDurangoMemoField(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - feeCalculator := config.PickFeeCalculator(env.config, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(env.config, env.state.GetTimestamp()) // Populated memo field should error tx, onAcceptState := tt.setupTest(env, []byte{'m', 'e', 'm', 'o'}) @@ -1757,7 +1757,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1784,7 +1784,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := config.PickFeeCalculator(cfg, env.latestForkTime) + feeCalculator := state.PickFeeCalculator(cfg, env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1812,7 +1812,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetPendingValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1843,7 +1843,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(&staker, nil).Times(1) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1872,7 +1872,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1900,7 +1900,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1930,7 +1930,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) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1963,7 +1963,7 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { ).Return(errTest) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2120,7 +2120,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state = state.NewMockDiff(ctrl) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := config.PickFeeCalculator(cfg, env.latestForkTime) + feeCalculator := state.PickFeeCalculator(cfg, env.latestForkTime) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2147,7 +2147,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).Times(2) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2177,7 +2177,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2212,7 +2212,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2252,7 +2252,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := config.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, diff --git a/vms/platformvm/txs/executor/state_changes.go b/vms/platformvm/txs/executor/state_changes.go index 36981b095e8c..3086358304a3 100644 --- a/vms/platformvm/txs/executor/state_changes.go +++ b/vms/platformvm/txs/executor/state_changes.go @@ -10,7 +10,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -58,30 +57,6 @@ func VerifyNewChainTime( return nil } -func NextBlockTime(state state.Chain, clk *mockable.Clock) (time.Time, bool, error) { - var ( - timestamp = clk.Time() - parentTime = state.GetTimestamp() - ) - if parentTime.After(timestamp) { - timestamp = parentTime - } - // [timestamp] = max(now, parentTime) - - nextStakerChangeTime, err := GetNextStakerChangeTime(state) - if err != nil { - return time.Time{}, false, fmt.Errorf("failed getting next staker change time: %w", err) - } - - // timeWasCapped means that [timestamp] was reduced to [nextStakerChangeTime] - timeWasCapped := !timestamp.Before(nextStakerChangeTime) - if timeWasCapped { - timestamp = nextStakerChangeTime - } - // [timestamp] = min(max(now, parentTime), nextStakerChangeTime) - return timestamp, timeWasCapped, nil -} - // AdvanceTimeTo applies all state changes to [parentState] resulting from // advancing the chain time to [newChainTime]. // Returns true iff the validator set changed. diff --git a/vms/platformvm/txs/txstest/builder.go b/vms/platformvm/txs/txstest/builder.go index d5deace09419..806b12517f99 100644 --- a/vms/platformvm/txs/txstest/builder.go +++ b/vms/platformvm/txs/txstest/builder.go @@ -45,5 +45,5 @@ func (w *WalletFactory) NewWallet(keys ...*secp256k1.PrivateKey) (builder.Builde func (w *WalletFactory) feeCalculator() *fee.Calculator { chainTime := w.state.GetTimestamp() - return config.PickFeeCalculator(w.cfg, chainTime) + return state.PickFeeCalculator(w.cfg, chainTime) } diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index d51654a6d7a4..da03aaabc664 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -55,6 +55,7 @@ import ( "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/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" @@ -397,7 +398,7 @@ func TestGenesis(t *testing.T) { // we use the first key to fund a subnet creation in [defaultGenesis]. // As such we need to account for the subnet creation fee - feeCalc := config.PickFeeCalculator(&vm.Config, vm.state.GetTimestamp()) + feeCalc := state.PickFeeCalculator(&vm.Config, vm.state.GetTimestamp()) fee, err := feeCalc.ComputeFee(testSubnet1.Unsigned, testSubnet1.Creds) require.NoError(err) require.Equal(uint64(utxo.Amount)-fee, out.Amount()) @@ -2422,7 +2423,7 @@ func TestBaseTx(t *testing.T) { } require.Equal(totalOutputAmt, key0OutputAmt+key1OutputAmt+changeAddrOutputAmt) - feeCalc = config.PickFeeCalculator(&vm.Config, vm.state.GetTimestamp()) + feeCalc = state.PickFeeCalculator(&vm.Config, vm.state.GetTimestamp()) fee, err := feeCalc.ComputeFee(baseTx.Unsigned, baseTx.Creds) require.NoError(err) require.Equal(fee, totalInputAmt-totalOutputAmt) From bb4c5918f528bd899d95420f9b288888c122e749 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 14 Jun 2024 16:40:55 +0200 Subject: [PATCH 103/120] wip: introducing leaky bucket for blocks gas --- tests/e2e/p/workflow.go | 2 +- vms/components/fees/config.go | 26 +- vms/platformvm/block/builder/builder.go | 11 +- vms/platformvm/block/builder/builder_test.go | 18 +- vms/platformvm/block/builder/helpers_test.go | 10 +- .../block/builder/standard_block_test.go | 4 +- vms/platformvm/block/executor/helpers_test.go | 19 +- vms/platformvm/block/executor/manager.go | 8 +- .../block/executor/proposal_block_test.go | 39 ++- .../block/executor/standard_block_test.go | 15 +- vms/platformvm/block/executor/verifier.go | 46 +++- .../block/executor/verifier_test.go | 53 ++-- vms/platformvm/service_test.go | 149 +++++++---- vms/platformvm/state/block_helpers.go | 25 +- vms/platformvm/state/diff.go | 32 +++ vms/platformvm/state/mock_state.go | 82 ++++++ vms/platformvm/state/state.go | 52 ++++ .../txs/executor/advance_time_test.go | 64 +++-- .../txs/executor/create_chain_test.go | 55 +++- .../txs/executor/create_subnet_test.go | 10 +- vms/platformvm/txs/executor/export_test.go | 4 +- vms/platformvm/txs/executor/helpers_test.go | 6 +- vms/platformvm/txs/executor/import_test.go | 8 +- .../txs/executor/proposal_tx_executor_test.go | 123 ++++++--- .../txs/executor/reward_validator_test.go | 32 ++- .../executor/staker_tx_verification_test.go | 45 ++-- .../txs/executor/standard_tx_executor_test.go | 238 ++++++++++++------ vms/platformvm/txs/fee/dynamic_config.go | 15 +- vms/platformvm/txs/txstest/builder.go | 31 ++- vms/platformvm/validator_set_property_test.go | 24 +- vms/platformvm/vm_regression_test.go | 83 ++++-- vms/platformvm/vm_test.go | 80 ++++-- wallet/chain/p/wallet.go | 5 +- 33 files changed, 1062 insertions(+), 352 deletions(-) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 3e4643c4c14c..ec00a575370f 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -159,7 +159,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { feeCfg, err := fee.GetDynamicConfig(true /*isEActive*/) require.NoError(err) - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(feeCfg.GasPrice), feeCfg.TempBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(feeCfg.GasPrice), fee.TempGasCap) pChainExportFee, err = feeCalc.ComputeFee(tx.Unsigned, tx.Creds) require.NoError(err) }) diff --git a/vms/components/fees/config.go b/vms/components/fees/config.go index d141c033993d..ae34231cedb8 100644 --- a/vms/components/fees/config.go +++ b/vms/components/fees/config.go @@ -3,12 +3,34 @@ package fees +import "errors" + +var errZeroLeakGasCoeff = errors.New("zero leak gas coefficient") + type DynamicFeesConfig struct { GasPrice GasPrice `json:"gas-price"` // weights to merge fees dimensions complexities into a single gas value FeeDimensionWeights Dimensions `json:"fee-dimension-weights"` - // TODO ABENEGIA: replace with leaky bucket implementation - TempBlockMaxGas Gas + MaxGasPerSecond Gas + LeakGasCoeff Gas // TODO ABENEGIA: not sure of the unit of measurement here +} + +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 +// MaxGas = min (MaxGas + MaxGasPerSecond/LeakGasCoeff*ElapsedTime, MaxGasPerSecond) +func MaxGas(cfg DynamicFeesConfig, currentGasCapacity Gas, elapsedTime uint64) Gas { + if elapsedTime > uint64(cfg.LeakGasCoeff) { + return cfg.MaxGasPerSecond + } + + return min(cfg.MaxGasPerSecond, currentGasCapacity+cfg.MaxGasPerSecond*Gas(elapsedTime)/cfg.LeakGasCoeff) } diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 259b0b6422cc..0fd6810f0320 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -331,12 +331,15 @@ func packBlockTxs( return nil, err } + feeCalculator, err := state.PickFeeCalculator(backend.Config, stateDiff, parentState.GetTimestamp()) + if err != nil { + return nil, err + } + var ( - blockTxs []*txs.Tx - inputs set.Set[ids.ID] - feeCalculator = state.PickFeeCalculator(backend.Config, timestamp) + blockTxs []*txs.Tx + inputs set.Set[ids.ID] ) - for { tx, exists := mempool.Peek() if !exists { diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 26928575cbb4..d914d73bde53 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -39,7 +39,8 @@ func TestBuildBlockBasic(t *testing.T) { defer env.ctx.Lock.Unlock() // Create a valid transaction - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewCreateChainTx( testSubnet1.ID(), nil, @@ -112,7 +113,8 @@ func TestBuildBlockShouldReward(t *testing.T) { require.NoError(err) // Create a valid [AddPermissionlessValidatorTx] - builder, txSigner, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, txSigner, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -253,7 +255,8 @@ func TestBuildBlockForceAdvanceTime(t *testing.T) { defer env.ctx.Lock.Unlock() // Create a valid transaction - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewCreateChainTx( testSubnet1.ID(), nil, @@ -323,7 +326,8 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { sk, err := bls.NewSecretKey() require.NoError(err) - builder1, signer1, feeCalc1 := env.factory.NewWallet(preFundedKeys[0]) + builder1, signer1, feeCalc1, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) utx1, err := builder1.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -365,7 +369,8 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { sk, err = bls.NewSecretKey() require.NoError(err) - builder2, signer2, feeCalc2 := env.factory.NewWallet(preFundedKeys[2]) + builder2, signer2, feeCalc2, err := env.factory.NewWallet(preFundedKeys[2]) + require.NoError(err) utx2, err := builder2.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -431,7 +436,8 @@ func TestPreviouslyDroppedTxsCannotBeReAddedToMempool(t *testing.T) { defer env.ctx.Lock.Unlock() // Create a valid transaction - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewCreateChainTx( testSubnet1.ID(), nil, diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 7ce806474c60..3b126b8748a0 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -153,7 +153,7 @@ func newEnvironment(t *testing.T, f fork) *environment { //nolint:unparam res.uptimes = uptime.NewManager(res.state, res.clk) res.utxosVerifier = utxo.NewVerifier(res.ctx, res.clk, res.fx) - res.factory = txstest.NewWalletFactory(res.ctx, res.config, res.state) + res.factory = txstest.NewWalletFactory(res.ctx, res.config, res.clk, res.state) genesisID := res.state.GetLastAccepted() res.backend = txexecutor.Backend{ @@ -236,7 +236,9 @@ func newEnvironment(t *testing.T, f fork) *environment { //nolint:unparam func addSubnet(t *testing.T, env *environment) { require := require.New(t) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) + utx, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{ Threshold: 2, @@ -260,7 +262,9 @@ func addSubnet(t *testing.T, env *environment) { stateDiff, err := state.NewDiff(genesisID, env.blkManager) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff, stateDiff.GetTimestamp()) + require.NoError(err) + executor := txexecutor.StandardTxExecutor{ Backend: &env.backend, State: stateDiff, diff --git a/vms/platformvm/block/builder/standard_block_test.go b/vms/platformvm/block/builder/standard_block_test.go index bfd800382ab1..193eedac6893 100644 --- a/vms/platformvm/block/builder/standard_block_test.go +++ b/vms/platformvm/block/builder/standard_block_test.go @@ -63,7 +63,9 @@ func TestAtomicTxImports(t *testing.T) { }}}, })) - builder, signer, feeCalc := env.factory.NewWallet(recipientKey) + builder, signer, feeCalc, err := env.factory.NewWallet(recipientKey) + require.NoError(err) + utx, err := builder.NewImportTx( env.ctx.XChainID, &secp256k1fx.OutputOwners{ diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index b18ede7a43d6..b36f49443439 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -182,6 +182,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment res.factory = txstest.NewWalletFactory( res.ctx, res.config, + res.clk, res.state, ) } else { @@ -192,6 +193,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment res.factory = txstest.NewWalletFactory( res.ctx, res.config, + res.clk, res.mockedState, ) @@ -272,7 +274,11 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment } func addSubnet(env *environment) { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + if err != nil { + panic(err) + } + utx, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{ Threshold: 2, @@ -301,8 +307,11 @@ func addSubnet(env *environment) { if err != nil { panic(err) } + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff, stateDiff.GetTimestamp()) + if err != nil { + panic(err) + } - feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) executor := executor.StandardTxExecutor{ Backend: env.backend, State: stateDiff, @@ -523,7 +532,11 @@ func addPendingValidator( rewardAddress ids.ShortID, keys []*secp256k1.PrivateKey, ) (*txs.Tx, error) { - builder, signer, feeCalc := env.factory.NewWallet(keys...) + builder, signer, feeCalc, err := env.factory.NewWallet(keys...) + if err != nil { + return nil, err + } + utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index 1c2f8dffdc14..f287f202cf89 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -132,6 +132,8 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } + parentBlkTime := stateDiff.GetTimestamp() + nextBlkTime, _, err := state.NextBlockTime(stateDiff, m.txExecutorBackend.Clk) if err != nil { return err @@ -142,7 +144,11 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - feeCalculator := state.PickFeeCalculator(m.txExecutorBackend.Config, nextBlkTime) + feeCalculator, err := state.PickFeeCalculator(m.txExecutorBackend.Config, stateDiff, parentBlkTime) + if err != nil { + return err + } + return tx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: m.txExecutorBackend, State: stateDiff, diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 5c056a69a3d9..c38bf27f2c09 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -29,6 +29,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -88,6 +89,7 @@ func TestApricotProposalBlockTimeVerification(t *testing.T) { // setup state to validate proposal block transaction onParentAccept.EXPECT().GetTimestamp().Return(chainTime).AnyTimes() + onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfees.Gas(1_000_000), nil) currentStakersIt := state.NewMockStakerIterator(ctrl) currentStakersIt.EXPECT().Next().Return(true) @@ -160,6 +162,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { onParentAccept := state.NewMockDiff(ctrl) onParentAccept.EXPECT().GetTimestamp().Return(parentTime).AnyTimes() + onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfees.Gas(1_000_000), nil).AnyTimes() onParentAccept.EXPECT().GetCurrentSupply(constants.PrimaryNetworkID).Return(uint64(1000), nil).AnyTimes() env.blkManager.(*manager).blkIDToState[parentID] = &blockState{ @@ -538,7 +541,8 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { env.config.TrackedSubnets.Add(subnetID) for _, staker := range test.stakers { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: staker.nodeID, @@ -573,7 +577,8 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { } for _, subStaker := range test.subnetStakers { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -611,7 +616,8 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { // add Staker0 (with the right end time) to state // so to allow proposalBlk issuance staker0.endTime = newTime - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: staker0.nodeID, @@ -722,7 +728,8 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { subnetValidatorNodeID := genesisNodeIDs[0] subnetVdr1StartTime := defaultValidateStartTime subnetVdr1EndTime := defaultValidateStartTime.Add(defaultMinStakingDuration) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -885,7 +892,8 @@ func TestBanffProposalBlockTrackedSubnet(t *testing.T) { subnetVdr1StartTime := defaultGenesisTime.Add(1 * time.Minute) subnetVdr1EndTime := defaultGenesisTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1011,7 +1019,8 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { // just to allow proposalBlk issuance (with a reward Tx) staker0StartTime := defaultGenesisTime staker0EndTime := pendingValidatorStartTime - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: ids.GenerateTestNodeID(), @@ -1083,7 +1092,8 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { pendingDelegatorStartTime := pendingValidatorStartTime.Add(1 * time.Second) pendingDelegatorEndTime := pendingDelegatorStartTime.Add(1 * time.Second) - builder, signer, feeCalc = env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + builder, signer, feeCalc, err = env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + require.NoError(err) uDelTx, err := builder.NewAddDelegatorTx( &txs.Validator{ NodeID: nodeID, @@ -1115,7 +1125,8 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { // add Staker0 (with the right end time) to state // so to allow proposalBlk issuance staker0EndTime = pendingDelegatorStartTime - builder, signer, feeCalc = env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err = env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err = builder.NewAddValidatorTx( &txs.Validator{ NodeID: ids.GenerateTestNodeID(), @@ -1211,7 +1222,8 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { // so to allow proposalBlk issuance staker0StartTime := defaultGenesisTime staker0EndTime := pendingValidatorStartTime - builder, txSigner, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, txSigner, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: ids.GenerateTestNodeID(), @@ -1282,7 +1294,8 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { // Add delegator pendingDelegatorStartTime := pendingValidatorStartTime.Add(1 * time.Second) pendingDelegatorEndTime := pendingDelegatorStartTime.Add(defaultMinStakingDuration) - builder, txSigner, feeCalc = env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + builder, txSigner, feeCalc, err = env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + require.NoError(err) uDelTx, err := builder.NewAddDelegatorTx( &txs.Validator{ NodeID: nodeID, @@ -1314,7 +1327,8 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { // add Staker0 (with the right end time) to state // so to allow proposalBlk issuance staker0EndTime = pendingDelegatorStartTime - builder, txSigner, feeCalc = env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, txSigner, feeCalc, err = env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err = builder.NewAddValidatorTx( &txs.Validator{ NodeID: ids.GenerateTestNodeID(), @@ -1399,7 +1413,8 @@ func TestAddValidatorProposalBlock(t *testing.T) { sk, err := bls.NewSecretKey() require.NoError(err) - builder, txSigner, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + builder, txSigner, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + require.NoError(err) utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ diff --git a/vms/platformvm/block/executor/standard_block_test.go b/vms/platformvm/block/executor/standard_block_test.go index 6c7353caa068..ad279a4e24b7 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -24,6 +24,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) @@ -57,6 +58,7 @@ func TestApricotStandardBlockTimeVerification(t *testing.T) { env.mockedState.EXPECT().GetLastAccepted().Return(parentID).AnyTimes() env.mockedState.EXPECT().GetTimestamp().Return(chainTime).AnyTimes() onParentAccept.EXPECT().GetTimestamp().Return(chainTime).AnyTimes() + onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfees.ZeroGas, nil).AnyTimes() // wrong height apricotChildBlk, err := block.NewApricotStandardBlock( @@ -150,6 +152,7 @@ func TestBanffStandardBlockTimeVerification(t *testing.T) { } utxoID := utxo.InputID() onParentAccept.EXPECT().GetUTXO(utxoID).Return(utxo, nil).AnyTimes() + onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfees.ZeroGas, nil).AnyTimes() // Create the tx utx := &txs.CreateSubnetTx{ @@ -510,7 +513,8 @@ func TestBanffStandardBlockUpdateStakers(t *testing.T) { } for _, staker := range test.subnetStakers { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -605,7 +609,8 @@ func TestBanffStandardBlockRemoveSubnetValidator(t *testing.T) { subnetValidatorNodeID := genesisNodeIDs[0] subnetVdr1StartTime := defaultValidateStartTime subnetVdr1EndTime := defaultValidateStartTime.Add(defaultMinStakingDuration) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -713,7 +718,8 @@ func TestBanffStandardBlockTrackedSubnet(t *testing.T) { subnetValidatorNodeID := genesisNodeIDs[0] subnetVdr1StartTime := defaultGenesisTime.Add(1 * time.Minute) subnetVdr1EndTime := defaultGenesisTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -809,7 +815,8 @@ func TestBanffStandardBlockDelegatorStakerWeight(t *testing.T) { pendingDelegatorStartTime := pendingValidatorStartTime.Add(1 * time.Second) pendingDelegatorEndTime := pendingDelegatorStartTime.Add(1 * time.Second) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + require.NoError(err) utx, err := builder.NewAddDelegatorTx( &txs.Validator{ NodeID: nodeID, diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 7bbed416b6f9..837fe73cd6a0 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -62,14 +62,26 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { return err } + // retrieve parent block time before moving time forward + parentBlkTime := onDecisionState.GetTimestamp() + // Advance the time to [nextChainTime]. nextChainTime := b.Timestamp() if _, err := executor.AdvanceTimeTo(v.txExecutorBackend, onDecisionState, nextChainTime); err != nil { return err } - feeCalculator := state.PickFeeCalculator(v.txExecutorBackend.Config, b.Timestamp()) - inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, feeCalculator, onDecisionState, b.Parent()) + feeCalculator, err := state.PickFeeCalculator(v.txExecutorBackend.Config, onDecisionState, parentBlkTime) + if err != nil { + return err + } + + inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs( + b.Transactions, + feeCalculator, + onDecisionState, + b.Parent(), + ) if err != nil { return err } @@ -107,6 +119,9 @@ func (v *verifier) BanffStandardBlock(b *block.BanffStandardBlock) error { return err } + // retrieve parent block time before moving time forward + parentBlkTime := onAcceptState.GetTimestamp() + // Advance the time to [b.Timestamp()]. changed, err := executor.AdvanceTimeTo( v.txExecutorBackend, @@ -123,7 +138,10 @@ func (v *verifier) BanffStandardBlock(b *block.BanffStandardBlock) error { return errBanffStandardBlockWithoutChanges } - feeCalculator := state.PickFeeCalculator(v.txExecutorBackend.Config, b.Timestamp()) + feeCalculator, err := state.PickFeeCalculator(v.txExecutorBackend.Config, onAcceptState, parentBlkTime) + if err != nil { + return err + } return v.standardBlock(&b.ApricotStandardBlock, feeCalculator, onAcceptState) } @@ -385,6 +403,11 @@ func (v *verifier) proposalBlock( atomicRequests map[ids.ID]*atomic.Requests, onAcceptFunc func(), ) error { + currentGasCap, err := onCommitState.GetCurrentGasCap() + if err != nil { + return err + } + txExecutor := executor.ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -399,6 +422,10 @@ func (v *verifier) proposalBlock( return err } + blkGas := feeCalculator.GetGas() + onCommitState.SetCurrentGasCap(currentGasCap + blkGas) + onAbortState.SetCurrentGasCap(currentGasCap + blkGas) + onCommitState.AddTx(b.Tx, status.Committed) onAbortState.AddTx(b.Tx, status.Aborted) @@ -421,7 +448,7 @@ func (v *verifier) proposalBlock( // never be modified by an Apricot Abort block and the timestamp will // always be the same as the Banff Proposal Block. timestamp: onAbortState.GetTimestamp(), - blockGas: feeCalculator.GetGas(), + blockGas: blkGas, atomicRequests: atomicRequests, } return nil @@ -433,6 +460,11 @@ func (v *verifier) standardBlock( feeCalculator *fee.Calculator, onAcceptState state.Diff, ) error { + currentGasCap, err := onAcceptState.GetCurrentGasCap() + if err != nil { + return err + } + inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, feeCalculator, onAcceptState, b.Parent()) if err != nil { return err @@ -441,6 +473,10 @@ func (v *verifier) standardBlock( v.Mempool.Remove(b.Transactions...) blkID := b.ID() + + blkGas := feeCalculator.GetGas() + onAcceptState.SetCurrentGasCap(currentGasCap + blkGas) + v.blkIDToState[blkID] = &blockState{ statelessBlock: b, @@ -448,7 +484,7 @@ func (v *verifier) standardBlock( onAcceptFunc: onAcceptFunc, timestamp: onAcceptState.GetTimestamp(), - blockGas: feeCalculator.GetGas(), + blockGas: blkGas, inputs: inputs, atomicRequests: atomicRequests, } diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index 392099a3a635..23c0180ba67f 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -40,9 +40,9 @@ import ( walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) -// Check that complexity of standard blocks is duly calculated once block is verified +// Check that gas consumed by a standard blocks is duly calculated once block is verified // Only transactions active post E upgrade are considered and tested pre and post E upgrade. -func TestStandardBlockComplexity(t *testing.T) { +func TestStandardBlockGas(t *testing.T) { type test struct { name string setupTest func(env *environment) *txs.Tx @@ -60,7 +60,8 @@ func TestStandardBlockComplexity(t *testing.T) { sk, err := bls.NewSecretKey() require.NoError(t, err) - builder, s, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, s, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -112,7 +113,8 @@ func TestStandardBlockComplexity(t *testing.T) { } it.Release() - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewAddPermissionlessDelegatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -158,7 +160,8 @@ func TestStandardBlockComplexity(t *testing.T) { } it.Release() - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -186,7 +189,8 @@ func TestStandardBlockComplexity(t *testing.T) { { name: "CreateChainTx", setupTest: func(env *environment) *txs.Tx { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewCreateChainTx( testSubnet1.TxID, []byte{}, // genesisData @@ -210,7 +214,8 @@ func TestStandardBlockComplexity(t *testing.T) { { name: "CreateSubnetTx", setupTest: func(env *environment) *txs.Tx { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{ Threshold: 1, @@ -248,7 +253,8 @@ func TestStandardBlockComplexity(t *testing.T) { endTime := primaryValidator.EndTime - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) uSubnetValTx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -274,7 +280,9 @@ func TestStandardBlockComplexity(t *testing.T) { onAcceptState, err := state.NewDiffOn(env.state) require.NoError(t, err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(t, err) + require.NoError(t, subnetValTx.Unsigned.Visit(&executor.StandardTxExecutor{ Backend: env.backend, State: onAcceptState, @@ -306,7 +314,8 @@ func TestStandardBlockComplexity(t *testing.T) { { name: "TransformSubnetTx", setupTest: func(env *environment) *txs.Tx { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewTransformSubnetTx( testSubnet1.TxID, // subnetID ids.GenerateTestID(), // assetID @@ -339,7 +348,8 @@ func TestStandardBlockComplexity(t *testing.T) { { name: "TransferSubnetOwnershipTx", setupTest: func(env *environment) *txs.Tx { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewTransferSubnetOwnershipTx( testSubnet1.TxID, &secp256k1fx.OutputOwners{ @@ -384,7 +394,8 @@ func TestStandardBlockComplexity(t *testing.T) { ) env.msm.SharedMemory = sharedMemory - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewImportTx( sourceChain, &secp256k1fx.OutputOwners{ @@ -412,7 +423,8 @@ func TestStandardBlockComplexity(t *testing.T) { { name: "ExportTx", setupTest: func(env *environment) *txs.Tx { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewExportTx( env.ctx.XChainID, []*avax.TransferableOutput{{ @@ -444,7 +456,8 @@ func TestStandardBlockComplexity(t *testing.T) { { name: "BaseTx", setupTest: func(env *environment) *txs.Tx { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewBaseTx( []*avax.TransferableOutput{ { @@ -533,6 +546,7 @@ func TestVerifierVisitProposalBlock(t *testing.T) { timestamp := time.Now() // One call for each of onCommitState and onAbortState. parentOnAcceptState.EXPECT().GetTimestamp().Return(timestamp).Times(2) + parentOnAcceptState.EXPECT().GetCurrentGasCap().Return(commonfees.Gas(1_000_000), nil) backend := &backend{ lastAccepted: parentID, @@ -785,8 +799,9 @@ func TestVerifierVisitStandardBlock(t *testing.T) { // Set expectations for dependencies. timestamp := time.Now() - parentState.EXPECT().GetTimestamp().Return(timestamp).Times(1) - parentStatelessBlk.EXPECT().Height().Return(uint64(1)).Times(1) + parentState.EXPECT().GetTimestamp().Return(timestamp) + parentState.EXPECT().GetCurrentGasCap().Return(commonfees.Gas(1_000_000), nil) + parentStatelessBlk.EXPECT().Height().Return(uint64(1)) mempool.EXPECT().Remove(apricotBlk.Txs()).Times(1) blk := manager.NewBlock(apricotBlk) @@ -1278,8 +1293,10 @@ func TestVerifierVisitStandardBlockWithDuplicateInputs(t *testing.T) { // Set expectations for dependencies. timestamp := time.Now() - parentStatelessBlk.EXPECT().Height().Return(uint64(1)).Times(1) - parentState.EXPECT().GetTimestamp().Return(timestamp).Times(1) + parentStatelessBlk.EXPECT().Height().Return(uint64(1)) + parentState.EXPECT().GetTimestamp().Return(timestamp) + parentState.EXPECT().GetCurrentGasCap().Return(commonfees.Gas(1_000_000), nil) + parentStatelessBlk.EXPECT().Parent().Return(grandParentID).Times(1) err = verifier.ApricotStandardBlock(blk) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 3336b47e5665..513b75bbf1b8 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -34,15 +34,18 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/block" + "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "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" avajson "github.com/ava-labs/avalanchego/utils/json" + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" vmkeystore "github.com/ava-labs/avalanchego/vms/components/keystore" pchainapi "github.com/ava-labs/avalanchego/vms/platformvm/api" blockbuilder "github.com/ava-labs/avalanchego/vms/platformvm/block/builder" @@ -75,8 +78,36 @@ var ( } ) -func defaultService(t *testing.T, f fork) (*Service, *mutableSharedMemory, *txstest.WalletFactory) { - vm, factory, _, mutableSharedMemory := defaultVM(t, f) +func testReplayFeeCalculator(cfg *config.Config, parentBlkTime time.Time, state state.Chain) (*fee.Calculator, error) { + var ( + childBlkTime = state.GetTimestamp() + isEActive = cfg.UpgradeConfig.IsEActivated(childBlkTime) + + feeCalculator *fee.Calculator + ) + + if !isEActive { + feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, childBlkTime) + } else { + feesCfg, err := fee.GetDynamicConfig(isEActive) + if err != nil { + return nil, fmt.Errorf("failed retrieving dynamic fees config: %w", err) + } + currentGasCap, err := state.GetCurrentGasCap() + if err != nil { + return nil, fmt.Errorf("failed retrieving gas cap: %w", err) + } + + elapsedTime := childBlkTime.Unix() - parentBlkTime.Unix() + maxGas := commonfees.MaxGas(feesCfg, currentGasCap, uint64(elapsedTime)) + feesMan := commonfees.NewManager(feesCfg.GasPrice) + feeCalculator = fee.NewDynamicCalculator(feesMan, maxGas) + } + return feeCalculator, nil +} + +func defaultService(t *testing.T) (*Service, *mutableSharedMemory, *txstest.WalletFactory) { + vm, factory, _, mutableSharedMemory := defaultVM(t, latestFork) return &Service{ vm: vm, @@ -90,7 +121,7 @@ func defaultService(t *testing.T, f fork) (*Service, *mutableSharedMemory, *txst func TestExportKey(t *testing.T) { require := require.New(t) - service, _, _ := defaultService(t, latestFork) + service, _, _ := defaultService(t) service.vm.ctx.Lock.Lock() ks := keystore.New(logging.NoLog{}, memdb.New()) @@ -120,7 +151,7 @@ func TestExportKey(t *testing.T) { // Test issuing a tx and accepted func TestGetTxStatus(t *testing.T) { require := require.New(t) - service, mutableSharedMemory, factory := defaultService(t, latestFork) + service, mutableSharedMemory, factory := defaultService(t) service.vm.ctx.Lock.Lock() recipientKey, err := secp256k1.NewPrivateKey() @@ -168,7 +199,9 @@ func TestGetTxStatus(t *testing.T) { mutableSharedMemory.SharedMemory = sm - builder, signer, feeCalc := factory.NewWallet(recipientKey) + builder, signer, feeCalc, err := factory.NewWallet(recipientKey) + require.NoError(err) + utx, err := builder.NewImportTx( service.vm.ctx.XChainID, &secp256k1fx.OutputOwners{ @@ -222,7 +255,9 @@ func TestGetTx(t *testing.T) { { "standard block", func(_ *Service, factory *txstest.WalletFactory) (*txs.Tx, error) { - builder, signer, feeCalc := factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(t, err) + utx, err := builder.NewCreateChainTx( testSubnet1.ID(), []byte{}, @@ -250,7 +285,9 @@ func TestGetTx(t *testing.T) { Addrs: []ids.ShortID{ids.GenerateTestShortID()}, } - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(t, err) + utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -279,7 +316,9 @@ func TestGetTx(t *testing.T) { { "atomic block", func(service *Service, factory *txstest.WalletFactory) (*txs.Tx, error) { - builder, signer, feeCalc := factory.NewWallet(keys[0]) + builder, signer, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(t, err) + utx, err := builder.NewExportTx( service.vm.ctx.XChainID, []*avax.TransferableOutput{{ @@ -313,7 +352,7 @@ func TestGetTx(t *testing.T) { ) t.Run(testName, func(t *testing.T) { require := require.New(t) - service, _, txBuilder := defaultService(t, latestFork) + service, _, txBuilder := defaultService(t) service.vm.ctx.Lock.Lock() tx, err := test.createTx(service, txBuilder) @@ -377,7 +416,7 @@ func TestGetTx(t *testing.T) { func TestGetBalance(t *testing.T) { require := require.New(t) - service, _, _ := defaultService(t, latestFork) + service, _, _ := defaultService(t) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) @@ -394,7 +433,8 @@ 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 - feeCalc := state.PickFeeCalculator(&service.vm.Config, service.vm.state.GetTimestamp()) + feeCalc, err := testReplayFeeCalculator(&service.vm.Config, defaultGenesisTime, service.vm.state) + require.NoError(err) fee, err := feeCalc.ComputeFee(testSubnet1.Unsigned, testSubnet1.Creds) require.NoError(err) balance = defaultBalance - fee @@ -408,7 +448,7 @@ func TestGetBalance(t *testing.T) { func TestGetStake(t *testing.T) { require := require.New(t) - service, _, factory := defaultService(t, durango) + service, _, factory := defaultService(t) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) @@ -480,14 +520,20 @@ func TestGetStake(t *testing.T) { delegatorNodeID := genesisNodeIDs[0] delegatorStartTime := defaultValidateStartTime delegatorEndTime := defaultGenesisTime.Add(defaultMinStakingDuration) - builder, signer, feeCalc := factory.NewWallet(keys[0]) - utx, err := builder.NewAddDelegatorTx( - &txs.Validator{ - NodeID: delegatorNodeID, - Start: uint64(delegatorStartTime.Unix()), - End: uint64(delegatorEndTime.Unix()), - Wght: stakeAmount, + builder, sign, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) + + utx, err := builder.NewAddPermissionlessDelegatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: delegatorNodeID, + Start: uint64(delegatorStartTime.Unix()), + End: uint64(delegatorEndTime.Unix()), + Wght: stakeAmount, + }, + Subnet: constants.PrimaryNetworkID, }, + service.vm.ctx.AVAXAssetID, &secp256k1fx.OutputOwners{ Threshold: 1, Addrs: []ids.ShortID{ids.GenerateTestShortID()}, @@ -499,10 +545,10 @@ func TestGetStake(t *testing.T) { }), ) require.NoError(err) - tx, err := walletsigner.SignUnsigned(context.Background(), signer, utx) + tx, err := walletsigner.SignUnsigned(context.Background(), sign, utx) require.NoError(err) - addDelTx := tx.Unsigned.(*txs.AddDelegatorTx) + addDelTx := tx.Unsigned.(*txs.AddPermissionlessDelegatorTx) staker, err := state.NewCurrentStaker( tx.ID(), addDelTx, @@ -542,15 +588,26 @@ func TestGetStake(t *testing.T) { // Make sure this works for pending stakers // Add a pending staker + sk, err := bls.NewSecretKey() + require.NoError(err) stakeAmount = service.vm.MinValidatorStake + 54321 pendingStakerNodeID := ids.GenerateTestNodeID() pendingStakerEndTime := uint64(defaultGenesisTime.Add(defaultMinStakingDuration).Unix()) - utx2, err := builder.NewAddValidatorTx( - &txs.Validator{ - NodeID: pendingStakerNodeID, - Start: uint64(defaultGenesisTime.Unix()), - End: pendingStakerEndTime, - Wght: stakeAmount, + utx2, err := builder.NewAddPermissionlessValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: pendingStakerNodeID, + Start: uint64(defaultGenesisTime.Unix()), + End: pendingStakerEndTime, + Wght: stakeAmount, + }, + Subnet: constants.PlatformChainID, + }, + signer.NewProofOfPossession(sk), + service.vm.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, }, &secp256k1fx.OutputOwners{ Threshold: 1, @@ -564,12 +621,12 @@ func TestGetStake(t *testing.T) { }), ) require.NoError(err) - tx, err = walletsigner.SignUnsigned(context.Background(), signer, utx2) + tx, err = walletsigner.SignUnsigned(context.Background(), sign, utx2) require.NoError(err) staker, err = state.NewPendingStaker( tx.ID(), - tx.Unsigned.(*txs.AddValidatorTx), + tx.Unsigned.(*txs.AddPermissionlessValidatorTx), ) require.NoError(err) @@ -599,7 +656,7 @@ func TestGetStake(t *testing.T) { func TestGetCurrentValidators(t *testing.T) { require := require.New(t) - service, _, factory := defaultService(t, durango) + service, _, factory := defaultService(t) genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) @@ -633,14 +690,20 @@ func TestGetCurrentValidators(t *testing.T) { service.vm.ctx.Lock.Lock() - builder, signer, feeCalc := factory.NewWallet(keys[0]) - utx, err := builder.NewAddDelegatorTx( - &txs.Validator{ - NodeID: validatorNodeID, - Start: uint64(delegatorStartTime.Unix()), - End: uint64(delegatorEndTime.Unix()), - Wght: stakeAmount, + builder, signer, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) + + utx, err := builder.NewAddPermissionlessDelegatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: validatorNodeID, + Start: uint64(delegatorStartTime.Unix()), + End: uint64(delegatorEndTime.Unix()), + Wght: stakeAmount, + }, + Subnet: constants.PrimaryNetworkID, }, + service.vm.ctx.AVAXAssetID, &secp256k1fx.OutputOwners{ Threshold: 1, Addrs: []ids.ShortID{ids.GenerateTestShortID()}, @@ -655,7 +718,7 @@ func TestGetCurrentValidators(t *testing.T) { delTx, err := walletsigner.SignUnsigned(context.Background(), signer, utx) require.NoError(err) - addDelTx := delTx.Unsigned.(*txs.AddDelegatorTx) + addDelTx := delTx.Unsigned.(*txs.AddPermissionlessDelegatorTx) staker, err := state.NewCurrentStaker( delTx.ID(), addDelTx, @@ -735,7 +798,7 @@ func TestGetCurrentValidators(t *testing.T) { func TestGetTimestamp(t *testing.T) { require := require.New(t) - service, _, _ := defaultService(t, latestFork) + service, _, _ := defaultService(t) reply := GetTimestampReply{} require.NoError(service.GetTimestamp(nil, nil, &reply)) @@ -771,12 +834,14 @@ func TestGetBlock(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { require := require.New(t) - service, _, factory := defaultService(t, latestFork) + service, _, factory := defaultService(t) service.vm.ctx.Lock.Lock() service.vm.StaticFeeConfig.CreateAssetTxFee = 100 * defaultTxFee - builder, signer, feeCalc := factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) + utx, err := builder.NewCreateChainTx( testSubnet1.ID(), []byte{}, @@ -1064,7 +1129,7 @@ func TestServiceGetBlockByHeight(t *testing.T) { func TestServiceGetSubnets(t *testing.T) { require := require.New(t) - service, _, _ := defaultService(t, latestFork) + service, _, _ := defaultService(t) testSubnet1ID := testSubnet1.ID() diff --git a/vms/platformvm/state/block_helpers.go b/vms/platformvm/state/block_helpers.go index e4074da28197..d4f43db7eea8 100644 --- a/vms/platformvm/state/block_helpers.go +++ b/vms/platformvm/state/block_helpers.go @@ -74,18 +74,31 @@ func GetNextStakerChangeTime(state Chain) (time.Time, error) { } // [PickFeeCalculator] creates either a static or a dynamic fee calculator, depending on the active upgrade -func PickFeeCalculator(cfg *config.Config, time time.Time) *fee.Calculator { +// [PickFeeCalculator] does not mnodify [state] +func PickFeeCalculator(cfg *config.Config, state Chain, parentBlkTime time.Time) (*fee.Calculator, error) { var ( - isEActive = cfg.UpgradeConfig.IsEActivated(time) + childBlkTime = state.GetTimestamp() + isEActive = cfg.UpgradeConfig.IsEActivated(childBlkTime) + feeCalculator *fee.Calculator ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, time) + feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, childBlkTime) } else { - feesCfg, _ := fee.GetDynamicConfig(isEActive) + feesCfg, err := fee.GetDynamicConfig(isEActive) + if err != nil { + return nil, fmt.Errorf("failed retrieving dynamic fees config: %w", err) + } + currentGasCap, err := state.GetCurrentGasCap() + if err != nil { + return nil, fmt.Errorf("failed retrieving gas cap: %w", err) + } + + elapsedTime := childBlkTime.Unix() - parentBlkTime.Unix() + maxGas := commonfees.MaxGas(feesCfg, currentGasCap, uint64(elapsedTime)) feesMan := commonfees.NewManager(feesCfg.GasPrice) - feeCalculator = fee.NewDynamicCalculator(feesMan, feesCfg.TempBlockMaxGas) + feeCalculator = fee.NewDynamicCalculator(feesMan, maxGas) } - return feeCalculator + return feeCalculator, nil } diff --git a/vms/platformvm/state/diff.go b/vms/platformvm/state/diff.go index 91fb01d08fc9..9f2134f06105 100644 --- a/vms/platformvm/state/diff.go +++ b/vms/platformvm/state/diff.go @@ -14,6 +14,8 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) var ( @@ -35,6 +37,8 @@ type diff struct { timestamp time.Time + currentGasCap *commonfees.Gas + // Subnet ID --> supply of native asset of the subnet currentSupply map[ids.ID]uint64 @@ -89,6 +93,31 @@ func NewDiffOn(parentState Chain) (Diff, error) { }) } +func (d *diff) GetCurrentGasCap() (commonfees.Gas, error) { + if d.currentGasCap == nil { + parentState, ok := d.stateVersions.GetState(d.parentID) + if !ok { + return commonfees.ZeroGas, fmt.Errorf("%w: %s", ErrMissingParentState, d.parentID) + } + parentCurrentGasCap, err := parentState.GetCurrentGasCap() + if err != nil { + return commonfees.ZeroGas, err + } + + d.currentGasCap = new(commonfees.Gas) + *d.currentGasCap = parentCurrentGasCap + } + + return *d.currentGasCap, nil +} + +func (d *diff) SetCurrentGasCap(gasCap commonfees.Gas) { + if d.currentGasCap == nil { + d.currentGasCap = new(commonfees.Gas) + } + *d.currentGasCap = gasCap +} + func (d *diff) GetTimestamp() time.Time { return d.timestamp } @@ -401,6 +430,9 @@ func (d *diff) DeleteUTXO(utxoID ids.ID) { func (d *diff) Apply(baseState Chain) error { baseState.SetTimestamp(d.timestamp) + if d.currentGasCap != nil { + baseState.SetCurrentGasCap(*d.currentGasCap) + } for subnetID, supply := range d.currentSupply { baseState.SetCurrentSupply(subnetID, supply) } diff --git a/vms/platformvm/state/mock_state.go b/vms/platformvm/state/mock_state.go index c1321567e6a9..bf49f002089a 100644 --- a/vms/platformvm/state/mock_state.go +++ b/vms/platformvm/state/mock_state.go @@ -20,6 +20,7 @@ import ( validators "github.com/ava-labs/avalanchego/snow/validators" logging "github.com/ava-labs/avalanchego/utils/logging" avax "github.com/ava-labs/avalanchego/vms/components/avax" + fees "github.com/ava-labs/avalanchego/vms/components/fees" block "github.com/ava-labs/avalanchego/vms/platformvm/block" fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" status "github.com/ava-labs/avalanchego/vms/platformvm/status" @@ -197,6 +198,21 @@ func (mr *MockChainMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *go return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentDelegatorIterator), arg0, arg1) } +// GetCurrentGasCap mocks base method. +func (m *MockChain) GetCurrentGasCap() (fees.Gas, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentGasCap") + ret0, _ := ret[0].(fees.Gas) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentGasCap indicates an expected call of GetCurrentGasCap. +func (mr *MockChainMockRecorder) GetCurrentGasCap() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentGasCap", reflect.TypeOf((*MockChain)(nil).GetCurrentGasCap)) +} + // GetCurrentStakerIterator mocks base method. func (m *MockChain) GetCurrentStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() @@ -425,6 +441,18 @@ func (mr *MockChainMockRecorder) PutPendingValidator(arg0 any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockChain)(nil).PutPendingValidator), arg0) } +// SetCurrentGasCap mocks base method. +func (m *MockChain) SetCurrentGasCap(arg0 fees.Gas) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetCurrentGasCap", arg0) +} + +// SetCurrentGasCap indicates an expected call of SetCurrentGasCap. +func (mr *MockChainMockRecorder) SetCurrentGasCap(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentGasCap", reflect.TypeOf((*MockChain)(nil).SetCurrentGasCap), arg0) +} + // SetCurrentSupply mocks base method. func (m *MockChain) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { m.ctrl.T.Helper() @@ -659,6 +687,21 @@ func (mr *MockDiffMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *gom return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentDelegatorIterator), arg0, arg1) } +// GetCurrentGasCap mocks base method. +func (m *MockDiff) GetCurrentGasCap() (fees.Gas, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentGasCap") + ret0, _ := ret[0].(fees.Gas) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentGasCap indicates an expected call of GetCurrentGasCap. +func (mr *MockDiffMockRecorder) GetCurrentGasCap() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentGasCap", reflect.TypeOf((*MockDiff)(nil).GetCurrentGasCap)) +} + // GetCurrentStakerIterator mocks base method. func (m *MockDiff) GetCurrentStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() @@ -887,6 +930,18 @@ func (mr *MockDiffMockRecorder) PutPendingValidator(arg0 any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockDiff)(nil).PutPendingValidator), arg0) } +// SetCurrentGasCap mocks base method. +func (m *MockDiff) SetCurrentGasCap(arg0 fees.Gas) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetCurrentGasCap", arg0) +} + +// SetCurrentGasCap indicates an expected call of SetCurrentGasCap. +func (mr *MockDiffMockRecorder) SetCurrentGasCap(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentGasCap", reflect.TypeOf((*MockDiff)(nil).SetCurrentGasCap), arg0) +} + // SetCurrentSupply mocks base method. func (m *MockDiff) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { m.ctrl.T.Helper() @@ -1246,6 +1301,21 @@ func (mr *MockStateMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *go return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockState)(nil).GetCurrentDelegatorIterator), arg0, arg1) } +// GetCurrentGasCap mocks base method. +func (m *MockState) GetCurrentGasCap() (fees.Gas, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentGasCap") + ret0, _ := ret[0].(fees.Gas) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentGasCap indicates an expected call of GetCurrentGasCap. +func (mr *MockStateMockRecorder) GetCurrentGasCap() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentGasCap", reflect.TypeOf((*MockState)(nil).GetCurrentGasCap)) +} + // GetCurrentStakerIterator mocks base method. func (m *MockState) GetCurrentStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() @@ -1578,6 +1648,18 @@ func (mr *MockStateMockRecorder) ReindexBlocks(arg0, arg1 any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReindexBlocks", reflect.TypeOf((*MockState)(nil).ReindexBlocks), arg0, arg1) } +// SetCurrentGasCap mocks base method. +func (m *MockState) SetCurrentGasCap(arg0 fees.Gas) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetCurrentGasCap", arg0) +} + +// SetCurrentGasCap indicates an expected call of SetCurrentGasCap. +func (mr *MockStateMockRecorder) SetCurrentGasCap(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentGasCap", reflect.TypeOf((*MockState)(nil).SetCurrentGasCap), arg0) +} + // SetCurrentSupply mocks base method. func (m *MockState) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { m.ctrl.T.Helper() diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 295e67c52ff3..c2aad726e2af 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -42,8 +42,10 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/reward" "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" safemath "github.com/ava-labs/avalanchego/utils/math" + commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) const ( @@ -84,6 +86,7 @@ var ( CurrentSupplyKey = []byte("current supply") LastAcceptedKey = []byte("last accepted") HeightsIndexedKey = []byte("heights indexed") + CurrentGasCapKey = []byte("gas cap") InitializedKey = []byte("initialized") BlocksReindexedKey = []byte("blocks reindexed") ) @@ -96,6 +99,9 @@ type Chain interface { avax.UTXOGetter avax.UTXODeleter + GetCurrentGasCap() (commonfees.Gas, error) + SetCurrentGasCap(commonfees.Gas) + GetTimestamp() time.Time SetTimestamp(tm time.Time) @@ -355,6 +361,7 @@ type state struct { // The persisted fields represent the current database value timestamp, persistedTimestamp time.Time + currentGasCap *commonfees.Gas currentSupply, persistedCurrentSupply uint64 // [lastAccepted] is the most recently accepted block. lastAccepted, persistedLastAccepted ids.ID @@ -999,6 +1006,20 @@ func (s *state) GetStartTime(nodeID ids.NodeID, subnetID ids.ID) (time.Time, err return staker.StartTime, nil } +func (s *state) GetCurrentGasCap() (commonfees.Gas, error) { + if s.currentGasCap == nil { + return commonfees.ZeroGas, nil + } + return *s.currentGasCap, nil +} + +func (s *state) SetCurrentGasCap(gasCap commonfees.Gas) { + if s.currentGasCap == nil { + s.currentGasCap = new(commonfees.Gas) + } + *s.currentGasCap = gasCap +} + func (s *state) GetTimestamp() time.Time { return s.timestamp } @@ -1289,6 +1310,30 @@ func (s *state) loadMetadata() error { s.persistedTimestamp = timestamp s.SetTimestamp(timestamp) + switch currentGasCapBytes, err := s.singletonDB.Get(CurrentGasCapKey); err { + case nil: + gas, err := database.ParseUInt64(currentGasCapBytes) + if err != nil { + return err + } + s.currentGasCap = new(commonfees.Gas) + *s.currentGasCap = commonfees.Gas(gas) + + case database.ErrNotFound: + // fork introducing dynamic fees may not be active yet, + // hence we may have never stored fees windows. Set to nil + // TODO: remove once fork is active + feesCfg, err := fee.GetDynamicConfig(true /*isEActive*/) + if err != nil { + return fmt.Errorf("failed retrieving dynamic fees config: %w", err) + } + s.currentGasCap = new(commonfees.Gas) + *s.currentGasCap = feesCfg.MaxGasPerSecond + + default: + return err + } + currentSupply, err := database.GetUInt64(s.singletonDB, CurrentSupplyKey) if err != nil { return err @@ -2263,6 +2308,13 @@ func (s *state) writeMetadata() error { } s.persistedTimestamp = s.timestamp } + + if s.currentGasCap != nil { + if err := database.PutUInt64(s.singletonDB, CurrentGasCapKey, uint64(*s.currentGasCap)); err != nil { + return fmt.Errorf("failed to write current gas cap: %w", err) + } + } + if s.persistedCurrentSupply != s.currentSupply { if err := database.PutUInt64(s.singletonDB, CurrentSupplyKey, s.currentSupply); err != nil { return fmt.Errorf("failed to write current supply: %w", err) diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index e608f0d2ed0b..90ff022b21b3 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -66,7 +66,9 @@ func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -114,7 +116,9 @@ func TestAdvanceTimeTxTimestampTooEarly(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -151,7 +155,9 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -182,7 +188,9 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -387,7 +395,9 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { } for _, staker := range test.subnetStakers { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -427,7 +437,9 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -490,7 +502,9 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { subnetVdr1StartTime := defaultValidateStartTime subnetVdr1EndTime := defaultValidateStartTime.Add(defaultMinStakingDuration) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -565,7 +579,9 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -608,7 +624,8 @@ func TestTrackedSubnet(t *testing.T) { subnetVdr1StartTime := defaultValidateStartTime.Add(1 * time.Minute) subnetVdr1EndTime := defaultValidateStartTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -647,7 +664,9 @@ func TestTrackedSubnet(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -697,7 +716,9 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -720,7 +741,9 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { pendingDelegatorStartTime := pendingValidatorStartTime.Add(1 * time.Second) pendingDelegatorEndTime := pendingDelegatorStartTime.Add(1 * time.Second) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + require.NoError(err) + utx, err := builder.NewAddDelegatorTx( &txs.Validator{ NodeID: nodeID, @@ -802,7 +825,9 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -824,7 +849,8 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { // Add delegator pendingDelegatorStartTime := pendingValidatorStartTime.Add(1 * time.Second) pendingDelegatorEndTime := pendingDelegatorStartTime.Add(defaultMinStakingDuration) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]) + require.NoError(err) utx, err := builder.NewAddDelegatorTx( &txs.Validator{ NodeID: nodeID, @@ -903,7 +929,9 @@ func TestAdvanceTimeTxAfterBanff(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -946,7 +974,11 @@ func addPendingValidator( nodeID ids.NodeID, keys []*secp256k1.PrivateKey, ) (*txs.Tx, error) { - builder, signer, feeCalc := env.factory.NewWallet(keys...) + builder, signer, feeCalc, err := env.factory.NewWallet(keys...) + if err != nil { + return nil, err + } + utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 087e152b5b4d..253f0abf14cd 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -29,11 +29,13 @@ import ( // Ensure Execute fails when there are not enough control sigs func TestCreateChainTxInsufficientControlSigs(t *testing.T) { require := require.New(t) - env := newEnvironment(t, banff) + env := newEnvironment(t, eUpgrade) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0], preFundedKeys[1]) + require.NoError(err) + utx, err := builder.NewCreateChainTx( testSubnet1.ID(), nil, @@ -47,7 +49,7 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { require.NoError(err) // Remove a signature - tx.Creds[0].(*secp256k1fx.Credential).Sigs = tx.Creds[0].(*secp256k1fx.Credential).Sigs[1:] + tx.Creds[1].(*secp256k1fx.Credential).Sigs = tx.Creds[1].(*secp256k1fx.Credential).Sigs[1:] stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) @@ -65,11 +67,12 @@ 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, banff) + env := newEnvironment(t, eUpgrade) env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewCreateChainTx( testSubnet1.ID(), nil, @@ -89,7 +92,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { // Replace a valid signature with one from another key sig, err := key.SignHash(hashing.ComputeHash256(tx.Unsigned.Bytes())) require.NoError(err) - copy(tx.Creds[0].(*secp256k1fx.Credential).Sigs[0][:], sig) + copy(tx.Creds[1].(*secp256k1fx.Credential).Sigs[0][:], sig) stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) @@ -112,7 +115,8 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewCreateChainTx( testSubnet1.ID(), nil, @@ -130,7 +134,17 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + parentBlkTime := stateDiff.GetTimestamp() + + builderDiff, err := state.NewDiffOn(stateDiff) + require.NoError(err) + nextBlkTime, _, err := state.NextBlockTime(stateDiff, env.clk) + require.NoError(err) + builderDiff.SetTimestamp(nextBlkTime) + + feeCalculator, err := state.PickFeeCalculator(env.config, builderDiff, parentBlkTime) + require.NoError(err) + executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -148,7 +162,8 @@ func TestCreateChainTxValid(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewCreateChainTx( testSubnet1.ID(), nil, @@ -164,7 +179,17 @@ func TestCreateChainTxValid(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + parentBlkTime := stateDiff.GetTimestamp() + + builderDiff, err := state.NewDiffOn(stateDiff) + require.NoError(err) + nextBlkTime, _, err := state.NextBlockTime(stateDiff, env.clk) + require.NoError(err) + builderDiff.SetTimestamp(nextBlkTime) + + feeCalculator, err := state.PickFeeCalculator(env.config, builderDiff, parentBlkTime) + require.NoError(err) + executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -218,8 +243,10 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.StaticFeeConfig.CreateBlockchainTxFee = test.fee - factory := txstest.NewWalletFactory(env.ctx, &cfg, env.state) - builder, signer, feeCalc := factory.NewWallet(preFundedKeys...) + factory := txstest.NewWalletFactory(env.ctx, &cfg, env.clk, env.state) + builder, signer, feeCalc, err := factory.NewWallet(preFundedKeys...) + require.NoError(err) + utx, err := builder.NewCreateChainTx( testSubnet1.ID(), nil, @@ -237,7 +264,9 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff, stateDiff.GetTimestamp()) + 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 7016796501ce..2c7931bf3fd0 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -66,8 +66,10 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.StaticFeeConfig.CreateSubnetTxFee = test.fee - factory := txstest.NewWalletFactory(env.ctx, &cfg, env.state) - builder, signer, feeCalc := factory.NewWallet(preFundedKeys...) + factory := txstest.NewWalletFactory(env.ctx, &cfg, env.clk, env.state) + builder, signer, feeCalc, err := factory.NewWallet(preFundedKeys...) + require.NoError(err) + utx, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{}, feeCalc, @@ -81,7 +83,9 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { stateDiff.SetTimestamp(test.time) - feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff, stateDiff.GetTimestamp()) + 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 f58652a26a65..a25e29868836 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -53,7 +53,9 @@ func TestNewExportTx(t *testing.T) { t.Run(tt.description, func(t *testing.T) { require := require.New(t) - builder, signer, feeCalc := env.factory.NewWallet(tt.sourceKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(tt.sourceKeys...) + require.NoError(err) + utx, err := builder.NewExportTx( tt.destinationChainID, []*avax.TransferableOutput{{ diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 634ec442802e..56f20b546b8e 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -147,7 +147,7 @@ func newEnvironment(t *testing.T, f fork) *environment { uptimes := uptime.NewManager(baseState, clk) utxosVerifier := utxo.NewVerifier(ctx, clk, fx) - factory := txstest.NewWalletFactory(ctx, config, baseState) + factory := txstest.NewWalletFactory(ctx, config, clk, baseState) backend := Backend{ Config: config, @@ -208,7 +208,9 @@ func newEnvironment(t *testing.T, f fork) *environment { func addSubnet(t *testing.T, env *environment) { require := require.New(t) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) + utx, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{ Threshold: 2, diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index d6a99c73d3cb..80b6947a6c4b 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -124,7 +124,9 @@ func TestNewImportTx(t *testing.T) { env.msm.SharedMemory = tt.sharedMemory - builder, signer, feeCalc := env.factory.NewWallet(tt.sourceKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(tt.sourceKeys...) + require.NoError(err) + utx, err := builder.NewImportTx( tt.sourceChainID, to, @@ -161,7 +163,9 @@ func TestNewImportTx(t *testing.T) { stateDiff.SetTimestamp(tt.timestamp) - feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff, stateDiff.GetTimestamp()) + 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 c0166c47e4bb..31f934d8f10e 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -38,7 +38,9 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { addMinStakeValidator := func(env *environment) { require := require.New(t) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) + utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: newValidatorID, @@ -77,7 +79,9 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { addMaxStakeValidator := func(env *environment) { require := require.New(t) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) + utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: newValidatorID, @@ -246,7 +250,9 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { env := newEnvironment(t, apricotPhase5) env.config.UpgradeConfig.ApricotPhase3Time = tt.AP3Time - builder, signer, feeCalc := env.factory.NewWallet(tt.feeKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(tt.feeKeys...) + require.NoError(err) + utx, err := builder.NewAddDelegatorTx( &txs.Validator{ NodeID: tt.nodeID, @@ -274,7 +280,9 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -299,7 +307,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // Case: Proposed validator currently validating primary network // but stops validating subnet after stops validating primary network // (note that keys[0] is a genesis validator) - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -322,7 +331,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -339,7 +349,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // and proposed subnet validation period is subset of // primary network validation period // (note that keys[0] is a genesis validator) - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -362,7 +373,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -379,7 +391,9 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { dsStartTime := defaultValidateStartTime.Add(10 * time.Second) dsEndTime := dsStartTime.Add(5 * defaultMinStakingDuration) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) + utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: pendingDSValidatorID, @@ -400,7 +414,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Case: Proposed validator isn't in pending or current validator sets - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -423,7 +438,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -455,7 +471,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Case: Proposed validator is pending validator of primary network // but starts validating subnet before primary network - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -478,7 +495,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -493,7 +511,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Case: Proposed validator is pending validator of primary network // but stops validating subnet after primary network - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -516,7 +535,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -531,7 +551,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Case: Proposed validator is pending validator of primary network and // period validating subnet is subset of time validating primary network - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -554,7 +575,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -571,7 +593,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { env.state.SetTimestamp(newTimestamp) { - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -594,7 +617,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -611,7 +635,9 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // Case: Proposed validator already validating the subnet // First, add validator as validator of subnet - builder, signer, feeCalc = env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err = env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) + uSubnetTx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -644,7 +670,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Node with ID nodeIDKey.PublicKey().Address() now validating subnet with ID testSubnet1.ID - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -667,7 +694,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -685,7 +713,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Case: Too few signatures - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -715,7 +744,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -729,7 +759,9 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Case: Control Signature from invalid key (keys[3] is not a control key) - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], preFundedKeys[1]) + require.NoError(err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -757,7 +789,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -772,7 +805,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Case: Proposed validator in pending validator set for subnet // First, add validator to pending validator set of subnet - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -809,7 +843,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -833,7 +868,9 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { { // Case: Validator's start time too early - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) + utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -858,7 +895,9 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -874,7 +913,9 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { nodeID := genesisNodeIDs[0] // Case: Validator already validating primary network - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) + utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -899,7 +940,9 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -914,7 +957,9 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { { // Case: Validator in pending validator set of primary network startTime := defaultValidateStartTime.Add(1 * time.Second) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) + utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -954,7 +999,9 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) + executor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -968,7 +1015,9 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { { // Case: Validator doesn't have enough tokens to cover stake amount - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) + utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: ids.GenerateTestNodeID(), @@ -1001,7 +1050,9 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + 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 13688149e651..8166ecc77306 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -61,7 +61,9 @@ func TestRewardValidatorTxExecuteOnCommit(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAbortState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAbortState, onAbortState.GetTimestamp()) + require.NoError(err) + txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -165,7 +167,8 @@ func TestRewardValidatorTxExecuteOnAbort(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAbortState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAbortState, onAbortState.GetTimestamp()) + require.NoError(err) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -249,7 +252,8 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { vdrEndTime := uint64(defaultValidateStartTime.Add(2 * defaultMinStakingDuration).Unix()) vdrNodeID := ids.GenerateTestNodeID() - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) uVdrTx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: vdrNodeID, @@ -327,7 +331,8 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -385,7 +390,8 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { vdrEndTime := uint64(defaultValidateStartTime.Add(2 * defaultMinStakingDuration).Unix()) vdrNodeID := ids.GenerateTestNodeID() - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) uVdrTx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: vdrNodeID, @@ -474,7 +480,8 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + require.NoError(err) txExecutor := ProposalTxExecutor{ OnCommitState: onCommitState, OnAbortState: onAbortState, @@ -617,7 +624,8 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * vdrEndTime := uint64(defaultValidateStartTime.Add(2 * defaultMinStakingDuration).Unix()) vdrNodeID := ids.GenerateTestNodeID() - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) uVdrTx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: vdrNodeID, @@ -702,7 +710,9 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * delOnAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, delOnCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, delOnCommitState, delOnCommitState.GetTimestamp()) + require.NoError(err) + txExecutor := ProposalTxExecutor{ OnCommitState: delOnCommitState, OnAbortState: delOnAbortState, @@ -795,7 +805,8 @@ func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { vdrEndTime := uint64(defaultValidateStartTime.Add(2 * defaultMinStakingDuration).Unix()) vdrNodeID := ids.GenerateTestNodeID() - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) uVdrTx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: vdrNodeID, @@ -869,7 +880,8 @@ func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { onAbortState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onCommitState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onCommitState, onCommitState.GetTimestamp()) + 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 e0191ded789b..7b38a798f9ee 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -102,7 +102,10 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Creds: []verify.Verifiable{}, } ) - verifiedSignedTx.SetBytes([]byte{1}, []byte{2}) + + unsignedBytes := []byte{1} + signedBytes := []byte{2} + verifiedSignedTx.SetBytes(unsignedBytes, signedBytes) tests := []test{ { @@ -115,7 +118,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now) + mockState.EXPECT().GetTimestamp().Return(now).Times(2) return mockState }, sTxF: func() *txs.Tx { @@ -137,7 +140,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) return mockState }, sTxF: func() *txs.Tx { @@ -161,7 +164,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(verifiedTx.StartTime()).Times(2) + state.EXPECT().GetTimestamp().Return(verifiedTx.StartTime()).Times(3) return state }, sTxF: func() *txs.Tx { @@ -185,7 +188,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) + state.EXPECT().GetTimestamp().Return(now).Times(3) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -212,7 +215,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) + state.EXPECT().GetTimestamp().Return(now).Times(3) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -239,7 +242,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) + state.EXPECT().GetTimestamp().Return(now).Times(3) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -267,7 +270,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) + state.EXPECT().GetTimestamp().Return(now).Times(3) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -298,7 +301,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)).Times(2) // chain time is after fork activation since time.Unix(1, 0).After(activeForkTime) + state.EXPECT().GetTimestamp().Return(time.Unix(1, 0)).Times(3) // chain time is after fork activation since time.Unix(1, 0).After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -329,7 +332,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) return mockState }, @@ -362,7 +365,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) // State says validator exists mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, nil) @@ -389,7 +392,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now).Times(3) // chain time is after latest fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(4) // 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) @@ -436,7 +439,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now).Times(3) // chain time is after latest fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(4) // 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) @@ -482,7 +485,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now).Times(3) // chain time is after Durango fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(4) // 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) @@ -507,14 +510,16 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { ctrl := gomock.NewController(t) var ( - backend = tt.backendF(ctrl) - chain = tt.stateF(ctrl) - sTx = tt.sTxF() - tx = tt.txF() - feeCalculator = state.PickFeeCalculator(backend.Config, chain.GetTimestamp()) + backend = tt.backendF(ctrl) + chain = tt.stateF(ctrl) + sTx = tt.sTxF() + tx = tt.txF() ) - err := verifyAddPermissionlessValidatorTx(backend, feeCalculator, chain, sTx, tx) + feeCalculator, err := state.PickFeeCalculator(backend.Config, chain, chain.GetTimestamp()) + 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 6970bc9b9d78..c437edba0031 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -77,7 +77,9 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { // Case: Empty validator node ID after banff env.config.UpgradeConfig.BanffTime = test.banffTime - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) + utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: ids.EmptyNodeID, @@ -99,7 +101,8 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { stateDiff, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, stateDiff.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, stateDiff, stateDiff.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: stateDiff, @@ -125,7 +128,8 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { addMinStakeValidator := func(env *environment) { require := require.New(t) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: newValidatorID, @@ -164,7 +168,8 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { addMaxStakeValidator := func(env *environment) { require := require.New(t) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: newValidatorID, @@ -333,7 +338,9 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { env := newEnvironment(t, apricotPhase5) env.config.UpgradeConfig.ApricotPhase3Time = tt.AP3Time - builder, signer, feeCalc := env.factory.NewWallet(tt.feeKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(tt.feeKeys...) + require.NoError(err) + utx, err := builder.NewAddDelegatorTx( &txs.Validator{ NodeID: tt.nodeID, @@ -360,7 +367,8 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { env.config.UpgradeConfig.BanffTime = onAcceptState.GetTimestamp() - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -386,7 +394,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // but stops validating subnet after stops validating primary network // (note that keys[0] is a genesis validator) startTime := defaultValidateStartTime.Add(time.Second) - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -406,7 +415,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -422,7 +432,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // and proposed subnet validation period is subset of // primary network validation period // (note that keys[0] is a genesis validator) - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -442,7 +453,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -458,7 +470,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { dsStartTime := defaultGenesisTime.Add(10 * time.Second) dsEndTime := dsStartTime.Add(5 * defaultMinStakingDuration) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: pendingDSValidatorID, @@ -479,7 +492,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { { // Case: Proposed validator isn't in pending or current validator sets - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -499,7 +513,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -530,7 +545,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { { // Case: Proposed validator is pending validator of primary network // but starts validating subnet before primary network - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -550,7 +566,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -564,7 +581,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { { // Case: Proposed validator is pending validator of primary network // but stops validating subnet after primary network - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -584,7 +602,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -598,7 +617,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { { // Case: Proposed validator is pending validator of primary network and // period validating subnet is subset of time validating primary network - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -618,7 +638,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -634,7 +655,9 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { env.state.SetTimestamp(newTimestamp) { - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -654,7 +677,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -670,7 +694,9 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // Case: Proposed validator already validating the subnet // First, add validator as validator of subnet - builder, signer, feeCalc = env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err = env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) + uSubnetTx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -704,7 +730,9 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { { // Node with ID nodeIDKey.PublicKey().Address() now validating subnet with ID testSubnet1.ID startTime := defaultValidateStartTime.Add(time.Second) - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -724,7 +752,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -742,7 +771,9 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { { // Case: Duplicate signatures startTime := defaultValidateStartTime.Add(time.Second) - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1], testSubnet1ControlKeys[2]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1], testSubnet1ControlKeys[2]) + require.NoError(err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -769,7 +800,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -783,7 +815,9 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { { // Case: Too few signatures startTime := defaultValidateStartTime.Add(time.Second) - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[2]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[2]) + require.NoError(err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -810,7 +844,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -824,7 +859,9 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { { // Case: Control Signature from invalid key (keys[3] is not a control key) startTime := defaultValidateStartTime.Add(time.Second) - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], preFundedKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], preFundedKeys[1]) + require.NoError(err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -849,7 +886,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -864,7 +902,9 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // Case: Proposed validator in pending validator set for subnet // First, add validator to pending validator set of subnet startTime := defaultValidateStartTime.Add(time.Second) - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -898,7 +938,8 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -920,7 +961,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { { // Case: Validator's start time too early - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -942,7 +984,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState, err := state.NewDiff(lastAcceptedID, env) require.NoError(err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -956,7 +999,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { { // Case: Validator in current validator set of primary network startTime := defaultValidateStartTime.Add(1 * time.Second) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -990,7 +1034,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutCurrentValidator(staker) onAcceptState.AddTx(tx, status.Committed) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1004,7 +1049,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { { // Case: Validator in pending validator set of primary network startTime := defaultValidateStartTime.Add(1 * time.Second) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -1035,7 +1081,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.PutPendingValidator(staker) onAcceptState.AddTx(tx, status.Committed) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1049,7 +1096,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { { // Case: Validator doesn't have enough tokens to cover stake amount startTime := defaultValidateStartTime.Add(1 * time.Second) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys[0]) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -1079,7 +1127,8 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { onAcceptState.DeleteUTXO(utxoID) } - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) executor := StandardTxExecutor{ Backend: &env.backend, FeeCalculator: feeCalculator, @@ -1109,7 +1158,8 @@ func TestDurangoDisabledTransactions(t *testing.T) { endTime = chainTime.Add(defaultMaxStakingDuration) ) - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -1148,7 +1198,8 @@ func TestDurangoDisabledTransactions(t *testing.T) { } it.Release() - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewAddDelegatorTx( &txs.Validator{ NodeID: primaryValidator.NodeID, @@ -1185,7 +1236,8 @@ func TestDurangoDisabledTransactions(t *testing.T) { tx := tt.buildTx(env) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(err) err = tx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1221,7 +1273,8 @@ func TestDurangoMemoField(t *testing.T) { } it.Release() - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1247,7 +1300,8 @@ func TestDurangoMemoField(t *testing.T) { { name: "CreateChainTx", setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewCreateChainTx( testSubnet1.TxID, []byte{}, @@ -1270,7 +1324,8 @@ func TestDurangoMemoField(t *testing.T) { { name: "CreateSubnetTx", setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{ Threshold: 1, @@ -1313,7 +1368,8 @@ func TestDurangoMemoField(t *testing.T) { ) env.msm.SharedMemory = sharedMemory - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewImportTx( sourceChain, &secp256k1fx.OutputOwners{ @@ -1337,7 +1393,8 @@ func TestDurangoMemoField(t *testing.T) { { name: "ExportTx", setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewExportTx( env.ctx.XChainID, []*avax.TransferableOutput{{ @@ -1381,7 +1438,9 @@ func TestDurangoMemoField(t *testing.T) { it.Release() endTime := primaryValidator.EndTime - builder, signer, feeCalc := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, signer, feeCalc, err := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(t, err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1401,7 +1460,8 @@ func TestDurangoMemoField(t *testing.T) { onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) require.NoError(t, err) - feeCalculator := state.PickFeeCalculator(env.config, onAcceptState.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, onAcceptState, onAcceptState.GetTimestamp()) + require.NoError(t, err) require.NoError(t, subnetValTx.Unsigned.Visit(&StandardTxExecutor{ Backend: &env.backend, State: onAcceptState, @@ -1409,7 +1469,9 @@ func TestDurangoMemoField(t *testing.T) { Tx: subnetValTx, })) - builder, signer, feeCalc = env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err = env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) + utx2, err := builder.NewRemoveSubnetValidatorTx( primaryValidator.NodeID, testSubnet1.ID(), @@ -1426,7 +1488,8 @@ func TestDurangoMemoField(t *testing.T) { { name: "TransformSubnetTx", setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewTransformSubnetTx( testSubnet1.TxID, // subnetID ids.GenerateTestID(), // assetID @@ -1466,7 +1529,9 @@ func TestDurangoMemoField(t *testing.T) { sk, err := bls.NewSecretKey() require.NoError(t, err) - builder, txSigner, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, txSigner, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) + utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1517,7 +1582,8 @@ func TestDurangoMemoField(t *testing.T) { } it.Release() - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewAddPermissionlessDelegatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1549,7 +1615,8 @@ func TestDurangoMemoField(t *testing.T) { { name: "TransferSubnetOwnershipTx", setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewTransferSubnetOwnershipTx( testSubnet1.TxID, &secp256k1fx.OutputOwners{ @@ -1572,7 +1639,8 @@ func TestDurangoMemoField(t *testing.T) { { name: "BaseTx", setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { - builder, signer, feeCalc := env.factory.NewWallet(preFundedKeys...) + builder, signer, feeCalc, err := env.factory.NewWallet(preFundedKeys...) + require.NoError(t, err) utx, err := builder.NewBaseTx( []*avax.TransferableOutput{ { @@ -1609,11 +1677,12 @@ func TestDurangoMemoField(t *testing.T) { env.ctx.Lock.Lock() defer env.ctx.Lock.Unlock() - feeCalculator := state.PickFeeCalculator(env.config, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(env.config, env.state, env.state.GetTimestamp()) + 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, @@ -1757,7 +1826,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().AddUTXO(gomock.Any()).Times(len(env.unsignedTx.Outs)) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1782,9 +1852,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).Times(2) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := state.PickFeeCalculator(cfg, env.latestForkTime) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1812,7 +1884,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetPendingValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(nil, database.ErrNotFound) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1839,11 +1912,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).Times(3) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(&staker, nil).Times(1) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1868,11 +1942,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).Times(3) env.state.EXPECT().GetCurrentValidator(env.unsignedTx.Subnet, env.unsignedTx.NodeID).Return(env.staker, nil) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1900,7 +1975,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1930,7 +2006,8 @@ 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) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -1963,7 +2040,8 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { ).Return(errTest) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2118,9 +2196,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).Times(2) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := state.PickFeeCalculator(cfg, env.latestForkTime) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2144,10 +2224,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).Times(3) cfg := defaultTestConfig(t, durango, env.latestForkTime) - feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2172,12 +2253,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).Times(3) cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2201,7 +2283,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).Times(3) 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) @@ -2212,7 +2294,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, @@ -2237,7 +2320,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).Times(3) 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) @@ -2252,7 +2335,8 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { cfg := defaultTestConfig(t, durango, env.latestForkTime) cfg.MaxStakeDuration = math.MaxInt64 - feeCalculator := state.PickFeeCalculator(cfg, env.state.GetTimestamp()) + feeCalculator, err := state.PickFeeCalculator(cfg, env.state, env.state.GetTimestamp()) + require.NoError(t, err) e := &StandardTxExecutor{ Backend: &Backend{ Config: cfg, diff --git a/vms/platformvm/txs/fee/dynamic_config.go b/vms/platformvm/txs/fee/dynamic_config.go index f16ce9b27d8f..10abf02a2d53 100644 --- a/vms/platformvm/txs/fee/dynamic_config.go +++ b/vms/platformvm/txs/fee/dynamic_config.go @@ -6,7 +6,6 @@ package fee import ( "errors" "fmt" - "math" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/constants" @@ -15,18 +14,27 @@ import ( commonfees "github.com/ava-labs/avalanchego/vms/components/fees" ) +const TempGasCap = commonfees.Gas(1_000_000) // TODO ABENEGIA: temp const to be replaced with API call + var ( errDynamicFeeConfigNotAvailable = errors.New("dynamic fee config not available") eUpgradeDynamicFeesConfig = commonfees.DynamicFeesConfig{ GasPrice: commonfees.GasPrice(10 * units.NanoAvax), FeeDimensionWeights: commonfees.Dimensions{1, 1, 1, 1}, - TempBlockMaxGas: commonfees.Gas(math.MaxUint64), + MaxGasPerSecond: commonfees.Gas(1_000_000), + LeakGasCoeff: commonfees.Gas(1), } customDynamicFeesConfig *commonfees.DynamicFeesConfig ) +func init() { + if err := eUpgradeDynamicFeesConfig.Validate(); err != nil { + panic(err) + } +} + func GetDynamicConfig(isEActive bool) (commonfees.DynamicFeesConfig, error) { if !isEActive { return commonfees.DynamicFeesConfig{}, errDynamicFeeConfigNotAvailable @@ -45,6 +53,9 @@ func ResetDynamicConfig(ctx *snow.Context, customFeesConfig *commonfees.DynamicF 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/txstest/builder.go b/vms/platformvm/txs/txstest/builder.go index 806b12517f99..62c60ecd7a2d 100644 --- a/vms/platformvm/txs/txstest/builder.go +++ b/vms/platformvm/txs/txstest/builder.go @@ -4,8 +4,11 @@ package txstest import ( + "fmt" + "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" @@ -17,11 +20,13 @@ import ( func NewWalletFactory( ctx *snow.Context, cfg *config.Config, + clk *mockable.Clock, state state.State, ) *WalletFactory { return &WalletFactory{ ctx: ctx, cfg: cfg, + clk: clk, state: state, } } @@ -29,21 +34,37 @@ func NewWalletFactory( type WalletFactory struct { ctx *snow.Context cfg *config.Config + clk *mockable.Clock state state.State } -func (w *WalletFactory) NewWallet(keys ...*secp256k1.PrivateKey) (builder.Builder, signer.Signer, *fee.Calculator) { +func (w *WalletFactory) NewWallet(keys ...*secp256k1.PrivateKey) (builder.Builder, signer.Signer, *fee.Calculator, error) { var ( kc = secp256k1fx.NewKeychain(keys...) addrs = kc.Addresses() backend = newBackend(addrs, w.state, w.ctx.SharedMemory) context = newContext(w.ctx, w.cfg, w.state.GetTimestamp()) + + builder = builder.New(addrs, context, backend) + signer = signer.New(kc, backend) + feeCalc, err = w.FeeCalculator() ) - return builder.New(addrs, context, backend), signer.New(kc, backend), w.feeCalculator() + return builder, signer, feeCalc, err } -func (w *WalletFactory) feeCalculator() *fee.Calculator { - chainTime := w.state.GetTimestamp() - return state.PickFeeCalculator(w.cfg, chainTime) +func (w *WalletFactory) FeeCalculator() (*fee.Calculator, error) { + parentBlkTime := w.state.GetTimestamp() + nextBlkTime, _, err := state.NextBlockTime(w.state, w.clk) + if err != nil { + return nil, fmt.Errorf("failed calculating next block time: %w", err) + } + + diff, err := state.NewDiffOn(w.state) + if err != nil { + return nil, fmt.Errorf("failed building diff: %w", err) + } + diff.SetTimestamp(nextBlkTime) + + return state.PickFeeCalculator(w.cfg, diff, parentBlkTime) } diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index d6999e4642f0..d8b6eb932bea 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -258,8 +258,12 @@ func takeValidatorsSnapshotAtCurrentHeight(vm *VM, validatorsSetByHeightAndSubne } func addSubnetValidator(vm *VM, data *validatorInputData, subnetID ids.ID) (*state.Staker, error) { - factory := txstest.NewWalletFactory(vm.ctx, &vm.Config, vm.state) - builder, signer, feeCalc := factory.NewWallet(keys[0], keys[1]) + factory := txstest.NewWalletFactory(vm.ctx, &vm.Config, &vm.clock, vm.state) + builder, signer, feeCalc, err := factory.NewWallet(keys[0], keys[1]) + if err != nil { + return nil, err + } + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -294,8 +298,12 @@ func addPrimaryValidatorWithBLSKey(vm *VM, data *validatorInputData) (*state.Sta return nil, fmt.Errorf("failed to generate BLS key: %w", err) } - factory := txstest.NewWalletFactory(vm.ctx, &vm.Config, vm.state) - builder, txSigner, feeCalc := factory.NewWallet(keys[0], keys[1]) + factory := txstest.NewWalletFactory(vm.ctx, &vm.Config, &vm.clock, vm.state) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0], keys[1]) + if err != nil { + return nil, err + } + utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -720,8 +728,12 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { // Create a subnet and store it in testSubnet1 // Note: following Banff activation, block acceptance will move // chain time ahead - factory := txstest.NewWalletFactory(vm.ctx, &vm.Config, vm.state) - builder, signer, feeCalc := factory.NewWallet(keys[len(keys)-1]) + factory := txstest.NewWalletFactory(vm.ctx, &vm.Config, &vm.clock, vm.state) + builder, signer, feeCalc, err := factory.NewWallet(keys[len(keys)-1]) + if err != nil { + return nil, ids.Empty, err + } + utx, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{ Threshold: 1, diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index b04af5dcd990..7bbb6b7a77ac 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -66,7 +66,8 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { changeAddr := keys[0].PublicKey().Address() // create valid tx - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -112,7 +113,8 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { firstDelegatorEndTime := firstDelegatorStartTime.Add(vm.MinStakeDuration) // create valid tx - builder, txSigner, feeCalc = factory.NewWallet(keys[0], keys[1]) + builder, txSigner, feeCalc, err = factory.NewWallet(keys[0], keys[1]) + require.NoError(err) uDelTx1, err := builder.NewAddDelegatorTx( &txs.Validator{ NodeID: nodeID, @@ -159,7 +161,9 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { vm.clock.Set(secondDelegatorStartTime.Add(-10 * executor.SyncBound)) // create valid tx - builder, txSigner, feeCalc = factory.NewWallet(keys[0], keys[1], keys[3]) + builder, txSigner, feeCalc, err = factory.NewWallet(keys[0], keys[1], keys[3]) + require.NoError(err) + uDelTx2, err := builder.NewAddDelegatorTx( &txs.Validator{ NodeID: nodeID, @@ -196,7 +200,9 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { thirdDelegatorEndTime := thirdDelegatorStartTime.Add(vm.MinStakeDuration) // create valid tx - builder, txSigner, feeCalc = factory.NewWallet(keys[0], keys[1], keys[4]) + builder, txSigner, feeCalc, err = factory.NewWallet(keys[0], keys[1], keys[4]) + require.NoError(err) + uDelTx3, err := builder.NewAddDelegatorTx( &txs.Validator{ NodeID: nodeID, @@ -278,7 +284,8 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { changeAddr := keys[0].PublicKey().Address() // create valid tx - builder, txSigner, feeCalc := factory.NewWallet(keys[0], keys[1]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0], keys[1]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -512,10 +519,13 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { factory := txstest.NewWalletFactory( vm.ctx, &vm.Config, + &vm.clock, vm.state, ) - builder, txSigner, feeCalc := factory.NewWallet(key0) + builder, txSigner, feeCalc, err := factory.NewWallet(key0) + require.NoError(err) + utx0, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{ Threshold: 1, @@ -531,7 +541,9 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { addSubnetTx0, err := walletsigner.SignUnsigned(context.Background(), txSigner, utx0) require.NoError(err) - builder, txSigner, feeCalc = factory.NewWallet(key1) + builder, txSigner, feeCalc, err = factory.NewWallet(key1) + require.NoError(err) + utx1, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{ Threshold: 1, @@ -623,7 +635,8 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { newValidatorEndTime := newValidatorStartTime.Add(defaultMinStakingDuration) // Create the tx to add a new validator - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -838,7 +851,8 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { nodeID0 := ids.GenerateTestNodeID() // Create the tx to add the first new validator - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID0, @@ -1017,7 +1031,9 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { nodeID1 := ids.GenerateTestNodeID() // Create the tx to add the second new validator - builder, txSigner, feeCalc = factory.NewWallet(keys[1]) + builder, txSigner, feeCalc, err = factory.NewWallet(keys[1]) + require.NoError(err) + utx1, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID1, @@ -1179,7 +1195,8 @@ func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { extraNodeID := ids.GenerateTestNodeID() // Create the tx to add the first new validator - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: extraNodeID, @@ -1307,7 +1324,9 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { changeAddr := keys[0].PublicKey().Address() // create valid tx - builder, txSigner, feeCalc := factory.NewWallet(keys[0], keys[1]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0], keys[1]) + require.NoError(err) + utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -1423,7 +1442,8 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t nodeID := ids.GenerateTestNodeID() changeAddr := keys[0].PublicKey().Address() - builder, txSigner, feeCalc := factory.NewWallet(keys[0], keys[1]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0], keys[1]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -1576,7 +1596,8 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t nodeID := ids.GenerateTestNodeID() changeAddr := keys[0].PublicKey().Address() - builder, txSigner, feeCalc := factory.NewWallet(keys[0], keys[1]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0], keys[1]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -1731,7 +1752,9 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) // build primary network validator with BLS key - builder, txSigner, feeCalc := factory.NewWallet(keys...) + builder, txSigner, feeCalc, err := factory.NewWallet(keys...) + require.NoError(err) + uPrimaryTx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1781,7 +1804,8 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) // insert the subnet validator - builder, txSigner, feeCalc = factory.NewWallet(keys[0], keys[1]) + builder, txSigner, feeCalc, err = factory.NewWallet(keys[0], keys[1]) + require.NoError(err) uAddSubnetValTx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1863,7 +1887,8 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) require.NotEqual(sk1, sk2) - builder, txSigner, feeCalc = factory.NewWallet(keys...) + builder, txSigner, feeCalc, err = factory.NewWallet(keys...) + require.NoError(err) uPrimaryRestartTx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1990,7 +2015,8 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { nodeID := ids.GenerateTestNodeID() addr := keys[0].PublicKey().Address() - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) uAddValTx1, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -2061,7 +2087,8 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { sk2, err := bls.NewSecretKey() require.NoError(err) - builder, txSigner, feeCalc = factory.NewWallet(keys...) + builder, txSigner, feeCalc, err = factory.NewWallet(keys...) + require.NoError(err) uPrimaryRestartTx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -2152,7 +2179,9 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { nodeID := ids.GenerateTestNodeID() addr := keys[0].PublicKey().Address() - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) + uPrimaryTx1, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -2193,7 +2222,8 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { require.NoError(err) // insert the subnet validator - builder, txSigner, feeCalc = factory.NewWallet(keys[0], keys[1]) + builder, txSigner, feeCalc, err = factory.NewWallet(keys[0], keys[1]) + require.NoError(err) uAddSubnetValTx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -2274,7 +2304,9 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { sk2, err := bls.NewSecretKey() require.NoError(err) - builder, txSigner, feeCalc = factory.NewWallet(keys...) + builder, txSigner, feeCalc, err = factory.NewWallet(keys...) + require.NoError(err) + uPrimaryRestartTx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -2372,7 +2404,8 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { nodeID := ids.GenerateTestNodeID() addr := keys[0].PublicKey().Address() - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) uPrimaryTx1, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -2410,7 +2443,9 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { require.NoError(err) // insert the subnet validator - builder, txSigner, feeCalc = factory.NewWallet(keys[0], keys[1]) + builder, txSigner, feeCalc, err = factory.NewWallet(keys[0], keys[1]) + require.NoError(err) + uAddSubnetValTx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index da03aaabc664..893efb2a34d8 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -314,13 +314,16 @@ func defaultVM(t *testing.T, f fork) (*VM, *txstest.WalletFactory, database.Data factory := txstest.NewWalletFactory( ctx, &vm.Config, + &vm.clock, vm.state, ) // Create a subnet and store it in testSubnet1 // Note: following Banff activation, block acceptance will move // chain time ahead - builder, signer, feeCalc := factory.NewWallet(keys[0]) + builder, signer, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) + utx, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{ Threshold: 2, @@ -362,7 +365,7 @@ func defaultVM(t *testing.T, f fork) (*VM, *txstest.WalletFactory, database.Data // Ensure genesis state is parsed from bytes and stored correctly func TestGenesis(t *testing.T) { require := require.New(t) - vm, _, _, _ := defaultVM(t, latestFork) + vm, _, _, _ := defaultVM(t, durango) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -398,7 +401,8 @@ func TestGenesis(t *testing.T) { // we use the first key to fund a subnet creation in [defaultGenesis]. // As such we need to account for the subnet creation fee - feeCalc := state.PickFeeCalculator(&vm.Config, vm.state.GetTimestamp()) + feeCalc, err := testReplayFeeCalculator(&vm.Config, defaultGenesisTime, vm.state) + require.NoError(err) fee, err := feeCalc.ComputeFee(testSubnet1.Unsigned, testSubnet1.Creds) require.NoError(err) require.Equal(uint64(utxo.Amount)-fee, out.Amount()) @@ -436,7 +440,9 @@ func TestAddValidatorCommit(t *testing.T) { require.NoError(err) // create valid tx - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) + utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -496,7 +502,8 @@ func TestInvalidAddValidatorCommit(t *testing.T) { endTime := startTime.Add(defaultMinStakingDuration) // create invalid tx - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -556,7 +563,8 @@ func TestAddValidatorReject(t *testing.T) { ) // create valid tx - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) utx, err := builder.NewAddValidatorTx( &txs.Validator{ NodeID: nodeID, @@ -610,7 +618,8 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { require.NoError(err) // create valid tx - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -661,7 +670,9 @@ func TestAddSubnetValidatorAccept(t *testing.T) { // create valid tx // note that [startTime, endTime] is a subset of time that keys[0] // validates primary network ([defaultValidateStartTime, defaultValidateEndTime]) - builder, txSigner, feeCalc := factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, txSigner, feeCalc, err := factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -714,7 +725,9 @@ func TestAddSubnetValidatorReject(t *testing.T) { // create valid tx // note that [startTime, endTime] is a subset of time that keys[0] // validates primary network ([defaultValidateStartTime, defaultValidateEndTime]) - builder, txSigner, feeCalc := factory.NewWallet(testSubnet1ControlKeys[1], testSubnet1ControlKeys[2]) + builder, txSigner, feeCalc, err := factory.NewWallet(testSubnet1ControlKeys[1], testSubnet1ControlKeys[2]) + require.NoError(err) + utx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -906,7 +919,9 @@ func TestCreateChain(t *testing.T) { vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() - builder, txSigner, feeCalc := factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + builder, txSigner, feeCalc, err := factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]) + require.NoError(err) + utx, err := builder.NewCreateChainTx( testSubnet1.ID(), nil, @@ -957,7 +972,8 @@ func TestCreateSubnet(t *testing.T) { vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) uCreateSubnetTx, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{ Threshold: 1, @@ -1073,8 +1089,10 @@ func TestAtomicImport(t *testing.T) { mutableSharedMemory.SharedMemory = m.NewSharedMemory(vm.ctx.ChainID) peerSharedMemory := m.NewSharedMemory(vm.ctx.XChainID) - builder, _, feeCalc := factory.NewWallet(keys[0]) - _, err := builder.NewImportTx( + builder, _, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) + + _, err = builder.NewImportTx( vm.ctx.XChainID, &secp256k1fx.OutputOwners{ Threshold: 1, @@ -1114,7 +1132,9 @@ func TestAtomicImport(t *testing.T) { }, })) - builder, txSigner, feeCalc := factory.NewWallet(recipientKey) + builder, txSigner, feeCalc, err := factory.NewWallet(recipientKey) + require.NoError(err) + utx, err := builder.NewImportTx( vm.ctx.XChainID, &secp256k1fx.OutputOwners{ @@ -2137,7 +2157,8 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { sk, err := bls.NewSecretKey() require.NoError(err) - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) uAddValTx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -2206,7 +2227,9 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { require.NoError(createSubnetBlock.Accept(context.Background())) require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) - builder, txSigner, feeCalc = factory.NewWallet(key, keys[1]) + builder, txSigner, feeCalc, err = factory.NewWallet(key, keys[1]) + require.NoError(err) + uAddSubnetValTx, err := builder.NewAddSubnetValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -2227,7 +2250,9 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { addSubnetValidatorTx, err := walletsigner.SignUnsigned(context.Background(), txSigner, uAddSubnetValTx) require.NoError(err) - builder, txSigner, feeCalc = factory.NewWallet(key, keys[2]) + builder, txSigner, feeCalc, err = factory.NewWallet(key, keys[2]) + require.NoError(err) + uRemoveSubnetValTx, err := builder.NewRemoveSubnetValidatorTx( nodeID, createSubnetTx.ID(), @@ -2269,7 +2294,8 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) uCreateSubnetTx, err := builder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{ Threshold: 1, @@ -2360,10 +2386,11 @@ func TestBaseTx(t *testing.T) { vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() - sendAmt := uint64(100000) + sendAmt := uint64(100_000) changeAddr := ids.ShortEmpty - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) utx, err := builder.NewBaseTx( []*avax.TransferableOutput{ { @@ -2423,7 +2450,9 @@ func TestBaseTx(t *testing.T) { } require.Equal(totalOutputAmt, key0OutputAmt+key1OutputAmt+changeAddrOutputAmt) - feeCalc = state.PickFeeCalculator(&vm.Config, vm.state.GetTimestamp()) + feeCalc, err = state.PickFeeCalculator(&vm.Config, vm.state, vm.state.GetTimestamp()) + require.NoError(err) + fee, err := feeCalc.ComputeFee(baseTx.Unsigned, baseTx.Creds) require.NoError(err) require.Equal(fee, totalInputAmt-totalOutputAmt) @@ -2446,7 +2475,7 @@ func TestBaseTx(t *testing.T) { func TestPruneMempool(t *testing.T) { require := require.New(t) - vm, factory, _, _ := defaultVM(t, latestFork) + vm, factory, _, _ := defaultVM(t, durango) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -2454,7 +2483,8 @@ func TestPruneMempool(t *testing.T) { sendAmt := uint64(100000) changeAddr := ids.ShortEmpty - builder, txSigner, feeCalc := factory.NewWallet(keys[0]) + builder, txSigner, feeCalc, err := factory.NewWallet(keys[0]) + require.NoError(err) utx, err := builder.NewBaseTx( []*avax.TransferableOutput{ { @@ -2498,7 +2528,9 @@ func TestPruneMempool(t *testing.T) { sk, err := bls.NewSecretKey() require.NoError(err) - builder, txSigner, feeCalc = factory.NewWallet(keys[1]) + builder, txSigner, feeCalc, err = factory.NewWallet(keys[1]) + require.NoError(err) + uAddValTx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index e2e4ff347a0b..35c4866f8c48 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -633,9 +633,8 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( if !w.isEForkActive { feeCalculator = fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Config{}, time.Time{}) } else { - feeCfg, _ := fee.GetDynamicConfig(w.isEForkActive) feeMan := commonfees.NewManager(w.gasPrice) - feeCalculator = fee.NewDynamicCalculator(feeMan, feeCfg.TempBlockMaxGas) + feeCalculator = fee.NewDynamicCalculator(feeMan, fee.TempGasCap) } return feeCalculator, nil } @@ -666,7 +665,7 @@ func (w *wallet) refreshFeesData(ctx *builder.Context, options ...common.Option) } feeCfg, _ := fee.GetDynamicConfig(w.isEForkActive) w.gasPrice = feeCfg.GasPrice - w.maxComplexity = feeCfg.TempBlockMaxGas + w.maxComplexity = fee.TempGasCap return nil } From 36b424f6ca8d93d10f4262ab3cdd9fcada801740 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 18 Jun 2024 12:37:39 +0200 Subject: [PATCH 104/120] cleanup --- vms/components/fees/config.go | 27 ++++++++++++++---- vms/components/fees/dimensions.go | 29 ++----------------- vms/components/fees/manager.go | 33 +++++++++++----------- vms/platformvm/service_test.go | 32 ++++++++++----------- vms/platformvm/state/block_helpers.go | 33 +++++++++++----------- vms/platformvm/txs/fee/calculator.go | 6 ++-- vms/platformvm/txs/fee/calculator_test.go | 34 +++++++++++------------ 7 files changed, 93 insertions(+), 101 deletions(-) diff --git a/vms/components/fees/config.go b/vms/components/fees/config.go index ae34231cedb8..36d2882453d3 100644 --- a/vms/components/fees/config.go +++ b/vms/components/fees/config.go @@ -3,7 +3,11 @@ package fees -import "errors" +import ( + "errors" + "fmt" + "time" +) var errZeroLeakGasCoeff = errors.New("zero leak gas coefficient") @@ -26,11 +30,24 @@ func (c *DynamicFeesConfig) Validate() error { } // We cap the maximum gas consumed by time with a leaky bucket approach -// MaxGas = min (MaxGas + MaxGasPerSecond/LeakGasCoeff*ElapsedTime, MaxGasPerSecond) -func MaxGas(cfg DynamicFeesConfig, currentGasCapacity Gas, elapsedTime uint64) Gas { +// GasCap = min (GasCap + MaxGasPerSecond/LeakGasCoeff*ElapsedTime, MaxGasPerSecond) +func GasCap(cfg DynamicFeesConfig, currentGasCapacity Gas, parentBlkTime, childBlkTime time.Time) (Gas, error) { + if !childBlkTime.After(parentBlkTime) { + return ZeroGas, fmt.Errorf("unexpected block times, parentBlkTim %v, childBlkTime %v", parentBlkTime, childBlkTime) + } + + elapsedTime := uint64(childBlkTime.Unix() - parentBlkTime.Unix()) if elapsedTime > uint64(cfg.LeakGasCoeff) { - return cfg.MaxGasPerSecond + return cfg.MaxGasPerSecond, nil } - return min(cfg.MaxGasPerSecond, currentGasCapacity+cfg.MaxGasPerSecond*Gas(elapsedTime)/cfg.LeakGasCoeff) + 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/fees/dimensions.go b/vms/components/fees/dimensions.go index e8e3f0922838..e5c025b7a4c4 100644 --- a/vms/components/fees/dimensions.go +++ b/vms/components/fees/dimensions.go @@ -4,8 +4,6 @@ package fees import ( - "errors" - safemath "github.com/ava-labs/avalanchego/utils/math" ) @@ -15,26 +13,13 @@ const ( UTXOWrite Dimension = 2 // includes delete Compute Dimension = 3 // signatures checks, tx-specific - bandwidthString string = "Bandwidth" - utxosReadString string = "UTXOsRead" - utxosWriteString string = "UTXOsWrite" - computeString string = "Compute" - FeeDimensions = 4 ) var ( - errUnknownDimension = errors.New("unknown dimension") - - ZeroGas = Gas(0) - Empty = Dimensions{} - - DimensionStrings = []string{ - bandwidthString, - utxosReadString, - utxosWriteString, - computeString, - } + ZeroGas = Gas(0) + ZeroGasPrice = GasPrice(0) + Empty = Dimensions{} ) type ( @@ -45,14 +30,6 @@ type ( Dimensions [FeeDimensions]uint64 ) -func (d Dimension) String() (string, error) { - if d < 0 || d >= FeeDimensions { - return "", errUnknownDimension - } - - return DimensionStrings[d], nil -} - func Add(lhs, rhs Dimensions) (Dimensions, error) { var res Dimensions for i := 0; i < FeeDimensions; i++ { diff --git a/vms/components/fees/manager.go b/vms/components/fees/manager.go index aad7ffbd6bfd..0729d89bbc59 100644 --- a/vms/components/fees/manager.go +++ b/vms/components/fees/manager.go @@ -16,9 +16,9 @@ type Manager struct { // Avax denominated gas price, i.e. fee per unit of complexity. gasPrice GasPrice - // cumulatedGas helps aggregating the gas consumed - // by a block so that we can verify it's not too big/build it properly. - cumulatedGas Gas + // blockGas helps aggregating the gas consumed in a single block + // so that we can verify it's not too big/build it properly. + blockGas Gas } func NewManager(gasPrice GasPrice) *Manager { @@ -31,8 +31,8 @@ func (m *Manager) GetGasPrice() GasPrice { return m.gasPrice } -func (m *Manager) GetGas() Gas { - return m.cumulatedGas +func (m *Manager) GetBlockGas() Gas { + return m.blockGas } // CalculateFee must be a stateless method @@ -40,30 +40,31 @@ func (m *Manager) CalculateFee(g Gas) (uint64, error) { return safemath.Mul64(uint64(m.gasPrice), uint64(g)) } -// CumulateComplexity tries to cumulate the consumed complexity [units]. Before -// actually cumulating them, it checks whether the result would breach [bounds]. +// CumulateGas tries to cumulate the consumed gas [units]. Before +// actually cumulating it, it checks whether the result would breach [bounds]. // If so, it returns the first dimension to breach bounds. -func (m *Manager) CumulateComplexity(gas, bound Gas) error { +func (m *Manager) CumulateGas(gas, bound Gas) error { // Ensure we can consume (don't want partial update of values) - consumed, err := safemath.Add64(uint64(m.cumulatedGas), uint64(gas)) + blkGas, err := safemath.Add64(uint64(m.blockGas), uint64(gas)) if err != nil { return fmt.Errorf("%w: %w", errGasBoundBreached, err) } - if Gas(consumed) > bound { + if Gas(blkGas) > bound { return errGasBoundBreached } - m.cumulatedGas = Gas(consumed) + m.blockGas = Gas(blkGas) return nil } // Sometimes, e.g. while building a tx, we'd like freedom to speculatively add complexity -// and to remove it later on. [RemoveComplexity] grants this freedom -func (m *Manager) RemoveComplexity(gasToRm Gas) error { - revertedGas, err := safemath.Sub(m.cumulatedGas, gasToRm) +// and to remove it later on. [RemoveGas] grants this freedom +func (m *Manager) RemoveGas(gasToRm Gas) error { + rBlkdGas, err := safemath.Sub(m.blockGas, gasToRm) if err != nil { - return fmt.Errorf("%w: current Gas %d, gas to revert %d", err, m.cumulatedGas, gasToRm) + return fmt.Errorf("%w: current Gas %d, gas to revert %d", err, m.blockGas, gasToRm) } - m.cumulatedGas = revertedGas + + m.blockGas = rBlkdGas return nil } diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 513b75bbf1b8..e673f7ed1825 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -82,28 +82,26 @@ func testReplayFeeCalculator(cfg *config.Config, parentBlkTime time.Time, state var ( childBlkTime = state.GetTimestamp() isEActive = cfg.UpgradeConfig.IsEActivated(childBlkTime) - - feeCalculator *fee.Calculator ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, childBlkTime) - } else { - feesCfg, err := fee.GetDynamicConfig(isEActive) - if err != nil { - return nil, fmt.Errorf("failed retrieving dynamic fees config: %w", err) - } - currentGasCap, err := state.GetCurrentGasCap() - if err != nil { - return nil, fmt.Errorf("failed retrieving gas cap: %w", err) - } + return fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, childBlkTime), nil + } - elapsedTime := childBlkTime.Unix() - parentBlkTime.Unix() - maxGas := commonfees.MaxGas(feesCfg, currentGasCap, uint64(elapsedTime)) - feesMan := commonfees.NewManager(feesCfg.GasPrice) - feeCalculator = fee.NewDynamicCalculator(feesMan, maxGas) + feesCfg, err := fee.GetDynamicConfig(isEActive) + if err != nil { + return nil, fmt.Errorf("failed retrieving dynamic fees config: %w", err) + } + currentGasCap, err := state.GetCurrentGasCap() + if err != nil { + return nil, fmt.Errorf("failed retrieving current gas cap: %w", err) + } + gasCap, err := commonfees.GasCap(feesCfg, currentGasCap, parentBlkTime, childBlkTime) + if err != nil { + return nil, fmt.Errorf("failed updating gas cap: %w", err) } - return feeCalculator, nil + feesMan := commonfees.NewManager(feesCfg.GasPrice) + return fee.NewDynamicCalculator(feesMan, gasCap), nil } func defaultService(t *testing.T) (*Service, *mutableSharedMemory, *txstest.WalletFactory) { diff --git a/vms/platformvm/state/block_helpers.go b/vms/platformvm/state/block_helpers.go index d4f43db7eea8..8d480e6b196a 100644 --- a/vms/platformvm/state/block_helpers.go +++ b/vms/platformvm/state/block_helpers.go @@ -74,31 +74,30 @@ 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 mnodify [state] +// [PickFeeCalculator] does not modify [state] func PickFeeCalculator(cfg *config.Config, state Chain, parentBlkTime time.Time) (*fee.Calculator, error) { var ( childBlkTime = state.GetTimestamp() isEActive = cfg.UpgradeConfig.IsEActivated(childBlkTime) - - feeCalculator *fee.Calculator ) if !isEActive { - feeCalculator = fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, childBlkTime) - } else { - feesCfg, err := fee.GetDynamicConfig(isEActive) - if err != nil { - return nil, fmt.Errorf("failed retrieving dynamic fees config: %w", err) - } - currentGasCap, err := state.GetCurrentGasCap() - if err != nil { - return nil, fmt.Errorf("failed retrieving gas cap: %w", err) - } + return fee.NewStaticCalculator(cfg.StaticFeeConfig, cfg.UpgradeConfig, childBlkTime), nil + } - elapsedTime := childBlkTime.Unix() - parentBlkTime.Unix() - maxGas := commonfees.MaxGas(feesCfg, currentGasCap, uint64(elapsedTime)) - feesMan := commonfees.NewManager(feesCfg.GasPrice) - feeCalculator = fee.NewDynamicCalculator(feesMan, maxGas) + feesCfg, err := fee.GetDynamicConfig(isEActive) + if err != nil { + return nil, fmt.Errorf("failed retrieving dynamic fees config: %w", err) + } + currentGasCap, err := state.GetCurrentGasCap() + if err != nil { + return nil, fmt.Errorf("failed retrieving gas cap: %w", err) + } + gasCap, err := commonfees.GasCap(feesCfg, currentGasCap, parentBlkTime, childBlkTime) + if err != nil { + return nil, fmt.Errorf("failed updating gas cap: %w", err) } + feesMan := commonfees.NewManager(feesCfg.GasPrice) + feeCalculator := fee.NewDynamicCalculator(feesMan, gasCap) return feeCalculator, nil } diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 0c85df173c69..81e2977aa8cc 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -83,7 +83,7 @@ func (c *Calculator) RemoveFeesFor(unitsToRm fees.Dimensions) (uint64, error) { func (c *Calculator) GetGas() fees.Gas { if c.c.feeManager != nil { - return c.c.feeManager.GetGas() + return c.c.feeManager.GetBlockGas() } return 0 } @@ -404,7 +404,7 @@ func (c *calculator) addFeesFor(complexity fees.Dimensions) (uint64, error) { return 0, fmt.Errorf("failed adding fees: %w", err) } - if err := c.feeManager.CumulateComplexity(txGas, c.maxGas); err != nil { + if err := c.feeManager.CumulateGas(txGas, c.maxGas); err != nil { return 0, fmt.Errorf("failed cumulating complexity: %w", err) } fee, err := c.feeManager.CalculateFee(txGas) @@ -430,7 +430,7 @@ func (c *calculator) removeFeesFor(unitsToRm fees.Dimensions) (uint64, error) { return 0, fmt.Errorf("failed adding fees: %w", err) } - if err := c.feeManager.RemoveComplexity(txGas); err != nil { + if err := c.feeManager.RemoveGas(txGas); err != nil { return 0, fmt.Errorf("failed removing units: %w", err) } fee, err := c.feeManager.CalculateFee(txGas) diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index ac5c150482c5..ae2db7a4c94c 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -59,25 +59,25 @@ func TestAddAndRemoveFees(t *testing.T) { feeDelta, err := fc.AddFeesFor(units) r.NoError(err) - r.Equal(gas, fc.c.feeManager.GetGas()) + r.Equal(gas, fc.c.feeManager.GetBlockGas()) r.NotZero(feeDelta) r.Equal(feeDelta, fc.c.fee) feeDelta2, err := fc.AddFeesFor(units) r.NoError(err) - r.Equal(doubleGas, fc.c.feeManager.GetGas()) + r.Equal(doubleGas, fc.c.feeManager.GetBlockGas()) r.Equal(feeDelta, feeDelta2) r.Equal(feeDelta+feeDelta2, fc.c.fee) feeDelta3, err := fc.RemoveFeesFor(units) r.NoError(err) - r.Equal(gas, fc.c.feeManager.GetGas()) + r.Equal(gas, fc.c.feeManager.GetBlockGas()) r.Equal(feeDelta, feeDelta3) r.Equal(feeDelta, fc.c.fee) feeDelta4, err := fc.RemoveFeesFor(units) r.NoError(err) - r.Zero(fc.c.feeManager.GetGas()) + r.Zero(fc.c.feeManager.GetBlockGas()) r.Equal(feeDelta, feeDelta4) r.Zero(fc.c.fee) } @@ -141,7 +141,7 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: addSubnetValidatorTx, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 19_110*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1911), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(1911), fc.feeManager.GetBlockGas()) }, }, { @@ -185,7 +185,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 19_540*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_954), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(1_954), fc.feeManager.GetBlockGas()) }, }, { @@ -221,7 +221,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 18_590*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_859), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(1_859), fc.feeManager.GetBlockGas()) }, }, { @@ -249,7 +249,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 18_870*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_887), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(1_887), fc.feeManager.GetBlockGas()) }, }, { @@ -277,7 +277,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 19_720*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_972), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(1_972), fc.feeManager.GetBlockGas()) }, }, { @@ -305,7 +305,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 19_030*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_903), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(1_903), fc.feeManager.GetBlockGas()) }, }, { @@ -349,7 +349,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 23_170*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(2_317), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(2_317), fc.feeManager.GetBlockGas()) }, }, { @@ -363,7 +363,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 23_170*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(2_317), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(2_317), fc.feeManager.GetBlockGas()) }, }, { @@ -410,7 +410,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 21_250*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(2_125), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(2_125), fc.feeManager.GetBlockGas()) }, }, { @@ -422,7 +422,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 21_250*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(2_125), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(2_125), fc.feeManager.GetBlockGas()) }, }, { @@ -454,7 +454,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 18_190*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_819), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(1_819), fc.feeManager.GetBlockGas()) }, }, { @@ -482,7 +482,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 31_230*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(3_123), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(3_123), fc.feeManager.GetBlockGas()) }, }, { @@ -510,7 +510,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 20_410*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(2_041), fc.feeManager.GetGas()) + require.Equal(t, fees.Gas(2_041), fc.feeManager.GetBlockGas()) }, }, { From 931561e57cf79f4a7c98b896294e234c6601f5f2 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 18 Jun 2024 12:47:37 +0200 Subject: [PATCH 105/120] renamed fees package to fee --- tests/e2e/p/workflow.go | 4 +- vms/components/{fees => fee}/config.go | 2 +- vms/components/{fees => fee}/dimensions.go | 2 +- vms/components/{fees => fee}/helpers.go | 2 +- vms/components/{fees => fee}/manager.go | 2 +- vms/platformvm/block/executor/block_state.go | 4 +- .../block/executor/proposal_block_test.go | 6 +- .../block/executor/standard_block_test.go | 6 +- vms/platformvm/block/executor/verifier.go | 5 +- .../block/executor/verifier_test.go | 12 ++-- vms/platformvm/config/execution_config.go | 4 +- vms/platformvm/metrics/metrics.go | 9 ++- vms/platformvm/metrics/no_op.go | 4 +- vms/platformvm/service_test.go | 6 +- vms/platformvm/state/block_helpers.go | 6 +- vms/platformvm/state/diff.go | 16 ++--- vms/platformvm/state/mock_state.go | 2 +- vms/platformvm/state/state.go | 22 +++---- vms/platformvm/txs/fee/calculator.go | 54 +++++++-------- vms/platformvm/txs/fee/calculator_test.go | 66 +++++++++---------- vms/platformvm/txs/fee/dynamic_config.go | 22 +++---- vms/platformvm/txs/fee/helpers.go | 16 ++--- wallet/chain/p/builder_test.go | 50 +++++++------- wallet/chain/p/wallet.go | 8 +-- 24 files changed, 165 insertions(+), 165 deletions(-) rename vms/components/{fees => fee}/config.go (99%) rename vms/components/{fees => fee}/dimensions.go (98%) rename vms/components/{fees => fee}/helpers.go (99%) rename vms/components/{fees => fee}/manager.go (99%) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index ec00a575370f..182d51c50925 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -23,7 +23,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ginkgo "github.com/onsi/ginkgo/v2" ) @@ -159,7 +159,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { feeCfg, err := fee.GetDynamicConfig(true /*isEActive*/) require.NoError(err) - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(feeCfg.GasPrice), fee.TempGasCap) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(feeCfg.GasPrice), fee.TempGasCap) pChainExportFee, err = feeCalc.ComputeFee(tx.Unsigned, tx.Creds) require.NoError(err) }) diff --git a/vms/components/fees/config.go b/vms/components/fee/config.go similarity index 99% rename from vms/components/fees/config.go rename to vms/components/fee/config.go index 36d2882453d3..68e3630536cf 100644 --- a/vms/components/fees/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. -package fees +package fee import ( "errors" diff --git a/vms/components/fees/dimensions.go b/vms/components/fee/dimensions.go similarity index 98% rename from vms/components/fees/dimensions.go rename to vms/components/fee/dimensions.go index e5c025b7a4c4..2be2c10a9d9e 100644 --- a/vms/components/fees/dimensions.go +++ b/vms/components/fee/dimensions.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 ( safemath "github.com/ava-labs/avalanchego/utils/math" diff --git a/vms/components/fees/helpers.go b/vms/components/fee/helpers.go similarity index 99% rename from vms/components/fees/helpers.go rename to vms/components/fee/helpers.go index 4908008013ce..192215b282a1 100644 --- a/vms/components/fees/helpers.go +++ b/vms/components/fee/helpers.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 ( "fmt" diff --git a/vms/components/fees/manager.go b/vms/components/fee/manager.go similarity index 99% rename from vms/components/fees/manager.go rename to vms/components/fee/manager.go index 0729d89bbc59..4d2212eb88e2 100644 --- a/vms/components/fees/manager.go +++ b/vms/components/fee/manager.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 ( "errors" diff --git a/vms/platformvm/block/executor/block_state.go b/vms/platformvm/block/executor/block_state.go index cdb3c7c8d2b7..2c12c867f207 100644 --- a/vms/platformvm/block/executor/block_state.go +++ b/vms/platformvm/block/executor/block_state.go @@ -12,7 +12,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/state" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) type proposalBlockState struct { @@ -32,6 +32,6 @@ type blockState struct { inputs set.Set[ids.ID] timestamp time.Time - blockGas commonfees.Gas + blockGas commonfee.Gas atomicRequests map[ids.ID]*atomic.Requests } diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index c38bf27f2c09..9b7a684fb762 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -29,7 +29,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -89,7 +89,7 @@ func TestApricotProposalBlockTimeVerification(t *testing.T) { // setup state to validate proposal block transaction onParentAccept.EXPECT().GetTimestamp().Return(chainTime).AnyTimes() - onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfees.Gas(1_000_000), nil) + onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfee.Gas(1_000_000), nil) currentStakersIt := state.NewMockStakerIterator(ctrl) currentStakersIt.EXPECT().Next().Return(true) @@ -162,7 +162,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { onParentAccept := state.NewMockDiff(ctrl) onParentAccept.EXPECT().GetTimestamp().Return(parentTime).AnyTimes() - onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfees.Gas(1_000_000), nil).AnyTimes() + onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfee.Gas(1_000_000), nil).AnyTimes() onParentAccept.EXPECT().GetCurrentSupply(constants.PrimaryNetworkID).Return(uint64(1000), nil).AnyTimes() env.blkManager.(*manager).blkIDToState[parentID] = &blockState{ diff --git a/vms/platformvm/block/executor/standard_block_test.go b/vms/platformvm/block/executor/standard_block_test.go index ad279a4e24b7..496cd38f032e 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -24,7 +24,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) @@ -58,7 +58,7 @@ func TestApricotStandardBlockTimeVerification(t *testing.T) { env.mockedState.EXPECT().GetLastAccepted().Return(parentID).AnyTimes() env.mockedState.EXPECT().GetTimestamp().Return(chainTime).AnyTimes() onParentAccept.EXPECT().GetTimestamp().Return(chainTime).AnyTimes() - onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfees.ZeroGas, nil).AnyTimes() + onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfee.ZeroGas, nil).AnyTimes() // wrong height apricotChildBlk, err := block.NewApricotStandardBlock( @@ -152,7 +152,7 @@ func TestBanffStandardBlockTimeVerification(t *testing.T) { } utxoID := utxo.InputID() onParentAccept.EXPECT().GetUTXO(utxoID).Return(utxo, nil).AnyTimes() - onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfees.ZeroGas, nil).AnyTimes() + onParentAccept.EXPECT().GetCurrentGasCap().Return(commonfee.ZeroGas, nil).AnyTimes() // Create the tx utx := &txs.CreateSubnetTx{ diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 837fe73cd6a0..273280adbc18 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -10,13 +10,14 @@ import ( "github.com/ava-labs/avalanchego/chains/atomic" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/fees" "github.com/ava-labs/avalanchego/vms/platformvm/block" "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/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + fee1 "github.com/ava-labs/avalanchego/vms/components/fee" ) var ( @@ -251,7 +252,7 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { inputs: atomicExecutor.Inputs, timestamp: atomicExecutor.OnAccept.GetTimestamp(), - blockGas: fees.ZeroGas, + blockGas: fee1.ZeroGas, atomicRequests: atomicExecutor.AtomicRequests, } return nil diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index 23c0180ba67f..9f69653654a1 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -36,7 +36,7 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) @@ -525,9 +525,9 @@ func TestStandardBlockGas(t *testing.T) { require.True(found) if dynamicFeesActive { - require.NotEqual(commonfees.ZeroGas, blkState.blockGas) + require.NotEqual(commonfee.ZeroGas, blkState.blockGas) } else { - require.Equal(commonfees.ZeroGas, blkState.blockGas) + require.Equal(commonfee.ZeroGas, blkState.blockGas) } }) } @@ -546,7 +546,7 @@ func TestVerifierVisitProposalBlock(t *testing.T) { timestamp := time.Now() // One call for each of onCommitState and onAbortState. parentOnAcceptState.EXPECT().GetTimestamp().Return(timestamp).Times(2) - parentOnAcceptState.EXPECT().GetCurrentGasCap().Return(commonfees.Gas(1_000_000), nil) + parentOnAcceptState.EXPECT().GetCurrentGasCap().Return(commonfee.Gas(1_000_000), nil) backend := &backend{ lastAccepted: parentID, @@ -800,7 +800,7 @@ func TestVerifierVisitStandardBlock(t *testing.T) { // Set expectations for dependencies. timestamp := time.Now() parentState.EXPECT().GetTimestamp().Return(timestamp) - parentState.EXPECT().GetCurrentGasCap().Return(commonfees.Gas(1_000_000), nil) + parentState.EXPECT().GetCurrentGasCap().Return(commonfee.Gas(1_000_000), nil) parentStatelessBlk.EXPECT().Height().Return(uint64(1)) mempool.EXPECT().Remove(apricotBlk.Txs()).Times(1) @@ -1295,7 +1295,7 @@ func TestVerifierVisitStandardBlockWithDuplicateInputs(t *testing.T) { timestamp := time.Now() parentStatelessBlk.EXPECT().Height().Return(uint64(1)) parentState.EXPECT().GetTimestamp().Return(timestamp) - parentState.EXPECT().GetCurrentGasCap().Return(commonfees.Gas(1_000_000), nil) + parentState.EXPECT().GetCurrentGasCap().Return(commonfee.Gas(1_000_000), nil) parentStatelessBlk.EXPECT().Parent().Return(grandParentID).Times(1) diff --git a/vms/platformvm/config/execution_config.go b/vms/platformvm/config/execution_config.go index 4ceaa7992887..4b1a0716f948 100644 --- a/vms/platformvm/config/execution_config.go +++ b/vms/platformvm/config/execution_config.go @@ -10,7 +10,7 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/network" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) var DefaultExecutionConfig = ExecutionConfig{ @@ -42,7 +42,7 @@ type ExecutionConfig struct { MempoolPruneFrequency time.Duration `json:"mempool-prune-frequency"` // test nets are allow to configure ad-hoc dynamic fees configuration - DynamicFeesConfig *commonfees.DynamicFeesConfig `json:"dynamic-fees-config"` + DynamicFeesConfig *commonfee.DynamicFeesConfig `json:"dynamic-fees-config"` } // GetExecutionConfig returns an ExecutionConfig diff --git a/vms/platformvm/metrics/metrics.go b/vms/platformvm/metrics/metrics.go index 3a3773708562..f82675ca4671 100644 --- a/vms/platformvm/metrics/metrics.go +++ b/vms/platformvm/metrics/metrics.go @@ -13,7 +13,7 @@ import ( "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/avalanchego/vms/platformvm/block" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) var _ Metrics = (*metrics)(nil) @@ -40,9 +40,8 @@ type Metrics interface { SetTimeUntilUnstake(time.Duration) // Mark when this node will unstake from a subnet. SetTimeUntilSubnetUnstake(subnetID ids.ID, timeUntilUnstake time.Duration) - - // Mark cumulated complexity of the latest accepted block - SetBlockGas(commonfees.Gas) + // Mark gas cumulated across txs of last accepted block + SetBlockGas(commonfee.Gas) } func New(registerer prometheus.Registerer) (Metrics, error) { @@ -165,6 +164,6 @@ func (m *metrics) SetTimeUntilSubnetUnstake(subnetID ids.ID, timeUntilUnstake ti m.timeUntilSubnetUnstake.WithLabelValues(subnetID.String()).Set(float64(timeUntilUnstake)) } -func (m *metrics) SetBlockGas(g commonfees.Gas) { +func (m *metrics) SetBlockGas(g commonfee.Gas) { m.blockGas.Set(float64(g)) } diff --git a/vms/platformvm/metrics/no_op.go b/vms/platformvm/metrics/no_op.go index f01c6458d74e..0fe89903ca6b 100644 --- a/vms/platformvm/metrics/no_op.go +++ b/vms/platformvm/metrics/no_op.go @@ -12,7 +12,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/vms/platformvm/block" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) var Noop Metrics = noopMetrics{} @@ -53,4 +53,4 @@ func (noopMetrics) SetSubnetPercentConnected(ids.ID, float64) {} func (noopMetrics) SetPercentConnected(float64) {} -func (noopMetrics) SetBlockGas(commonfees.Gas) {} +func (noopMetrics) SetBlockGas(commonfee.Gas) {} diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index e673f7ed1825..3e3af5a01dc8 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -45,7 +45,7 @@ import ( "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" avajson "github.com/ava-labs/avalanchego/utils/json" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" vmkeystore "github.com/ava-labs/avalanchego/vms/components/keystore" pchainapi "github.com/ava-labs/avalanchego/vms/platformvm/api" blockbuilder "github.com/ava-labs/avalanchego/vms/platformvm/block/builder" @@ -96,11 +96,11 @@ func testReplayFeeCalculator(cfg *config.Config, parentBlkTime time.Time, state if err != nil { return nil, fmt.Errorf("failed retrieving current gas cap: %w", err) } - gasCap, err := commonfees.GasCap(feesCfg, currentGasCap, parentBlkTime, childBlkTime) + gasCap, err := commonfee.GasCap(feesCfg, currentGasCap, parentBlkTime, childBlkTime) if err != nil { return nil, fmt.Errorf("failed updating gas cap: %w", err) } - feesMan := commonfees.NewManager(feesCfg.GasPrice) + feesMan := commonfee.NewManager(feesCfg.GasPrice) return fee.NewDynamicCalculator(feesMan, gasCap), nil } diff --git a/vms/platformvm/state/block_helpers.go b/vms/platformvm/state/block_helpers.go index 8d480e6b196a..f9deed03b99f 100644 --- a/vms/platformvm/state/block_helpers.go +++ b/vms/platformvm/state/block_helpers.go @@ -12,7 +12,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) func NextBlockTime(state Chain, clk *mockable.Clock) (time.Time, bool, error) { @@ -93,11 +93,11 @@ func PickFeeCalculator(cfg *config.Config, state Chain, parentBlkTime time.Time) if err != nil { return nil, fmt.Errorf("failed retrieving gas cap: %w", err) } - gasCap, err := commonfees.GasCap(feesCfg, currentGasCap, parentBlkTime, childBlkTime) + gasCap, err := commonfee.GasCap(feesCfg, currentGasCap, parentBlkTime, childBlkTime) if err != nil { return nil, fmt.Errorf("failed updating gas cap: %w", err) } - feesMan := commonfees.NewManager(feesCfg.GasPrice) + feesMan := commonfee.NewManager(feesCfg.GasPrice) feeCalculator := fee.NewDynamicCalculator(feesMan, gasCap) return feeCalculator, nil } diff --git a/vms/platformvm/state/diff.go b/vms/platformvm/state/diff.go index 9f2134f06105..f4fa883288ed 100644 --- a/vms/platformvm/state/diff.go +++ b/vms/platformvm/state/diff.go @@ -15,7 +15,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) var ( @@ -37,7 +37,7 @@ type diff struct { timestamp time.Time - currentGasCap *commonfees.Gas + currentGasCap *commonfee.Gas // Subnet ID --> supply of native asset of the subnet currentSupply map[ids.ID]uint64 @@ -93,27 +93,27 @@ func NewDiffOn(parentState Chain) (Diff, error) { }) } -func (d *diff) GetCurrentGasCap() (commonfees.Gas, error) { +func (d *diff) GetCurrentGasCap() (commonfee.Gas, error) { if d.currentGasCap == nil { parentState, ok := d.stateVersions.GetState(d.parentID) if !ok { - return commonfees.ZeroGas, fmt.Errorf("%w: %s", ErrMissingParentState, d.parentID) + return commonfee.ZeroGas, fmt.Errorf("%w: %s", ErrMissingParentState, d.parentID) } parentCurrentGasCap, err := parentState.GetCurrentGasCap() if err != nil { - return commonfees.ZeroGas, err + return commonfee.ZeroGas, err } - d.currentGasCap = new(commonfees.Gas) + d.currentGasCap = new(commonfee.Gas) *d.currentGasCap = parentCurrentGasCap } return *d.currentGasCap, nil } -func (d *diff) SetCurrentGasCap(gasCap commonfees.Gas) { +func (d *diff) SetCurrentGasCap(gasCap commonfee.Gas) { if d.currentGasCap == nil { - d.currentGasCap = new(commonfees.Gas) + d.currentGasCap = new(commonfee.Gas) } *d.currentGasCap = gasCap } diff --git a/vms/platformvm/state/mock_state.go b/vms/platformvm/state/mock_state.go index bf49f002089a..2174ab4e264f 100644 --- a/vms/platformvm/state/mock_state.go +++ b/vms/platformvm/state/mock_state.go @@ -20,7 +20,7 @@ import ( validators "github.com/ava-labs/avalanchego/snow/validators" logging "github.com/ava-labs/avalanchego/utils/logging" avax "github.com/ava-labs/avalanchego/vms/components/avax" - fees "github.com/ava-labs/avalanchego/vms/components/fees" + fees "github.com/ava-labs/avalanchego/vms/components/fee" block "github.com/ava-labs/avalanchego/vms/platformvm/block" fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" status "github.com/ava-labs/avalanchego/vms/platformvm/status" diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index c2aad726e2af..dd956b32c5ff 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -45,7 +45,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" safemath "github.com/ava-labs/avalanchego/utils/math" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) const ( @@ -99,8 +99,8 @@ type Chain interface { avax.UTXOGetter avax.UTXODeleter - GetCurrentGasCap() (commonfees.Gas, error) - SetCurrentGasCap(commonfees.Gas) + GetCurrentGasCap() (commonfee.Gas, error) + SetCurrentGasCap(commonfee.Gas) GetTimestamp() time.Time SetTimestamp(tm time.Time) @@ -361,7 +361,7 @@ type state struct { // The persisted fields represent the current database value timestamp, persistedTimestamp time.Time - currentGasCap *commonfees.Gas + currentGasCap *commonfee.Gas currentSupply, persistedCurrentSupply uint64 // [lastAccepted] is the most recently accepted block. lastAccepted, persistedLastAccepted ids.ID @@ -1006,16 +1006,16 @@ func (s *state) GetStartTime(nodeID ids.NodeID, subnetID ids.ID) (time.Time, err return staker.StartTime, nil } -func (s *state) GetCurrentGasCap() (commonfees.Gas, error) { +func (s *state) GetCurrentGasCap() (commonfee.Gas, error) { if s.currentGasCap == nil { - return commonfees.ZeroGas, nil + return commonfee.ZeroGas, nil } return *s.currentGasCap, nil } -func (s *state) SetCurrentGasCap(gasCap commonfees.Gas) { +func (s *state) SetCurrentGasCap(gasCap commonfee.Gas) { if s.currentGasCap == nil { - s.currentGasCap = new(commonfees.Gas) + s.currentGasCap = new(commonfee.Gas) } *s.currentGasCap = gasCap } @@ -1316,8 +1316,8 @@ func (s *state) loadMetadata() error { if err != nil { return err } - s.currentGasCap = new(commonfees.Gas) - *s.currentGasCap = commonfees.Gas(gas) + s.currentGasCap = new(commonfee.Gas) + *s.currentGasCap = commonfee.Gas(gas) case database.ErrNotFound: // fork introducing dynamic fees may not be active yet, @@ -1327,7 +1327,7 @@ func (s *state) loadMetadata() error { if err != nil { return fmt.Errorf("failed retrieving dynamic fees config: %w", err) } - s.currentGasCap = new(commonfees.Gas) + s.currentGasCap = new(commonfee.Gas) *s.currentGasCap = feesCfg.MaxGasPerSecond default: diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 81e2977aa8cc..072cb50b53bd 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -12,7 +12,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/fees" + "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" @@ -41,8 +41,8 @@ func NewStaticCalculator( // NewDynamicCalculator must be used post E upgrade activation func NewDynamicCalculator( - feeManager *fees.Manager, - maxGas fees.Gas, + feeManager *fee.Manager, + maxGas fee.Gas, ) *Calculator { return &Calculator{ c: &calculator{ @@ -73,15 +73,15 @@ func (c *Calculator) ComputeFee(tx txs.UnsignedTx, creds []verify.Verifiable) (u return c.c.fee, err } -func (c *Calculator) AddFeesFor(complexity fees.Dimensions) (uint64, error) { +func (c *Calculator) AddFeesFor(complexity fee.Dimensions) (uint64, error) { return c.c.addFeesFor(complexity) } -func (c *Calculator) RemoveFeesFor(unitsToRm fees.Dimensions) (uint64, error) { +func (c *Calculator) RemoveFeesFor(unitsToRm fee.Dimensions) (uint64, error) { return c.c.removeFeesFor(unitsToRm) } -func (c *Calculator) GetGas() fees.Gas { +func (c *Calculator) GetGas() fee.Gas { if c.c.feeManager != nil { return c.c.feeManager.GetBlockGas() } @@ -98,8 +98,8 @@ type calculator struct { time time.Time // Post E-upgrade inputs - feeManager *fees.Manager - maxGas fees.Gas + feeManager *fee.Manager + maxGas fee.Gas credentials []verify.Verifiable // outputs of visitor execution @@ -335,14 +335,14 @@ func (c *calculator) meterTx( uTx txs.UnsignedTx, allOuts []*avax.TransferableOutput, allIns []*avax.TransferableInput, -) (fees.Dimensions, error) { - var complexity fees.Dimensions +) (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[fees.Bandwidth] = uint64(uTxSize) + 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) @@ -351,37 +351,37 @@ func (c *calculator) meterTx( if !ok { return complexity, fmt.Errorf("don't know how to calculate complexity of %T", cred) } - credDimensions, err := fees.MeterCredential(txs.Codec, txs.CodecVersion, len(c.Sigs)) + 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 = fees.Add(complexity, credDimensions) + complexity, err = fee.Add(complexity, credDimensions) if err != nil { return complexity, fmt.Errorf("failed adding credentials: %w", err) } } - complexity[fees.Bandwidth] += wrappers.IntLen // length of the credentials slice - complexity[fees.Bandwidth] += codec.VersionSize + complexity[fee.Bandwidth] += wrappers.IntLen // length of the credentials slice + complexity[fee.Bandwidth] += codec.VersionSize for _, in := range allIns { - inputDimensions, err := fees.MeterInput(txs.Codec, txs.CodecVersion, in) + inputDimensions, err := fee.MeterInput(txs.Codec, txs.CodecVersion, in) if err != nil { return complexity, fmt.Errorf("failed retrieving size of inputs: %w", err) } - inputDimensions[fees.Bandwidth] = 0 // inputs bandwidth is already accounted for above, so we zero it - complexity, err = fees.Add(complexity, inputDimensions) + 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 := fees.MeterOutput(txs.Codec, txs.CodecVersion, out) + outputDimensions, err := fee.MeterOutput(txs.Codec, txs.CodecVersion, out) if err != nil { return complexity, fmt.Errorf("failed retrieving size of outputs: %w", err) } - outputDimensions[fees.Bandwidth] = 0 // outputs bandwidth is already accounted for above, so we zero it - complexity, err = fees.Add(complexity, outputDimensions) + 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) } @@ -390,8 +390,8 @@ func (c *calculator) meterTx( return complexity, nil } -func (c *calculator) addFeesFor(complexity fees.Dimensions) (uint64, error) { - if c.feeManager == nil || complexity == fees.Empty { +func (c *calculator) addFeesFor(complexity fee.Dimensions) (uint64, error) { + if c.feeManager == nil || complexity == fee.Empty { return 0, nil } @@ -399,7 +399,7 @@ func (c *calculator) addFeesFor(complexity fees.Dimensions) (uint64, error) { if err != nil { return 0, fmt.Errorf("failed adding fees: %w", err) } - txGas, err := fees.ScalarProd(complexity, feeCfg.FeeDimensionWeights) + txGas, err := fee.ScalarProd(complexity, feeCfg.FeeDimensionWeights) if err != nil { return 0, fmt.Errorf("failed adding fees: %w", err) } @@ -416,8 +416,8 @@ func (c *calculator) addFeesFor(complexity fees.Dimensions) (uint64, error) { return fee, nil } -func (c *calculator) removeFeesFor(unitsToRm fees.Dimensions) (uint64, error) { - if c.feeManager == nil || unitsToRm == fees.Empty { +func (c *calculator) removeFeesFor(unitsToRm fee.Dimensions) (uint64, error) { + if c.feeManager == nil || unitsToRm == fee.Empty { return 0, nil } @@ -425,7 +425,7 @@ func (c *calculator) removeFeesFor(unitsToRm fees.Dimensions) (uint64, error) { if err != nil { return 0, fmt.Errorf("failed adding fees: %w", err) } - txGas, err := fees.ScalarProd(unitsToRm, feeCfg.FeeDimensionWeights) + txGas, err := fee.ScalarProd(unitsToRm, feeCfg.FeeDimensionWeights) if err != nil { return 0, fmt.Errorf("failed adding fees: %w", err) } diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index ae2db7a4c94c..946d80428fea 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -18,7 +18,7 @@ import ( "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/fees" + "github.com/ava-labs/avalanchego/vms/components/fee" "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/signer" @@ -29,9 +29,9 @@ import ( ) var ( - testGasPrice = fees.GasPrice(10 * units.NanoAvax) + testGasPrice = fee.GasPrice(10 * units.NanoAvax) - testBlockMaxGas = fees.Gas(100_000) + testBlockMaxGas = fee.Gas(100_000) preFundedKeys = secp256k1.TestKeys() feeTestSigners = [][]*secp256k1.PrivateKey{preFundedKeys} @@ -46,15 +46,15 @@ func TestAddAndRemoveFees(t *testing.T) { fc := &Calculator{ c: &calculator{ isEActive: true, - feeManager: fees.NewManager(testGasPrice), + feeManager: fee.NewManager(testGasPrice), maxGas: testBlockMaxGas, }, } var ( - units = fees.Dimensions{1, 2, 3, 4} - gas = fees.Gas(10) - doubleGas = fees.Gas(20) + units = fee.Dimensions{1, 2, 3, 4} + gas = fee.Gas(10) + doubleGas = fee.Gas(20) ) feeDelta, err := fc.AddFeesFor(units) @@ -114,7 +114,7 @@ func TestTxFees(t *testing.T) { name string chainTime time.Time unsignedAndSignedTx func(t *testing.T) (txs.UnsignedTx, *txs.Tx) - maxGasF func() fees.Gas + maxGasF func() fee.Gas expectedError error checksF func(*testing.T, *calculator) }{ @@ -141,13 +141,13 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: addSubnetValidatorTx, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 19_110*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1911), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(1911), fc.feeManager.GetBlockGas()) }, }, { name: "AddSubnetValidatorTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fees.Gas { + maxGasF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: addSubnetValidatorTx, @@ -185,14 +185,14 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 19_540*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_954), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(1_954), fc.feeManager.GetBlockGas()) }, }, { name: "CreateChainTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, unsignedAndSignedTx: createChainTx, - maxGasF: func() fees.Gas { + maxGasF: func() fee.Gas { return testBlockMaxGas - 1 }, expectedError: errFailedComplexityCumulation, @@ -221,14 +221,14 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 18_590*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_859), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(1_859), fc.feeManager.GetBlockGas()) }, }, { name: "CreateSubnetTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, unsignedAndSignedTx: createSubnetTx, - maxGasF: func() fees.Gas { + maxGasF: func() fee.Gas { return testBlockMaxGas - 1 }, expectedError: errFailedComplexityCumulation, @@ -249,13 +249,13 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 18_870*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_887), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(1_887), fc.feeManager.GetBlockGas()) }, }, { name: "RemoveSubnetValidatorTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fees.Gas { + maxGasF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: removeSubnetValidatorTx, @@ -277,13 +277,13 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 19_720*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_972), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(1_972), fc.feeManager.GetBlockGas()) }, }, { name: "TransformSubnetTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fees.Gas { + maxGasF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: transformSubnetTx, @@ -305,13 +305,13 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 19_030*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_903), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(1_903), fc.feeManager.GetBlockGas()) }, }, { name: "TransferSubnetOwnershipTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fees.Gas { + maxGasF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: transferSubnetOwnershipTx, @@ -349,7 +349,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 23_170*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(2_317), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(2_317), fc.feeManager.GetBlockGas()) }, }, { @@ -363,13 +363,13 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 23_170*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(2_317), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(2_317), fc.feeManager.GetBlockGas()) }, }, { name: "AddPermissionlessValidatorTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fees.Gas { + maxGasF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { @@ -410,7 +410,7 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 21_250*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(2_125), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(2_125), fc.feeManager.GetBlockGas()) }, }, { @@ -422,13 +422,13 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 21_250*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(2_125), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(2_125), fc.feeManager.GetBlockGas()) }, }, { name: "AddPermissionlessDelegatorTx Subnet post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fees.Gas { + maxGasF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { @@ -454,13 +454,13 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 18_190*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(1_819), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(1_819), fc.feeManager.GetBlockGas()) }, }, { name: "BaseTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fees.Gas { + maxGasF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: baseTx, @@ -482,13 +482,13 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 31_230*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(3_123), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(3_123), fc.feeManager.GetBlockGas()) }, }, { name: "ImportTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fees.Gas { + maxGasF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: importTx, @@ -510,13 +510,13 @@ func TestTxFees(t *testing.T) { expectedError: nil, checksF: func(t *testing.T, fc *calculator) { require.Equal(t, 20_410*units.NanoAvax, fc.fee) - require.Equal(t, fees.Gas(2_041), fc.feeManager.GetBlockGas()) + require.Equal(t, fee.Gas(2_041), fc.feeManager.GetBlockGas()) }, }, { name: "ExportTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fees.Gas { + maxGasF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: exportTx, @@ -562,7 +562,7 @@ func TestTxFees(t *testing.T) { if !upgrades.IsEActivated(tt.chainTime) { fc = NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) } else { - fc = NewDynamicCalculator(fees.NewManager(testGasPrice), maxComplexity) + fc = NewDynamicCalculator(fee.NewManager(testGasPrice), maxComplexity) } var creds []verify.Verifiable diff --git a/vms/platformvm/txs/fee/dynamic_config.go b/vms/platformvm/txs/fee/dynamic_config.go index 10abf02a2d53..b849152dcba2 100644 --- a/vms/platformvm/txs/fee/dynamic_config.go +++ b/vms/platformvm/txs/fee/dynamic_config.go @@ -11,22 +11,22 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/units" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) -const TempGasCap = commonfees.Gas(1_000_000) // TODO ABENEGIA: temp const to be replaced with API call +const TempGasCap = commonfee.Gas(1_000_000) // TODO ABENEGIA: temp const to be replaced with API call var ( errDynamicFeeConfigNotAvailable = errors.New("dynamic fee config not available") - eUpgradeDynamicFeesConfig = commonfees.DynamicFeesConfig{ - GasPrice: commonfees.GasPrice(10 * units.NanoAvax), - FeeDimensionWeights: commonfees.Dimensions{1, 1, 1, 1}, - MaxGasPerSecond: commonfees.Gas(1_000_000), - LeakGasCoeff: commonfees.Gas(1), + 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 *commonfees.DynamicFeesConfig + customDynamicFeesConfig *commonfee.DynamicFeesConfig ) func init() { @@ -35,9 +35,9 @@ func init() { } } -func GetDynamicConfig(isEActive bool) (commonfees.DynamicFeesConfig, error) { +func GetDynamicConfig(isEActive bool) (commonfee.DynamicFeesConfig, error) { if !isEActive { - return commonfees.DynamicFeesConfig{}, errDynamicFeeConfigNotAvailable + return commonfee.DynamicFeesConfig{}, errDynamicFeeConfigNotAvailable } if customDynamicFeesConfig != nil { @@ -46,7 +46,7 @@ func GetDynamicConfig(isEActive bool) (commonfees.DynamicFeesConfig, error) { return eUpgradeDynamicFeesConfig, nil } -func ResetDynamicConfig(ctx *snow.Context, customFeesConfig *commonfees.DynamicFeesConfig) error { +func ResetDynamicConfig(ctx *snow.Context, customFeesConfig *commonfee.DynamicFeesConfig) error { if customFeesConfig == nil { return nil // nothing to do } diff --git a/vms/platformvm/txs/fee/helpers.go b/vms/platformvm/txs/fee/helpers.go index 4148a79aae9b..b75af197ac46 100644 --- a/vms/platformvm/txs/fee/helpers.go +++ b/vms/platformvm/txs/fee/helpers.go @@ -7,7 +7,7 @@ import ( "fmt" "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/fees" + "github.com/ava-labs/avalanchego/vms/components/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs" ) @@ -16,7 +16,7 @@ func FinanceInput(feeCalc *Calculator, input *avax.TransferableInput) (uint64, e return 0, nil // pre E-upgrade we have a fixed fee regardless how complex the input is } - inDimensions, err := fees.MeterInput(txs.Codec, txs.CodecVersion, input) + inDimensions, err := fee.MeterInput(txs.Codec, txs.CodecVersion, input) if err != nil { return 0, fmt.Errorf("failed calculating input size: %w", err) } @@ -27,18 +27,18 @@ func FinanceInput(feeCalc *Calculator, input *avax.TransferableInput) (uint64, e return addedFees, nil } -func FinanceOutput(feeCalc *Calculator, output *avax.TransferableOutput) (uint64, fees.Dimensions, error) { +func FinanceOutput(feeCalc *Calculator, output *avax.TransferableOutput) (uint64, fee.Dimensions, error) { if !feeCalc.c.isEActive { - return 0, fees.Empty, nil // pre E-upgrade we have a fixed fee regardless how complex the output is + return 0, fee.Empty, nil // pre E-upgrade we have a fixed fee regardless how complex the output is } - outDimensions, err := fees.MeterOutput(txs.Codec, txs.CodecVersion, output) + outDimensions, err := fee.MeterOutput(txs.Codec, txs.CodecVersion, output) if err != nil { - return 0, fees.Empty, fmt.Errorf("failed calculating changeOut size: %w", err) + return 0, fee.Empty, fmt.Errorf("failed calculating changeOut size: %w", err) } addedFees, err := feeCalc.AddFeesFor(outDimensions) if err != nil { - return 0, fees.Empty, fmt.Errorf("account for stakedOut fees: %w", err) + return 0, fee.Empty, fmt.Errorf("account for stakedOut fees: %w", err) } return addedFees, outDimensions, nil } @@ -48,7 +48,7 @@ func FinanceCredential(feeCalc *Calculator, keysCount int) (uint64, error) { return 0, nil // pre E-upgrade we have a fixed fee regardless how complex the credentials are } - credDimensions, err := fees.MeterCredential(txs.Codec, txs.CodecVersion, keysCount) + credDimensions, err := fee.MeterCredential(txs.Codec, txs.CodecVersion, keysCount) if err != nil { return 0, fmt.Errorf("failed calculating input size: %w", err) } diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index ca8855148d6b..e9c68d14d0d9 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -30,7 +30,7 @@ import ( "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" stdcontext "context" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) @@ -56,8 +56,8 @@ var ( } testStaticConfig = staticFeesConfigFromContext(testContext) - testGasPrice = commonfees.GasPrice(10 * units.MicroAvax) - testBlockMaxGas = commonfees.Gas(100_000) + testGasPrice = commonfee.GasPrice(10 * units.MicroAvax) + testBlockMaxGas = commonfee.Gas(100_000) ) // These tests create a tx, then verify that utxos included in the tx are @@ -95,7 +95,7 @@ func TestBaseTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewBaseTx( outputsToMove, feeCalc, @@ -105,7 +105,7 @@ func TestBaseTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(30_620*units.MicroAvax, fee) @@ -199,14 +199,14 @@ func TestAddSubnetValidatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewAddSubnetValidatorTx(subnetValidator, feeCalc) require.NoError(err) tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(30_610*units.MicroAvax, fee) @@ -287,7 +287,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewRemoveSubnetValidatorTx( ids.GenerateTestNodeID(), subnetID, @@ -298,7 +298,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(30_370*units.MicroAvax, fee) @@ -389,7 +389,7 @@ func TestCreateChainTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewCreateChainTx( subnetID, genesisBytes, @@ -403,7 +403,7 @@ func TestCreateChainTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(31_040*units.MicroAvax, fee) @@ -491,7 +491,7 @@ func TestCreateSubnetTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewCreateSubnetTx( subnetOwner, feeCalc, @@ -501,7 +501,7 @@ func TestCreateSubnetTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(29_400*units.MicroAvax, fee) @@ -585,7 +585,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewTransferSubnetOwnershipTx( subnetID, subnetOwner, @@ -596,7 +596,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(30_570*units.MicroAvax, fee) @@ -675,7 +675,7 @@ func TestImportTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewImportTx( sourceChainID, importTo, @@ -686,7 +686,7 @@ func TestImportTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(42_770*units.MicroAvax, fee) @@ -765,7 +765,7 @@ func TestExportTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewExportTx( subnetID, exportedOutputs, @@ -776,7 +776,7 @@ func TestExportTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(30_980*units.MicroAvax, fee) @@ -867,7 +867,7 @@ func TestTransformSubnetTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewTransformSubnetTx( subnetID, subnetAssetID, @@ -890,7 +890,7 @@ func TestTransformSubnetTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(46_250*units.MicroAvax, fee) @@ -989,7 +989,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { require.NoError(err) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1011,7 +1011,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(65_240*units.MicroAvax, fee) @@ -1108,7 +1108,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) utx, err := builder.NewAddPermissionlessDelegatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1127,7 +1127,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfees.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(63_320*units.MicroAvax, fee) diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index 35c4866f8c48..ba3df0a092b6 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -20,7 +20,7 @@ import ( "github.com/ava-labs/avalanchego/wallet/chain/p/builder" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" - commonfees "github.com/ava-labs/avalanchego/vms/components/fees" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" vmsigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) @@ -293,8 +293,8 @@ type wallet struct { isEForkActive bool staticFeesConfig fee.StaticConfig - gasPrice commonfees.GasPrice - maxComplexity commonfees.Gas + gasPrice commonfee.GasPrice + maxComplexity commonfee.Gas } func (w *wallet) Builder() builder.Builder { @@ -633,7 +633,7 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( if !w.isEForkActive { feeCalculator = fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Config{}, time.Time{}) } else { - feeMan := commonfees.NewManager(w.gasPrice) + feeMan := commonfee.NewManager(w.gasPrice) feeCalculator = fee.NewDynamicCalculator(feeMan, fee.TempGasCap) } return feeCalculator, nil From 4f71f0c721816a9aa7e920427ac7a43b6f851228 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 18 Jun 2024 13:05:12 +0200 Subject: [PATCH 106/120] calculator ctor cleanup --- tests/e2e/p/workflow.go | 3 +- vms/components/fee/manager.go | 9 +++-- vms/platformvm/service_test.go | 3 +- vms/platformvm/state/block_helpers.go | 3 +- vms/platformvm/txs/fee/calculator.go | 11 ++---- vms/platformvm/txs/fee/calculator_test.go | 35 +++++++++--------- wallet/chain/p/builder_test.go | 44 +++++++++++------------ wallet/chain/p/wallet.go | 7 ++-- 8 files changed, 54 insertions(+), 61 deletions(-) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 182d51c50925..b30d82004671 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -23,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ginkgo "github.com/onsi/ginkgo/v2" ) @@ -159,7 +158,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { feeCfg, err := fee.GetDynamicConfig(true /*isEActive*/) require.NoError(err) - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(feeCfg.GasPrice), fee.TempGasCap) + feeCalc := fee.NewDynamicCalculator(feeCfg.GasPrice, fee.TempGasCap) pChainExportFee, err = feeCalc.ComputeFee(tx.Unsigned, tx.Creds) require.NoError(err) }) diff --git a/vms/components/fee/manager.go b/vms/components/fee/manager.go index 4d2212eb88e2..10e0f56b1d5f 100644 --- a/vms/components/fee/manager.go +++ b/vms/components/fee/manager.go @@ -13,6 +13,8 @@ import ( var errGasBoundBreached = errors.New("gas bound breached") type Manager struct { + gasCap Gas + // Avax denominated gas price, i.e. fee per unit of complexity. gasPrice GasPrice @@ -21,8 +23,9 @@ type Manager struct { blockGas Gas } -func NewManager(gasPrice GasPrice) *Manager { +func NewManager(gasPrice GasPrice, gasCap Gas) *Manager { return &Manager{ + gasCap: gasCap, gasPrice: gasPrice, } } @@ -43,13 +46,13 @@ func (m *Manager) CalculateFee(g Gas) (uint64, error) { // CumulateGas tries to cumulate the consumed gas [units]. Before // actually cumulating it, it checks whether the result would breach [bounds]. // If so, it returns the first dimension to breach bounds. -func (m *Manager) CumulateGas(gas, bound Gas) error { +func (m *Manager) CumulateGas(gas Gas) error { // Ensure we can consume (don't want partial update of values) blkGas, err := safemath.Add64(uint64(m.blockGas), uint64(gas)) if err != nil { return fmt.Errorf("%w: %w", errGasBoundBreached, err) } - if Gas(blkGas) > bound { + if Gas(blkGas) > m.gasCap { return errGasBoundBreached } diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 3e3af5a01dc8..4210d0754e4f 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -100,8 +100,7 @@ func testReplayFeeCalculator(cfg *config.Config, parentBlkTime time.Time, state if err != nil { return nil, fmt.Errorf("failed updating gas cap: %w", err) } - feesMan := commonfee.NewManager(feesCfg.GasPrice) - return fee.NewDynamicCalculator(feesMan, gasCap), nil + return fee.NewDynamicCalculator(feesCfg.GasPrice, gasCap), nil } func defaultService(t *testing.T) (*Service, *mutableSharedMemory, *txstest.WalletFactory) { diff --git a/vms/platformvm/state/block_helpers.go b/vms/platformvm/state/block_helpers.go index f9deed03b99f..e05de8e1ddc3 100644 --- a/vms/platformvm/state/block_helpers.go +++ b/vms/platformvm/state/block_helpers.go @@ -97,7 +97,6 @@ func PickFeeCalculator(cfg *config.Config, state Chain, parentBlkTime time.Time) if err != nil { return nil, fmt.Errorf("failed updating gas cap: %w", err) } - feesMan := commonfee.NewManager(feesCfg.GasPrice) - feeCalculator := fee.NewDynamicCalculator(feesMan, gasCap) + feeCalculator := fee.NewDynamicCalculator(feesCfg.GasPrice, gasCap) return feeCalculator, nil } diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 072cb50b53bd..ab3aa27088bd 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -40,15 +40,11 @@ func NewStaticCalculator( } // NewDynamicCalculator must be used post E upgrade activation -func NewDynamicCalculator( - feeManager *fee.Manager, - maxGas fee.Gas, -) *Calculator { +func NewDynamicCalculator(gasPrice fee.GasPrice, gasCap fee.Gas) *Calculator { return &Calculator{ c: &calculator{ isEActive: true, - feeManager: feeManager, - maxGas: maxGas, + feeManager: fee.NewManager(gasPrice, gasCap), // credentials are set when CalculateFee is called }, } @@ -99,7 +95,6 @@ type calculator struct { // Post E-upgrade inputs feeManager *fee.Manager - maxGas fee.Gas credentials []verify.Verifiable // outputs of visitor execution @@ -404,7 +399,7 @@ func (c *calculator) addFeesFor(complexity fee.Dimensions) (uint64, error) { return 0, fmt.Errorf("failed adding fees: %w", err) } - if err := c.feeManager.CumulateGas(txGas, c.maxGas); err != nil { + if err := c.feeManager.CumulateGas(txGas); err != nil { return 0, fmt.Errorf("failed cumulating complexity: %w", err) } fee, err := c.feeManager.CalculateFee(txGas) diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index 946d80428fea..d069b412403b 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -46,8 +46,7 @@ func TestAddAndRemoveFees(t *testing.T) { fc := &Calculator{ c: &calculator{ isEActive: true, - feeManager: fee.NewManager(testGasPrice), - maxGas: testBlockMaxGas, + feeManager: fee.NewManager(testGasPrice, testBlockMaxGas), }, } @@ -114,7 +113,7 @@ func TestTxFees(t *testing.T) { name string chainTime time.Time unsignedAndSignedTx func(t *testing.T) (txs.UnsignedTx, *txs.Tx) - maxGasF func() fee.Gas + gasCapF func() fee.Gas expectedError error checksF func(*testing.T, *calculator) }{ @@ -147,7 +146,7 @@ func TestTxFees(t *testing.T) { { name: "AddSubnetValidatorTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fee.Gas { + gasCapF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: addSubnetValidatorTx, @@ -192,7 +191,7 @@ func TestTxFees(t *testing.T) { name: "CreateChainTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, unsignedAndSignedTx: createChainTx, - maxGasF: func() fee.Gas { + gasCapF: func() fee.Gas { return testBlockMaxGas - 1 }, expectedError: errFailedComplexityCumulation, @@ -228,7 +227,7 @@ func TestTxFees(t *testing.T) { name: "CreateSubnetTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, unsignedAndSignedTx: createSubnetTx, - maxGasF: func() fee.Gas { + gasCapF: func() fee.Gas { return testBlockMaxGas - 1 }, expectedError: errFailedComplexityCumulation, @@ -255,7 +254,7 @@ func TestTxFees(t *testing.T) { { name: "RemoveSubnetValidatorTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fee.Gas { + gasCapF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: removeSubnetValidatorTx, @@ -283,7 +282,7 @@ func TestTxFees(t *testing.T) { { name: "TransformSubnetTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fee.Gas { + gasCapF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: transformSubnetTx, @@ -311,7 +310,7 @@ func TestTxFees(t *testing.T) { { name: "TransferSubnetOwnershipTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fee.Gas { + gasCapF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: transferSubnetOwnershipTx, @@ -369,7 +368,7 @@ func TestTxFees(t *testing.T) { { name: "AddPermissionlessValidatorTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fee.Gas { + gasCapF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { @@ -428,7 +427,7 @@ func TestTxFees(t *testing.T) { { name: "AddPermissionlessDelegatorTx Subnet post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fee.Gas { + gasCapF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { @@ -460,7 +459,7 @@ func TestTxFees(t *testing.T) { { name: "BaseTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fee.Gas { + gasCapF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: baseTx, @@ -488,7 +487,7 @@ func TestTxFees(t *testing.T) { { name: "ImportTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fee.Gas { + gasCapF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: importTx, @@ -516,7 +515,7 @@ func TestTxFees(t *testing.T) { { name: "ExportTx post EUpgrade, utxos read cap breached", chainTime: postEUpgradeTime, - maxGasF: func() fee.Gas { + gasCapF: func() fee.Gas { return testBlockMaxGas - 1 }, unsignedAndSignedTx: exportTx, @@ -551,9 +550,9 @@ func TestTxFees(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - maxComplexity := testBlockMaxGas - if tt.maxGasF != nil { - maxComplexity = tt.maxGasF() + gasCap := testBlockMaxGas + if tt.gasCapF != nil { + gasCap = tt.gasCapF() } uTx, sTx := tt.unsignedAndSignedTx(t) @@ -562,7 +561,7 @@ func TestTxFees(t *testing.T) { if !upgrades.IsEActivated(tt.chainTime) { fc = NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) } else { - fc = NewDynamicCalculator(fee.NewManager(testGasPrice), maxComplexity) + fc = NewDynamicCalculator(testGasPrice, gasCap) } var creds []verify.Verifiable diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index e9c68d14d0d9..3ac7049da955 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -95,7 +95,7 @@ func TestBaseTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) utx, err := builder.NewBaseTx( outputsToMove, feeCalc, @@ -105,7 +105,7 @@ func TestBaseTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(30_620*units.MicroAvax, fee) @@ -199,14 +199,14 @@ func TestAddSubnetValidatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) utx, err := builder.NewAddSubnetValidatorTx(subnetValidator, feeCalc) require.NoError(err) tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(30_610*units.MicroAvax, fee) @@ -287,7 +287,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) utx, err := builder.NewRemoveSubnetValidatorTx( ids.GenerateTestNodeID(), subnetID, @@ -298,7 +298,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(30_370*units.MicroAvax, fee) @@ -389,7 +389,7 @@ func TestCreateChainTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) utx, err := builder.NewCreateChainTx( subnetID, genesisBytes, @@ -403,7 +403,7 @@ func TestCreateChainTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(31_040*units.MicroAvax, fee) @@ -491,7 +491,7 @@ func TestCreateSubnetTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) utx, err := builder.NewCreateSubnetTx( subnetOwner, feeCalc, @@ -501,7 +501,7 @@ func TestCreateSubnetTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(29_400*units.MicroAvax, fee) @@ -585,7 +585,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) utx, err := builder.NewTransferSubnetOwnershipTx( subnetID, subnetOwner, @@ -596,7 +596,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(30_570*units.MicroAvax, fee) @@ -675,7 +675,7 @@ func TestImportTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) utx, err := builder.NewImportTx( sourceChainID, importTo, @@ -686,7 +686,7 @@ func TestImportTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(42_770*units.MicroAvax, fee) @@ -765,7 +765,7 @@ func TestExportTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) utx, err := builder.NewExportTx( subnetID, exportedOutputs, @@ -776,7 +776,7 @@ func TestExportTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(30_980*units.MicroAvax, fee) @@ -867,7 +867,7 @@ func TestTransformSubnetTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) utx, err := builder.NewTransformSubnetTx( subnetID, subnetAssetID, @@ -890,7 +890,7 @@ func TestTransformSubnetTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(46_250*units.MicroAvax, fee) @@ -989,7 +989,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { require.NoError(err) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) utx, err := builder.NewAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1011,7 +1011,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(65_240*units.MicroAvax, fee) @@ -1108,7 +1108,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { ) { // Post E-Upgrade - feeCalc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + feeCalc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) utx, err := builder.NewAddPermissionlessDelegatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ @@ -1127,7 +1127,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { tx, err := signer.SignUnsigned(stdcontext.Background(), s, utx) require.NoError(err) - fc := fee.NewDynamicCalculator(commonfee.NewManager(testGasPrice), testBlockMaxGas) + fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) require.Equal(63_320*units.MicroAvax, fee) diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index ba3df0a092b6..9d57179d885f 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -631,11 +631,10 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( var feeCalculator *fee.Calculator if !w.isEForkActive { - feeCalculator = fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Config{}, time.Time{}) - } else { - feeMan := commonfee.NewManager(w.gasPrice) - feeCalculator = fee.NewDynamicCalculator(feeMan, fee.TempGasCap) + return fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Config{}, time.Time{}), nil } + + feeCalculator = fee.NewDynamicCalculator(w.gasPrice, fee.TempGasCap) return feeCalculator, nil } From 963bc8d16e7bb1ae4356c4855433817b4dfb3f1e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 18 Jun 2024 13:30:45 +0200 Subject: [PATCH 107/120] nit --- vms/components/fee/config.go | 2 +- vms/components/fee/manager.go | 5 +++-- vms/platformvm/block/executor/verifier.go | 8 ++++---- vms/platformvm/txs/fee/calculator.go | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/vms/components/fee/config.go b/vms/components/fee/config.go index 68e3630536cf..e5f8410e6490 100644 --- a/vms/components/fee/config.go +++ b/vms/components/fee/config.go @@ -32,7 +32,7 @@ func (c *DynamicFeesConfig) Validate() error { // 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 !childBlkTime.After(parentBlkTime) { + if parentBlkTime.Compare(childBlkTime) > 0 { return ZeroGas, fmt.Errorf("unexpected block times, parentBlkTim %v, childBlkTime %v", parentBlkTime, childBlkTime) } diff --git a/vms/components/fee/manager.go b/vms/components/fee/manager.go index 10e0f56b1d5f..621a62f2077e 100644 --- a/vms/components/fee/manager.go +++ b/vms/components/fee/manager.go @@ -13,6 +13,7 @@ import ( var errGasBoundBreached = errors.New("gas bound breached") type Manager struct { + // gas cap enforced with adding gas via CumulateGas gasCap Gas // Avax denominated gas price, i.e. fee per unit of complexity. @@ -60,8 +61,8 @@ func (m *Manager) CumulateGas(gas Gas) error { return nil } -// Sometimes, e.g. while building a tx, we'd like freedom to speculatively add complexity -// and to remove it later on. [RemoveGas] grants this freedom +// Sometimes, e.g. while building a tx, we'd like freedom to speculatively +// add gas and to remove it later on. [RemoveGas] grants this freedom func (m *Manager) RemoveGas(gasToRm Gas) error { rBlkdGas, err := safemath.Sub(m.blockGas, gasToRm) if err != nil { diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 273280adbc18..5cd1840c1f89 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -17,7 +17,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" - fee1 "github.com/ava-labs/avalanchego/vms/components/fee" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) var ( @@ -252,7 +252,7 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { inputs: atomicExecutor.Inputs, timestamp: atomicExecutor.OnAccept.GetTimestamp(), - blockGas: fee1.ZeroGas, + blockGas: commonfee.ZeroGas, atomicRequests: atomicExecutor.AtomicRequests, } return nil @@ -423,7 +423,7 @@ func (v *verifier) proposalBlock( return err } - blkGas := feeCalculator.GetGas() + blkGas := feeCalculator.GetBlockGas() onCommitState.SetCurrentGasCap(currentGasCap + blkGas) onAbortState.SetCurrentGasCap(currentGasCap + blkGas) @@ -475,7 +475,7 @@ func (v *verifier) standardBlock( blkID := b.ID() - blkGas := feeCalculator.GetGas() + blkGas := feeCalculator.GetBlockGas() onAcceptState.SetCurrentGasCap(currentGasCap + blkGas) v.blkIDToState[blkID] = &blockState{ diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index ab3aa27088bd..8c0cf1766606 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -77,7 +77,7 @@ func (c *Calculator) RemoveFeesFor(unitsToRm fee.Dimensions) (uint64, error) { return c.c.removeFeesFor(unitsToRm) } -func (c *Calculator) GetGas() fee.Gas { +func (c *Calculator) GetBlockGas() fee.Gas { if c.c.feeManager != nil { return c.c.feeManager.GetBlockGas() } From 6f619a9fd68f17bbd5c9cb34a0165cfc9e79445e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 18 Jun 2024 13:43:50 +0200 Subject: [PATCH 108/120] fixed gas cap update Signed-off-by: Alberto Benegiamo --- vms/platformvm/block/executor/verifier.go | 8 +++++--- vms/platformvm/txs/fee/calculator.go | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 5cd1840c1f89..df2867516e9e 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -424,8 +424,9 @@ func (v *verifier) proposalBlock( } blkGas := feeCalculator.GetBlockGas() - onCommitState.SetCurrentGasCap(currentGasCap + blkGas) - onAbortState.SetCurrentGasCap(currentGasCap + blkGas) + nextGasCap := commonfee.UpdateGasCap(currentGasCap, blkGas) + onCommitState.SetCurrentGasCap(nextGasCap) + onAbortState.SetCurrentGasCap(nextGasCap) onCommitState.AddTx(b.Tx, status.Committed) onAbortState.AddTx(b.Tx, status.Aborted) @@ -476,7 +477,8 @@ func (v *verifier) standardBlock( blkID := b.ID() blkGas := feeCalculator.GetBlockGas() - onAcceptState.SetCurrentGasCap(currentGasCap + blkGas) + nextGasCap := commonfee.UpdateGasCap(currentGasCap, blkGas) + onAcceptState.SetCurrentGasCap(nextGasCap) v.blkIDToState[blkID] = &blockState{ statelessBlock: b, diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/calculator.go index 8c0cf1766606..7b81de8333a2 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/calculator.go @@ -64,7 +64,7 @@ func (c *Calculator) ResetFee(newFee uint64) { func (c *Calculator) ComputeFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) { c.c.credentials = creds - c.c.fee = 0 // zero fee among different ComputeFee invocations (unlike Complexity which gets cumulated) + c.c.fee = 0 // zero fee among different ComputeFee invocations (unlike gas which gets cumulated) err := tx.Visit(c.c) return c.c.fee, err } From f50583051fb1f3edae6b6e43a8abcb35a7c0e0a7 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 18 Jun 2024 14:29:23 +0200 Subject: [PATCH 109/120] refreshed mocks --- vms/platformvm/state/mock_state.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/vms/platformvm/state/mock_state.go b/vms/platformvm/state/mock_state.go index 2174ab4e264f..dd2401056237 100644 --- a/vms/platformvm/state/mock_state.go +++ b/vms/platformvm/state/mock_state.go @@ -20,7 +20,7 @@ import ( validators "github.com/ava-labs/avalanchego/snow/validators" logging "github.com/ava-labs/avalanchego/utils/logging" avax "github.com/ava-labs/avalanchego/vms/components/avax" - fees "github.com/ava-labs/avalanchego/vms/components/fee" + fee "github.com/ava-labs/avalanchego/vms/components/fee" block "github.com/ava-labs/avalanchego/vms/platformvm/block" fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" status "github.com/ava-labs/avalanchego/vms/platformvm/status" @@ -199,10 +199,10 @@ func (mr *MockChainMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *go } // GetCurrentGasCap mocks base method. -func (m *MockChain) GetCurrentGasCap() (fees.Gas, error) { +func (m *MockChain) GetCurrentGasCap() (fee.Gas, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetCurrentGasCap") - ret0, _ := ret[0].(fees.Gas) + ret0, _ := ret[0].(fee.Gas) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -442,7 +442,7 @@ func (mr *MockChainMockRecorder) PutPendingValidator(arg0 any) *gomock.Call { } // SetCurrentGasCap mocks base method. -func (m *MockChain) SetCurrentGasCap(arg0 fees.Gas) { +func (m *MockChain) SetCurrentGasCap(arg0 fee.Gas) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetCurrentGasCap", arg0) } @@ -688,10 +688,10 @@ func (mr *MockDiffMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *gom } // GetCurrentGasCap mocks base method. -func (m *MockDiff) GetCurrentGasCap() (fees.Gas, error) { +func (m *MockDiff) GetCurrentGasCap() (fee.Gas, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetCurrentGasCap") - ret0, _ := ret[0].(fees.Gas) + ret0, _ := ret[0].(fee.Gas) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -931,7 +931,7 @@ func (mr *MockDiffMockRecorder) PutPendingValidator(arg0 any) *gomock.Call { } // SetCurrentGasCap mocks base method. -func (m *MockDiff) SetCurrentGasCap(arg0 fees.Gas) { +func (m *MockDiff) SetCurrentGasCap(arg0 fee.Gas) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetCurrentGasCap", arg0) } @@ -1302,10 +1302,10 @@ func (mr *MockStateMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *go } // GetCurrentGasCap mocks base method. -func (m *MockState) GetCurrentGasCap() (fees.Gas, error) { +func (m *MockState) GetCurrentGasCap() (fee.Gas, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetCurrentGasCap") - ret0, _ := ret[0].(fees.Gas) + ret0, _ := ret[0].(fee.Gas) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1649,7 +1649,7 @@ func (mr *MockStateMockRecorder) ReindexBlocks(arg0, arg1 any) *gomock.Call { } // SetCurrentGasCap mocks base method. -func (m *MockState) SetCurrentGasCap(arg0 fees.Gas) { +func (m *MockState) SetCurrentGasCap(arg0 fee.Gas) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetCurrentGasCap", arg0) } From eb11869516ba9a7695e04a20747fffaebca423f2 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 18 Jun 2024 15:48:04 +0200 Subject: [PATCH 110/120] decoupled static and dynamic fee calculators --- vms/platformvm/txs/fee/calculator_api.go | 54 ++++ vms/platformvm/txs/fee/calculator_test.go | 249 ++++++++++-------- .../{calculator.go => dynamic_calculator.go} | 216 ++++----------- vms/platformvm/txs/fee/helpers.go | 6 +- vms/platformvm/txs/fee/static_calculator.go | 166 ++++++++++++ 5 files changed, 416 insertions(+), 275 deletions(-) create mode 100644 vms/platformvm/txs/fee/calculator_api.go rename vms/platformvm/txs/fee/{calculator.go => dynamic_calculator.go} (60%) create mode 100644 vms/platformvm/txs/fee/static_calculator.go diff --git a/vms/platformvm/txs/fee/calculator_api.go b/vms/platformvm/txs/fee/calculator_api.go new file mode 100644 index 000000000000..7cc0b58acf20 --- /dev/null +++ b/vms/platformvm/txs/fee/calculator_api.go @@ -0,0 +1,54 @@ +// 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/fee" + "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 +// calculator is embedded to avoid exposing unnecessary methods +type Calculator struct { + b backend +} + +func (c *Calculator) GetFee() uint64 { + return c.b.getFee() +} + +func (c *Calculator) ResetFee(newFee uint64) { + c.b.resetFee(newFee) +} + +func (c *Calculator) ComputeFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) { + return c.b.computeFee(tx, creds) +} + +func (c *Calculator) AddFeesFor(complexity fee.Dimensions) (uint64, error) { + return c.b.addFeesFor(complexity) +} + +func (c *Calculator) RemoveFeesFor(unitsToRm fee.Dimensions) (uint64, error) { + return c.b.removeFeesFor(unitsToRm) +} + +func (c *Calculator) GetBlockGas() fee.Gas { + return c.b.getBlockGas() +} + +// backend is the interfaces that any fee backend must implement +type backend interface { + txs.Visitor + + getFee() uint64 + resetFee(newFee uint64) + addFeesFor(complexity fee.Dimensions) (uint64, error) + removeFeesFor(unitsToRm fee.Dimensions) (uint64, error) + getBlockGas() fee.Gas + setCredentials(creds []verify.Verifiable) + computeFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) + isEActive() bool +} diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index d069b412403b..dad23b99d340 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -43,12 +43,7 @@ var ( func TestAddAndRemoveFees(t *testing.T) { r := require.New(t) - fc := &Calculator{ - c: &calculator{ - isEActive: true, - feeManager: fee.NewManager(testGasPrice, testBlockMaxGas), - }, - } + fc := NewDynamicCalculator(testGasPrice, testBlockMaxGas) var ( units = fee.Dimensions{1, 2, 3, 4} @@ -58,27 +53,27 @@ func TestAddAndRemoveFees(t *testing.T) { feeDelta, err := fc.AddFeesFor(units) r.NoError(err) - r.Equal(gas, fc.c.feeManager.GetBlockGas()) + r.Equal(gas, fc.GetBlockGas()) r.NotZero(feeDelta) - r.Equal(feeDelta, fc.c.fee) + r.Equal(feeDelta, fc.GetFee()) feeDelta2, err := fc.AddFeesFor(units) r.NoError(err) - r.Equal(doubleGas, fc.c.feeManager.GetBlockGas()) + r.Equal(doubleGas, fc.GetBlockGas()) r.Equal(feeDelta, feeDelta2) - r.Equal(feeDelta+feeDelta2, fc.c.fee) + r.Equal(feeDelta+feeDelta2, fc.GetFee()) feeDelta3, err := fc.RemoveFeesFor(units) r.NoError(err) - r.Equal(gas, fc.c.feeManager.GetBlockGas()) + r.Equal(gas, fc.GetBlockGas()) r.Equal(feeDelta, feeDelta3) - r.Equal(feeDelta, fc.c.fee) + r.Equal(feeDelta, fc.GetFee()) feeDelta4, err := fc.RemoveFeesFor(units) r.NoError(err) - r.Zero(fc.c.feeManager.GetBlockGas()) + r.Zero(fc.GetBlockGas()) r.Equal(feeDelta, feeDelta4) - r.Zero(fc.c.fee) + r.Zero(fc.GetFee()) } func TestTxFees(t *testing.T) { @@ -115,22 +110,29 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx func(t *testing.T) (txs.UnsignedTx, *txs.Tx) gasCapF func() fee.Gas expectedError error - checksF func(*testing.T, *calculator) + checksF func(*testing.T, *Calculator) }{ { name: "AddValidatorTx pre EUpgrade", chainTime: preEUpgradeTime, unsignedAndSignedTx: addValidatorTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.AddPrimaryNetworkValidatorFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, c.GetFee()) }, }, + { + name: "AddValidatorTx post EUpgrade", + chainTime: postEUpgradeTime, + expectedError: errFailedFeeCalculation, + unsignedAndSignedTx: addValidatorTx, + checksF: func(*testing.T, *Calculator) {}, + }, { name: "AddSubnetValidatorTx pre EUpgrade", chainTime: preEUpgradeTime, unsignedAndSignedTx: addSubnetValidatorTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.AddSubnetValidatorFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddSubnetValidatorFee, c.GetFee()) }, }, { @@ -138,9 +140,9 @@ func TestTxFees(t *testing.T) { chainTime: postEUpgradeTime, expectedError: nil, unsignedAndSignedTx: addSubnetValidatorTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 19_110*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(1911), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 19_110*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(1911), c.GetBlockGas()) }, }, { @@ -151,30 +153,37 @@ func TestTxFees(t *testing.T) { }, unsignedAndSignedTx: addSubnetValidatorTx, expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, *calculator) {}, + checksF: func(*testing.T, *Calculator) {}, }, { name: "AddDelegatorTx pre EUpgrade", chainTime: preEUpgradeTime, unsignedAndSignedTx: addDelegatorTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.AddPrimaryNetworkDelegatorFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, c.GetFee()) }, }, + { + name: "AddDelegatorTx post EUpgrade", + chainTime: postEUpgradeTime, + expectedError: errFailedFeeCalculation, + unsignedAndSignedTx: addDelegatorTx, + checksF: func(*testing.T, *Calculator) {}, + }, { name: "CreateChainTx pre ApricotPhase3", chainTime: preApricotPhase3Time, unsignedAndSignedTx: createChainTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.CreateAssetTxFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.CreateAssetTxFee, c.GetFee()) }, }, { name: "CreateChainTx pre EUpgrade", chainTime: preEUpgradeTime, unsignedAndSignedTx: createChainTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.CreateBlockchainTxFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.CreateBlockchainTxFee, c.GetFee()) }, }, { @@ -182,9 +191,9 @@ func TestTxFees(t *testing.T) { chainTime: postEUpgradeTime, unsignedAndSignedTx: createChainTx, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 19_540*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(1_954), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 19_540*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(1_954), c.GetBlockGas()) }, }, { @@ -195,22 +204,22 @@ func TestTxFees(t *testing.T) { return testBlockMaxGas - 1 }, expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, *calculator) {}, + checksF: func(*testing.T, *Calculator) {}, }, { name: "CreateSubnetTx pre ApricotPhase3", chainTime: preApricotPhase3Time, unsignedAndSignedTx: createSubnetTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.CreateAssetTxFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.CreateAssetTxFee, c.GetFee()) }, }, { name: "CreateSubnetTx pre EUpgrade", chainTime: preEUpgradeTime, unsignedAndSignedTx: createSubnetTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.CreateSubnetTxFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.CreateSubnetTxFee, c.GetFee()) }, }, { @@ -218,9 +227,9 @@ func TestTxFees(t *testing.T) { chainTime: postEUpgradeTime, unsignedAndSignedTx: createSubnetTx, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 18_590*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(1_859), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 18_590*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(1_859), c.GetBlockGas()) }, }, { @@ -231,14 +240,14 @@ func TestTxFees(t *testing.T) { return testBlockMaxGas - 1 }, expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, *calculator) {}, + checksF: func(*testing.T, *Calculator) {}, }, { name: "RemoveSubnetValidatorTx pre EUpgrade", chainTime: preEUpgradeTime, unsignedAndSignedTx: removeSubnetValidatorTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) }, }, { @@ -246,9 +255,9 @@ func TestTxFees(t *testing.T) { chainTime: postEUpgradeTime, unsignedAndSignedTx: removeSubnetValidatorTx, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 18_870*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(1_887), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 18_870*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(1_887), c.GetBlockGas()) }, }, { @@ -259,14 +268,14 @@ func TestTxFees(t *testing.T) { }, unsignedAndSignedTx: removeSubnetValidatorTx, expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, *calculator) {}, + checksF: func(*testing.T, *Calculator) {}, }, { name: "TransformSubnetTx pre EUpgrade", chainTime: preEUpgradeTime, unsignedAndSignedTx: transformSubnetTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.TransformSubnetTxFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.TransformSubnetTxFee, c.GetFee()) }, }, { @@ -274,9 +283,9 @@ func TestTxFees(t *testing.T) { chainTime: postEUpgradeTime, unsignedAndSignedTx: transformSubnetTx, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 19_720*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(1_972), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 19_720*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(1_972), c.GetBlockGas()) }, }, { @@ -287,14 +296,14 @@ func TestTxFees(t *testing.T) { }, unsignedAndSignedTx: transformSubnetTx, expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, *calculator) {}, + checksF: func(*testing.T, *Calculator) {}, }, { name: "TransferSubnetOwnershipTx pre EUpgrade", chainTime: preEUpgradeTime, unsignedAndSignedTx: transferSubnetOwnershipTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) }, }, { @@ -302,9 +311,9 @@ func TestTxFees(t *testing.T) { chainTime: postEUpgradeTime, unsignedAndSignedTx: transferSubnetOwnershipTx, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 19_030*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(1_903), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 19_030*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(1_903), c.GetBlockGas()) }, }, { @@ -315,7 +324,7 @@ func TestTxFees(t *testing.T) { }, unsignedAndSignedTx: transferSubnetOwnershipTx, expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, *calculator) {}, + checksF: func(*testing.T, *Calculator) {}, }, { name: "AddPermissionlessValidatorTx Primary Network pre EUpgrade", @@ -323,8 +332,8 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { return addPermissionlessValidatorTx(t, constants.PrimaryNetworkID) }, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.AddPrimaryNetworkValidatorFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkValidatorFee, c.GetFee()) }, }, { @@ -335,8 +344,8 @@ func TestTxFees(t *testing.T) { require.NotEqual(t, constants.PrimaryNetworkID, subnetID) return addPermissionlessValidatorTx(t, subnetID) }, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.AddSubnetValidatorFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddSubnetValidatorFee, c.GetFee()) }, }, { @@ -346,9 +355,9 @@ func TestTxFees(t *testing.T) { return addPermissionlessValidatorTx(t, constants.PrimaryNetworkID) }, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 23_170*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(2_317), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 23_170*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(2_317), c.GetBlockGas()) }, }, { @@ -360,9 +369,9 @@ func TestTxFees(t *testing.T) { return addPermissionlessValidatorTx(t, subnetID) }, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 23_170*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(2_317), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 23_170*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(2_317), c.GetBlockGas()) }, }, { @@ -376,7 +385,7 @@ func TestTxFees(t *testing.T) { return addPermissionlessValidatorTx(t, subnetID) }, expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, *calculator) {}, + checksF: func(*testing.T, *Calculator) {}, }, { name: "AddPermissionlessDelegatorTx Primary Network pre EUpgrade", @@ -384,8 +393,8 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: func(t *testing.T) (txs.UnsignedTx, *txs.Tx) { return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) }, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.AddPrimaryNetworkDelegatorFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddPrimaryNetworkDelegatorFee, c.GetFee()) }, }, { @@ -396,8 +405,8 @@ func TestTxFees(t *testing.T) { require.NotEqual(t, constants.PrimaryNetworkID, subnetID) return addPermissionlessDelegatorTx(t, subnetID) }, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.AddSubnetDelegatorFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.AddSubnetDelegatorFee, c.GetFee()) }, }, { @@ -407,9 +416,9 @@ func TestTxFees(t *testing.T) { return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) }, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 21_250*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(2_125), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 21_250*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(2_125), c.GetBlockGas()) }, }, { @@ -419,9 +428,9 @@ func TestTxFees(t *testing.T) { return addPermissionlessDelegatorTx(t, constants.PrimaryNetworkID) }, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 21_250*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(2_125), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 21_250*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(2_125), c.GetBlockGas()) }, }, { @@ -436,14 +445,14 @@ func TestTxFees(t *testing.T) { return addPermissionlessValidatorTx(t, subnetID) }, expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, *calculator) {}, + checksF: func(*testing.T, *Calculator) {}, }, { name: "BaseTx pre EUpgrade", chainTime: preEUpgradeTime, unsignedAndSignedTx: baseTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) }, }, { @@ -451,9 +460,9 @@ func TestTxFees(t *testing.T) { chainTime: postEUpgradeTime, unsignedAndSignedTx: baseTx, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 18_190*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(1_819), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 18_190*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(1_819), c.GetBlockGas()) }, }, { @@ -464,14 +473,14 @@ func TestTxFees(t *testing.T) { }, unsignedAndSignedTx: baseTx, expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, *calculator) {}, + checksF: func(*testing.T, *Calculator) {}, }, { name: "ImportTx pre EUpgrade", chainTime: preEUpgradeTime, unsignedAndSignedTx: importTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) }, }, { @@ -479,9 +488,9 @@ func TestTxFees(t *testing.T) { chainTime: postEUpgradeTime, unsignedAndSignedTx: importTx, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 31_230*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(3_123), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 31_230*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(3_123), c.GetBlockGas()) }, }, { @@ -492,14 +501,14 @@ func TestTxFees(t *testing.T) { }, unsignedAndSignedTx: importTx, expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, *calculator) {}, + checksF: func(*testing.T, *Calculator) {}, }, { name: "ExportTx pre EUpgrade", chainTime: preEUpgradeTime, unsignedAndSignedTx: exportTx, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, fc.staticCfg.TxFee, fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, feeTestsDefaultCfg.TxFee, c.GetFee()) }, }, { @@ -507,9 +516,9 @@ func TestTxFees(t *testing.T) { chainTime: postEUpgradeTime, unsignedAndSignedTx: exportTx, expectedError: nil, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, 20_410*units.NanoAvax, fc.fee) - require.Equal(t, fee.Gas(2_041), fc.feeManager.GetBlockGas()) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, 20_410*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(2_041), c.GetBlockGas()) }, }, { @@ -520,7 +529,7 @@ func TestTxFees(t *testing.T) { }, unsignedAndSignedTx: exportTx, expectedError: errFailedComplexityCumulation, - checksF: func(*testing.T, *calculator) {}, + checksF: func(*testing.T, *Calculator) {}, }, { name: "RewardValidatorTx pre EUpgrade", @@ -530,8 +539,20 @@ func TestTxFees(t *testing.T) { TxID: ids.GenerateTestID(), }, nil }, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, uint64(0), fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, uint64(0), c.GetFee()) + }, + }, + { + name: "RewardValidatorTx post EUpgrade", + chainTime: postEUpgradeTime, + unsignedAndSignedTx: func(_ *testing.T) (txs.UnsignedTx, *txs.Tx) { + return &txs.RewardValidatorTx{ + TxID: ids.GenerateTestID(), + }, nil + }, + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, uint64(0), c.GetFee()) }, }, { @@ -542,8 +563,20 @@ func TestTxFees(t *testing.T) { Time: uint64(time.Now().Unix()), }, nil }, - checksF: func(t *testing.T, fc *calculator) { - require.Equal(t, uint64(0), fc.fee) + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, uint64(0), c.GetFee()) + }, + }, + { + name: "AdvanceTimeTx post EUpgrade", + chainTime: postEUpgradeTime, + unsignedAndSignedTx: func(_ *testing.T) (txs.UnsignedTx, *txs.Tx) { + return &txs.AdvanceTimeTx{ + Time: uint64(time.Now().Unix()), + }, nil + }, + checksF: func(t *testing.T, c *Calculator) { + require.Equal(t, uint64(0), c.GetFee()) }, }, } @@ -557,11 +590,11 @@ func TestTxFees(t *testing.T) { uTx, sTx := tt.unsignedAndSignedTx(t) - var fc *Calculator + var c *Calculator if !upgrades.IsEActivated(tt.chainTime) { - fc = NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) + c = NewStaticCalculator(feeTestsDefaultCfg, upgrades, tt.chainTime) } else { - fc = NewDynamicCalculator(testGasPrice, gasCap) + c = NewDynamicCalculator(testGasPrice, gasCap) } var creds []verify.Verifiable @@ -569,8 +602,8 @@ func TestTxFees(t *testing.T) { // txs like RewardValidatorTx are not signed creds = sTx.Creds } - _, _ = fc.ComputeFee(uTx, creds) - tt.checksF(t, fc.c) + _, _ = c.ComputeFee(uTx, creds) + tt.checksF(t, c) }) } } diff --git a/vms/platformvm/txs/fee/calculator.go b/vms/platformvm/txs/fee/dynamic_calculator.go similarity index 60% rename from vms/platformvm/txs/fee/calculator.go rename to vms/platformvm/txs/fee/dynamic_calculator.go index 7b81de8333a2..07f2fb449caa 100644 --- a/vms/platformvm/txs/fee/calculator.go +++ b/vms/platformvm/txs/fee/dynamic_calculator.go @@ -6,94 +6,33 @@ package fee import ( "errors" "fmt" - "time" "github.com/ava-labs/avalanchego/codec" - "github.com/ava-labs/avalanchego/utils/constants" "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/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) var ( - _ txs.Visitor = (*calculator)(nil) + _ backend = (*dynamicCalculator)(nil) errFailedFeeCalculation = errors.New("failed fee calculation") ) -func NewStaticCalculator( - config StaticConfig, - upgradeTimes upgrade.Config, - chainTime time.Time, -) *Calculator { - return &Calculator{ - c: &calculator{ - upgrades: upgradeTimes, - staticCfg: config, - time: chainTime, - }, - } -} - -// NewDynamicCalculator must be used post E upgrade activation func NewDynamicCalculator(gasPrice fee.GasPrice, gasCap fee.Gas) *Calculator { return &Calculator{ - c: &calculator{ - isEActive: true, + b: &dynamicCalculator{ feeManager: fee.NewManager(gasPrice, gasCap), // credentials are set when CalculateFee is called }, } } -type Calculator struct { - c *calculator -} - -func (c *Calculator) GetFee() uint64 { - return c.c.fee -} - -func (c *Calculator) ResetFee(newFee uint64) { - c.c.fee = newFee -} - -func (c *Calculator) ComputeFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) { - c.c.credentials = creds - c.c.fee = 0 // zero fee among different ComputeFee invocations (unlike gas which gets cumulated) - err := tx.Visit(c.c) - return c.c.fee, err -} - -func (c *Calculator) AddFeesFor(complexity fee.Dimensions) (uint64, error) { - return c.c.addFeesFor(complexity) -} - -func (c *Calculator) RemoveFeesFor(unitsToRm fee.Dimensions) (uint64, error) { - return c.c.removeFeesFor(unitsToRm) -} - -func (c *Calculator) GetBlockGas() fee.Gas { - if c.c.feeManager != nil { - return c.c.feeManager.GetBlockGas() - } - return 0 -} - -type calculator struct { - // setup - isEActive bool - staticCfg StaticConfig - - // Pre E-upgrade inputs - upgrades upgrade.Config - time time.Time - - // Post E-upgrade inputs +type dynamicCalculator struct { + // inputs feeManager *fee.Manager credentials []verify.Verifiable @@ -101,21 +40,12 @@ type calculator struct { fee uint64 } -func (c *calculator) AddValidatorTx(*txs.AddValidatorTx) error { +func (*dynamicCalculator) AddValidatorTx(*txs.AddValidatorTx) error { // AddValidatorTx is banned following Durango activation - if !c.isEActive { - c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee - return nil - } return errFailedFeeCalculation } -func (c *calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { - if !c.isEActive { - c.fee = c.staticCfg.AddSubnetValidatorFee - return nil - } - +func (c *dynamicCalculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err @@ -125,25 +55,12 @@ func (c *calculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) error { return err } -func (c *calculator) AddDelegatorTx(*txs.AddDelegatorTx) error { +func (*dynamicCalculator) AddDelegatorTx(*txs.AddDelegatorTx) error { // AddDelegatorTx is banned following Durango activation - if !c.isEActive { - c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee - return nil - } return errFailedFeeCalculation } -func (c *calculator) CreateChainTx(tx *txs.CreateChainTx) error { - if !c.isEActive { - if c.upgrades.IsApricotPhase3Activated(c.time) { - c.fee = c.staticCfg.CreateBlockchainTxFee - } else { - c.fee = c.staticCfg.CreateAssetTxFee - } - return nil - } - +func (c *dynamicCalculator) CreateChainTx(tx *txs.CreateChainTx) error { complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err @@ -153,16 +70,7 @@ func (c *calculator) CreateChainTx(tx *txs.CreateChainTx) error { return err } -func (c *calculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { - if !c.isEActive { - if c.upgrades.IsApricotPhase3Activated(c.time) { - c.fee = c.staticCfg.CreateSubnetTxFee - } else { - c.fee = c.staticCfg.CreateAssetTxFee - } - return nil - } - +func (c *dynamicCalculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err @@ -172,22 +80,17 @@ func (c *calculator) CreateSubnetTx(tx *txs.CreateSubnetTx) error { return err } -func (c *calculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { +func (c *dynamicCalculator) AdvanceTimeTx(*txs.AdvanceTimeTx) error { c.fee = 0 // no fees return nil } -func (c *calculator) RewardValidatorTx(*txs.RewardValidatorTx) error { +func (c *dynamicCalculator) RewardValidatorTx(*txs.RewardValidatorTx) error { c.fee = 0 // no fees return nil } -func (c *calculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { - if !c.isEActive { - c.fee = c.staticCfg.TxFee - return nil - } - +func (c *dynamicCalculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) error { complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err @@ -197,12 +100,7 @@ func (c *calculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx) er return err } -func (c *calculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { - if !c.isEActive { - c.fee = c.staticCfg.TransformSubnetTxFee - return nil - } - +func (c *dynamicCalculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err @@ -212,12 +110,7 @@ func (c *calculator) TransformSubnetTx(tx *txs.TransformSubnetTx) error { return err } -func (c *calculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { - if !c.isEActive { - c.fee = c.staticCfg.TxFee - return nil - } - +func (c *dynamicCalculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err @@ -227,16 +120,7 @@ func (c *calculator) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx return err } -func (c *calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValidatorTx) error { - if !c.isEActive { - if tx.Subnet != constants.PrimaryNetworkID { - c.fee = c.staticCfg.AddSubnetValidatorFee - } else { - c.fee = c.staticCfg.AddPrimaryNetworkValidatorFee - } - return nil - } - +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) @@ -250,16 +134,7 @@ func (c *calculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionlessValid return err } -func (c *calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDelegatorTx) error { - if !c.isEActive { - if tx.Subnet != constants.PrimaryNetworkID { - c.fee = c.staticCfg.AddSubnetDelegatorFee - } else { - c.fee = c.staticCfg.AddPrimaryNetworkDelegatorFee - } - return nil - } - +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) @@ -273,12 +148,7 @@ func (c *calculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionlessDeleg return err } -func (c *calculator) BaseTx(tx *txs.BaseTx) error { - if !c.isEActive { - c.fee = c.staticCfg.TxFee - return nil - } - +func (c *dynamicCalculator) BaseTx(tx *txs.BaseTx) error { complexity, err := c.meterTx(tx, tx.Outs, tx.Ins) if err != nil { return err @@ -288,12 +158,7 @@ func (c *calculator) BaseTx(tx *txs.BaseTx) error { return err } -func (c *calculator) ImportTx(tx *txs.ImportTx) error { - if !c.isEActive { - c.fee = c.staticCfg.TxFee - return nil - } - +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) @@ -307,12 +172,7 @@ func (c *calculator) ImportTx(tx *txs.ImportTx) error { return err } -func (c *calculator) ExportTx(tx *txs.ExportTx) error { - if !c.isEActive { - c.fee = c.staticCfg.TxFee - return nil - } - +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) @@ -326,7 +186,7 @@ func (c *calculator) ExportTx(tx *txs.ExportTx) error { return err } -func (c *calculator) meterTx( +func (c *dynamicCalculator) meterTx( uTx txs.UnsignedTx, allOuts []*avax.TransferableOutput, allIns []*avax.TransferableInput, @@ -385,12 +245,12 @@ func (c *calculator) meterTx( return complexity, nil } -func (c *calculator) addFeesFor(complexity fee.Dimensions) (uint64, error) { +func (c *dynamicCalculator) addFeesFor(complexity fee.Dimensions) (uint64, error) { if c.feeManager == nil || complexity == fee.Empty { return 0, nil } - feeCfg, err := GetDynamicConfig(c.isEActive) + feeCfg, err := GetDynamicConfig(true /*isEActive*/) if err != nil { return 0, fmt.Errorf("failed adding fees: %w", err) } @@ -411,12 +271,12 @@ func (c *calculator) addFeesFor(complexity fee.Dimensions) (uint64, error) { return fee, nil } -func (c *calculator) removeFeesFor(unitsToRm fee.Dimensions) (uint64, error) { +func (c *dynamicCalculator) removeFeesFor(unitsToRm fee.Dimensions) (uint64, error) { if c.feeManager == nil || unitsToRm == fee.Empty { return 0, nil } - feeCfg, err := GetDynamicConfig(c.isEActive) + feeCfg, err := GetDynamicConfig(true /*isEActive*/) if err != nil { return 0, fmt.Errorf("failed adding fees: %w", err) } @@ -436,3 +296,31 @@ func (c *calculator) removeFeesFor(unitsToRm fee.Dimensions) (uint64, error) { c.fee -= fee return fee, nil } + +func (c *dynamicCalculator) getFee() uint64 { + return c.fee +} + +func (c *dynamicCalculator) resetFee(newFee uint64) { + c.fee = newFee +} + +func (c *dynamicCalculator) computeFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) { + c.setCredentials(creds) + c.fee = 0 // zero fee among different ComputeFee invocations (unlike gas which gets cumulated) + err := tx.Visit(c) + return c.fee, err +} + +func (c *dynamicCalculator) getBlockGas() fee.Gas { + if c.feeManager != nil { + return c.feeManager.GetBlockGas() + } + return 0 +} + +func (c *dynamicCalculator) setCredentials(creds []verify.Verifiable) { + c.credentials = creds +} + +func (*dynamicCalculator) isEActive() bool { return true } diff --git a/vms/platformvm/txs/fee/helpers.go b/vms/platformvm/txs/fee/helpers.go index b75af197ac46..e2cda9454d36 100644 --- a/vms/platformvm/txs/fee/helpers.go +++ b/vms/platformvm/txs/fee/helpers.go @@ -12,7 +12,7 @@ import ( ) func FinanceInput(feeCalc *Calculator, input *avax.TransferableInput) (uint64, error) { - if !feeCalc.c.isEActive { + if !feeCalc.b.isEActive() { return 0, nil // pre E-upgrade we have a fixed fee regardless how complex the input is } @@ -28,7 +28,7 @@ func FinanceInput(feeCalc *Calculator, input *avax.TransferableInput) (uint64, e } func FinanceOutput(feeCalc *Calculator, output *avax.TransferableOutput) (uint64, fee.Dimensions, error) { - if !feeCalc.c.isEActive { + if !feeCalc.b.isEActive() { return 0, fee.Empty, nil // pre E-upgrade we have a fixed fee regardless how complex the output is } @@ -44,7 +44,7 @@ func FinanceOutput(feeCalc *Calculator, output *avax.TransferableOutput) (uint64 } func FinanceCredential(feeCalc *Calculator, keysCount int) (uint64, error) { - if !feeCalc.c.isEActive { + if !feeCalc.b.isEActive() { return 0, nil // pre E-upgrade we have a fixed fee regardless how complex the credentials are } diff --git a/vms/platformvm/txs/fee/static_calculator.go b/vms/platformvm/txs/fee/static_calculator.go new file mode 100644 index 000000000000..9bc9321f7b11 --- /dev/null +++ b/vms/platformvm/txs/fee/static_calculator.go @@ -0,0 +1,166 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +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" +) + +var ( + _ backend = (*staticCalculator)(nil) + + errComplexityNotPriced = errors.New("complexity not priced") +) + +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) getFee() uint64 { + return c.fee +} + +func (c *staticCalculator) resetFee(newFee uint64) { + c.fee = newFee +} + +func (c *staticCalculator) computeFee(tx txs.UnsignedTx, _ []verify.Verifiable) (uint64, error) { + c.fee = 0 // zero fee among different ComputeFee invocations (unlike gas which gets cumulated) + err := tx.Visit(c) + return c.fee, err +} + +func (*staticCalculator) addFeesFor(fee.Dimensions) (uint64, error) { + return 0, errComplexityNotPriced +} + +func (*staticCalculator) removeFeesFor(fee.Dimensions) (uint64, error) { + return 0, errComplexityNotPriced +} + +func (*staticCalculator) getBlockGas() fee.Gas { + return 0 +} + +func (*staticCalculator) setCredentials([]verify.Verifiable) {} + +func (*staticCalculator) isEActive() bool { return false } From 0840496514c6586d77a6821ad6aab050259f8da3 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 18 Jun 2024 17:37:44 +0200 Subject: [PATCH 111/120] added UT --- vms/platformvm/block/executor/verifier_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index 9f69653654a1..d5e5b533e405 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -31,6 +31,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" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -526,8 +527,17 @@ func TestStandardBlockGas(t *testing.T) { if dynamicFeesActive { require.NotEqual(commonfee.ZeroGas, blkState.blockGas) + + gasCap, err := blkState.onAcceptState.GetCurrentGasCap() + require.NoError(err) + require.Greater(gasCap, commonfee.ZeroGas) + require.Less(gasCap, fee.TempGasCap) } else { require.Equal(commonfee.ZeroGas, blkState.blockGas) + + gasCap, err := blkState.onAcceptState.GetCurrentGasCap() + require.NoError(err) + require.Equal(fee.TempGasCap, gasCap) } }) } From a2edef091f94f3276ff32f95ad694cbd7d37c1dd Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 20 Jun 2024 09:23:48 +0200 Subject: [PATCH 112/120] nit --- vms/components/fee/config.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vms/components/fee/config.go b/vms/components/fee/config.go index e5f8410e6490..8f19df8172b3 100644 --- a/vms/components/fee/config.go +++ b/vms/components/fee/config.go @@ -12,13 +12,17 @@ import ( var errZeroLeakGasCoeff = errors.New("zero leak gas coefficient") 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 - LeakGasCoeff Gas // TODO ABENEGIA: not sure of the unit of measurement here + LeakGasCoeff Gas // techically the unit of measure if sec^{-1}, but picking Gas reduces casts needed } func (c *DynamicFeesConfig) Validate() error { From b26f87c71790f3f8175fb3da0ca5ad4abec29b04 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 20 Jun 2024 10:51:07 +0200 Subject: [PATCH 113/120] dropped TempGasCap --- tests/e2e/p/workflow.go | 8 ++-- .../fee/{manager.go => calculator.go} | 40 ++++++++++------- vms/platformvm/block/executor/verifier.go | 14 +++--- .../block/executor/verifier_test.go | 11 ++++- vms/platformvm/client.go | 11 +++++ vms/platformvm/service.go | 44 +++++++++++++++++++ vms/platformvm/txs/fee/calculator_api.go | 16 ++++++- vms/platformvm/txs/fee/dynamic_calculator.go | 20 +++++++-- vms/platformvm/txs/fee/dynamic_config.go | 2 - vms/platformvm/txs/fee/static_calculator.go | 8 ++-- wallet/chain/p/wallet.go | 32 +++++--------- 11 files changed, 148 insertions(+), 58 deletions(-) rename vms/components/fee/{manager.go => calculator.go} (59%) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index b30d82004671..9666794b76a9 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -140,6 +140,9 @@ var _ = e2e.DescribePChain("[Workflow]", func() { pChainExportFee := uint64(0) ginkgo.By("export avax from P to X chain", func() { + nextGasPrice, nextGasCap, err := pChainClient.GetNextGasData(e2e.DefaultContext()) + require.NoError(err) + tx, err := pWallet.IssueExportTx( xContext.BlockchainID, []*avax.TransferableOutput{ @@ -155,10 +158,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { require.NoError(err) // retrieve fees paid for the tx - feeCfg, err := fee.GetDynamicConfig(true /*isEActive*/) - require.NoError(err) - - feeCalc := fee.NewDynamicCalculator(feeCfg.GasPrice, fee.TempGasCap) + feeCalc := fee.NewDynamicCalculator(nextGasPrice, nextGasCap) pChainExportFee, err = feeCalc.ComputeFee(tx.Unsigned, tx.Creds) require.NoError(err) }) diff --git a/vms/components/fee/manager.go b/vms/components/fee/calculator.go similarity index 59% rename from vms/components/fee/manager.go rename to vms/components/fee/calculator.go index 621a62f2077e..2ceb5c23f02c 100644 --- a/vms/components/fee/manager.go +++ b/vms/components/fee/calculator.go @@ -12,7 +12,9 @@ import ( var errGasBoundBreached = errors.New("gas bound breached") -type Manager struct { +// Calculator performs fee-related operations that are share move P-chain and X-chain +// Calculator is supposed to be embedded with chain specific calculators. +type Calculator struct { // gas cap enforced with adding gas via CumulateGas gasCap Gas @@ -24,51 +26,55 @@ type Manager struct { blockGas Gas } -func NewManager(gasPrice GasPrice, gasCap Gas) *Manager { - return &Manager{ +func NewCalculator(gasPrice GasPrice, gasCap Gas) *Calculator { + return &Calculator{ gasCap: gasCap, gasPrice: gasPrice, } } -func (m *Manager) GetGasPrice() GasPrice { - return m.gasPrice +func (c *Calculator) GetGasPrice() GasPrice { + return c.gasPrice } -func (m *Manager) GetBlockGas() Gas { - return m.blockGas +func (c *Calculator) GetBlockGas() Gas { + return c.blockGas +} + +func (c *Calculator) GetGasCap() Gas { + return c.gasCap } // CalculateFee must be a stateless method -func (m *Manager) CalculateFee(g Gas) (uint64, error) { - return safemath.Mul64(uint64(m.gasPrice), uint64(g)) +func (c *Calculator) CalculateFee(g Gas) (uint64, error) { + return safemath.Mul64(uint64(c.gasPrice), uint64(g)) } // CumulateGas tries to cumulate the consumed gas [units]. Before // actually cumulating it, it checks whether the result would breach [bounds]. // If so, it returns the first dimension to breach bounds. -func (m *Manager) CumulateGas(gas Gas) error { +func (c *Calculator) CumulateGas(gas Gas) error { // Ensure we can consume (don't want partial update of values) - blkGas, err := safemath.Add64(uint64(m.blockGas), uint64(gas)) + blkGas, err := safemath.Add64(uint64(c.blockGas), uint64(gas)) if err != nil { return fmt.Errorf("%w: %w", errGasBoundBreached, err) } - if Gas(blkGas) > m.gasCap { + if Gas(blkGas) > c.gasCap { return errGasBoundBreached } - m.blockGas = Gas(blkGas) + c.blockGas = Gas(blkGas) return nil } // Sometimes, e.g. while building a tx, we'd like freedom to speculatively // add gas and to remove it later on. [RemoveGas] grants this freedom -func (m *Manager) RemoveGas(gasToRm Gas) error { - rBlkdGas, err := safemath.Sub(m.blockGas, gasToRm) +func (c *Calculator) RemoveGas(gasToRm Gas) error { + rBlkdGas, err := safemath.Sub(c.blockGas, gasToRm) if err != nil { - return fmt.Errorf("%w: current Gas %d, gas to revert %d", err, m.blockGas, gasToRm) + return fmt.Errorf("%w: current Gas %d, gas to revert %d", err, c.blockGas, gasToRm) } - m.blockGas = rBlkdGas + c.blockGas = rBlkdGas return nil } diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index df2867516e9e..b34e4b8973ff 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -424,9 +424,11 @@ func (v *verifier) proposalBlock( } blkGas := feeCalculator.GetBlockGas() - nextGasCap := commonfee.UpdateGasCap(currentGasCap, blkGas) - onCommitState.SetCurrentGasCap(nextGasCap) - onAbortState.SetCurrentGasCap(nextGasCap) + if feeCalculator.IsEActive() { + nextGasCap := commonfee.UpdateGasCap(currentGasCap, blkGas) + onCommitState.SetCurrentGasCap(nextGasCap) + onAbortState.SetCurrentGasCap(nextGasCap) + } onCommitState.AddTx(b.Tx, status.Committed) onAbortState.AddTx(b.Tx, status.Aborted) @@ -477,8 +479,10 @@ func (v *verifier) standardBlock( blkID := b.ID() blkGas := feeCalculator.GetBlockGas() - nextGasCap := commonfee.UpdateGasCap(currentGasCap, blkGas) - onAcceptState.SetCurrentGasCap(nextGasCap) + if feeCalculator.IsEActive() { + nextGasCap := commonfee.UpdateGasCap(currentGasCap, blkGas) + onAcceptState.SetCurrentGasCap(nextGasCap) + } v.blkIDToState[blkID] = &blockState{ statelessBlock: b, diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index d5e5b533e405..42b1cb110b74 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -531,13 +531,20 @@ func TestStandardBlockGas(t *testing.T) { gasCap, err := blkState.onAcceptState.GetCurrentGasCap() require.NoError(err) require.Greater(gasCap, commonfee.ZeroGas) - require.Less(gasCap, fee.TempGasCap) + + feeCfg, err := fee.GetDynamicConfig(dynamicFeesActive) + require.NoError(err) + require.Less(gasCap, feeCfg.MaxGasPerSecond) } else { require.Equal(commonfee.ZeroGas, blkState.blockGas) + // GasCap unchanged wrt parent state + parentGasCap, err := env.state.GetCurrentGasCap() + require.NoError(err) + gasCap, err := blkState.onAcceptState.GetCurrentGasCap() require.NoError(err) - require.Equal(fee.TempGasCap, gasCap) + require.Equal(parentGasCap, gasCap) } }) } diff --git a/vms/platformvm/client.go b/vms/platformvm/client.go index 11453efb5f6b..4bc1487cf9ee 100644 --- a/vms/platformvm/client.go +++ b/vms/platformvm/client.go @@ -17,6 +17,8 @@ import ( "github.com/ava-labs/avalanchego/utils/json" "github.com/ava-labs/avalanchego/utils/rpc" "github.com/ava-labs/avalanchego/vms/platformvm/status" + + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) var _ Client = (*client)(nil) @@ -121,6 +123,9 @@ type Client interface { GetBlock(ctx context.Context, blockID ids.ID, options ...rpc.Option) ([]byte, error) // GetBlockByHeight returns the block at the given [height]. GetBlockByHeight(ctx context.Context, height uint64, options ...rpc.Option) ([]byte, error) + // GetNextGasData returns the gas price that a transaction must pay to be accepted now + // and the gas cap, i.e. the maximum gas a transactions can consume + GetNextGasData(ctx context.Context, options ...rpc.Option) (commonfee.GasPrice, commonfee.Gas, error) } // Client implementation for interacting with the P Chain endpoint @@ -543,3 +548,9 @@ func AwaitTxAccepted( } } } + +func (c *client) GetNextGasData(ctx context.Context, options ...rpc.Option) (commonfee.GasPrice, commonfee.Gas, error) { + res := &GetGasPriceReply{} + err := c.requester.SendRequest(ctx, "platform.getNextGasPrice", struct{}{}, res, options...) + return res.NextGasPrice, res.NextGasCap, err +} diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index d1bdf60a6529..deefaafad2d2 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -40,6 +40,7 @@ import ( avajson "github.com/ava-labs/avalanchego/utils/json" safemath "github.com/ava-labs/avalanchego/utils/math" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" platformapi "github.com/ava-labs/avalanchego/vms/platformvm/api" ) @@ -1828,6 +1829,49 @@ func (s *Service) GetBlockByHeight(_ *http.Request, args *api.GetBlockByHeightAr return err } +// GetGasPriceReply is the response from GetFeeRates +type GetGasPriceReply struct { + NextGasPrice commonfee.GasPrice `json:"nextGasPrice"` + NextGasCap commonfee.Gas `json:"nextGasCap"` +} + +// GetNextFeeRates returns the next fee rates that a transaction must pay to be accepted now +func (s *Service) GetNextGasData(_ *http.Request, _ *struct{}, reply *GetGasPriceReply) error { + s.vm.ctx.Log.Debug("API called", + zap.String("service", "platform"), + zap.String("method", "getNextGasData"), + ) + + s.vm.ctx.Lock.Lock() + defer s.vm.ctx.Lock.Unlock() + + preferredID := s.vm.manager.Preferred() + onAccept, ok := s.vm.manager.GetState(preferredID) + if !ok { + return fmt.Errorf("could not retrieve state for block %s", preferredID) + } + + currentChainTime := onAccept.GetTimestamp() + nextTimestamp, _, err := state.NextBlockTime(onAccept, &s.vm.clock) + if err != nil { + return fmt.Errorf("could not calculate next staker change time: %w", err) + } + + stateDiff, err := state.NewDiffOn(onAccept) + if err != nil { + return err + } + stateDiff.SetTimestamp(nextTimestamp) + + feeCalculator, err := state.PickFeeCalculator(&s.vm.Config, stateDiff, currentChainTime) + if err != nil { + return err + } + reply.NextGasPrice = feeCalculator.GetGasPrice() + reply.NextGasCap = feeCalculator.GetGasCap() + return nil +} + func (s *Service) getAPIUptime(staker *state.Staker) (*avajson.Float32, error) { // Only report uptimes that we have been actively tracking. if constants.PrimaryNetworkID != staker.SubnetID && !s.vm.TrackedSubnets.Contains(staker.SubnetID) { diff --git a/vms/platformvm/txs/fee/calculator_api.go b/vms/platformvm/txs/fee/calculator_api.go index 7cc0b58acf20..46030e869dba 100644 --- a/vms/platformvm/txs/fee/calculator_api.go +++ b/vms/platformvm/txs/fee/calculator_api.go @@ -10,7 +10,7 @@ import ( ) // Calculator is a wrapper to exposed a more user friendly API than txs.Visitor allows -// calculator is embedded to avoid exposing unnecessary methods +// backend is not embedded to avoid exposing unnecessary methods type Calculator struct { b backend } @@ -35,10 +35,22 @@ func (c *Calculator) RemoveFeesFor(unitsToRm fee.Dimensions) (uint64, error) { return c.b.removeFeesFor(unitsToRm) } +func (c *Calculator) GetGasPrice() fee.GasPrice { + return c.b.getGasPrice() +} + func (c *Calculator) GetBlockGas() fee.Gas { return c.b.getBlockGas() } +func (c *Calculator) GetGasCap() fee.Gas { + return c.b.getGasCap() +} + +func (c *Calculator) IsEActive() bool { + return c.b.isEActive() +} + // backend is the interfaces that any fee backend must implement type backend interface { txs.Visitor @@ -47,7 +59,9 @@ type backend interface { resetFee(newFee uint64) addFeesFor(complexity fee.Dimensions) (uint64, error) removeFeesFor(unitsToRm fee.Dimensions) (uint64, error) + getGasPrice() fee.GasPrice getBlockGas() fee.Gas + getGasCap() fee.Gas setCredentials(creds []verify.Verifiable) computeFee(tx txs.UnsignedTx, creds []verify.Verifiable) (uint64, error) isEActive() bool diff --git a/vms/platformvm/txs/fee/dynamic_calculator.go b/vms/platformvm/txs/fee/dynamic_calculator.go index 07f2fb449caa..f6c7d9220843 100644 --- a/vms/platformvm/txs/fee/dynamic_calculator.go +++ b/vms/platformvm/txs/fee/dynamic_calculator.go @@ -25,7 +25,7 @@ var ( func NewDynamicCalculator(gasPrice fee.GasPrice, gasCap fee.Gas) *Calculator { return &Calculator{ b: &dynamicCalculator{ - feeManager: fee.NewManager(gasPrice, gasCap), + feeManager: fee.NewCalculator(gasPrice, gasCap), // credentials are set when CalculateFee is called }, } @@ -33,7 +33,7 @@ func NewDynamicCalculator(gasPrice fee.GasPrice, gasCap fee.Gas) *Calculator { type dynamicCalculator struct { // inputs - feeManager *fee.Manager + feeManager *fee.Calculator credentials []verify.Verifiable // outputs of visitor execution @@ -312,11 +312,25 @@ func (c *dynamicCalculator) computeFee(tx txs.UnsignedTx, creds []verify.Verifia return c.fee, err } +func (c *dynamicCalculator) getGasPrice() fee.GasPrice { + if c.feeManager != nil { + return c.feeManager.GetGasPrice() + } + return fee.ZeroGasPrice +} + func (c *dynamicCalculator) getBlockGas() fee.Gas { if c.feeManager != nil { return c.feeManager.GetBlockGas() } - return 0 + return fee.ZeroGas +} + +func (c *dynamicCalculator) getGasCap() fee.Gas { + if c.feeManager != nil { + return c.feeManager.GetGasCap() + } + return fee.ZeroGas } func (c *dynamicCalculator) setCredentials(creds []verify.Verifiable) { diff --git a/vms/platformvm/txs/fee/dynamic_config.go b/vms/platformvm/txs/fee/dynamic_config.go index b849152dcba2..94372c9a19f1 100644 --- a/vms/platformvm/txs/fee/dynamic_config.go +++ b/vms/platformvm/txs/fee/dynamic_config.go @@ -14,8 +14,6 @@ import ( commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) -const TempGasCap = commonfee.Gas(1_000_000) // TODO ABENEGIA: temp const to be replaced with API call - var ( errDynamicFeeConfigNotAvailable = errors.New("dynamic fee config not available") diff --git a/vms/platformvm/txs/fee/static_calculator.go b/vms/platformvm/txs/fee/static_calculator.go index 9bc9321f7b11..b601ee517740 100644 --- a/vms/platformvm/txs/fee/static_calculator.go +++ b/vms/platformvm/txs/fee/static_calculator.go @@ -157,9 +157,11 @@ func (*staticCalculator) removeFeesFor(fee.Dimensions) (uint64, error) { return 0, errComplexityNotPriced } -func (*staticCalculator) getBlockGas() fee.Gas { - return 0 -} +func (*staticCalculator) getGasPrice() fee.GasPrice { return 0 } + +func (*staticCalculator) getBlockGas() fee.Gas { return 0 } + +func (*staticCalculator) getGasCap() fee.Gas { return 0 } func (*staticCalculator) setCredentials([]verify.Verifiable) {} diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index a88e9096422a..123c46f827b5 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -292,7 +292,7 @@ type wallet struct { isEForkActive bool staticFeesConfig fee.StaticConfig gasPrice commonfee.GasPrice - maxComplexity commonfee.Gas + gasCap commonfee.Gas } func (w *wallet) Builder() builder.Builder { @@ -619,43 +619,33 @@ func (w *wallet) feeCalculator(ctx *builder.Context, options ...common.Option) ( return nil, err } - var feeCalculator *fee.Calculator if !w.isEForkActive { return fee.NewStaticCalculator(w.staticFeesConfig, upgrade.Config{}, time.Time{}), nil } - feeCalculator = fee.NewDynamicCalculator(w.gasPrice, fee.TempGasCap) - return feeCalculator, nil + return fee.NewDynamicCalculator(w.gasPrice, w.gasCap), nil } func (w *wallet) refreshFeesData(ctx *builder.Context, options ...common.Option) error { - if w.isEForkActive { - // E fork enables dinamic fees and it is active - // not need to recheck - return nil - } - var ( - ops = common.NewOptions(options) - opsCtx = ops.Context() - eForkTime = version.GetEUpgradeTime(w.builder.Context().NetworkID) + ops = common.NewOptions(options) + opsCtx = ops.Context() ) chainTime, err := w.client.GetTimestamp(opsCtx) if err != nil { return err } + eUpgradeTime := version.GetEUpgradeTime(w.builder.Context().NetworkID) + w.isEForkActive = !chainTime.Before(eUpgradeTime) - w.staticFeesConfig = staticFeesConfigFromContext(ctx) - - w.isEForkActive = !chainTime.Before(eForkTime) if !w.isEForkActive { - return nil // nothing else to update + w.staticFeesConfig = staticFeesConfigFromContext(ctx) + return nil } - feeCfg, _ := fee.GetDynamicConfig(w.isEForkActive) - w.gasPrice = feeCfg.GasPrice - w.maxComplexity = fee.TempGasCap - return nil + + w.gasPrice, w.gasCap, err = w.client.GetNextGasData(opsCtx) + return err } func staticFeesConfigFromContext(ctx *builder.Context) fee.StaticConfig { From 45a5752d4261cdefaec8026cf4051b0dd219d5b5 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 20 Jun 2024 11:38:55 +0200 Subject: [PATCH 114/120] nit: fixed RPC invocation --- vms/platformvm/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/platformvm/client.go b/vms/platformvm/client.go index 4bc1487cf9ee..2631a5d30c8c 100644 --- a/vms/platformvm/client.go +++ b/vms/platformvm/client.go @@ -551,6 +551,6 @@ func AwaitTxAccepted( func (c *client) GetNextGasData(ctx context.Context, options ...rpc.Option) (commonfee.GasPrice, commonfee.Gas, error) { res := &GetGasPriceReply{} - err := c.requester.SendRequest(ctx, "platform.getNextGasPrice", struct{}{}, res, options...) + err := c.requester.SendRequest(ctx, "platform.getNextGasData", struct{}{}, res, options...) return res.NextGasPrice, res.NextGasCap, err } From 99e9574c84c953215ef39422296c9b1dc1fb02b8 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 20 Jun 2024 12:25:11 +0200 Subject: [PATCH 115/120] nit --- vms/platformvm/txs/fee/dynamic_calculator.go | 45 +++++++------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/vms/platformvm/txs/fee/dynamic_calculator.go b/vms/platformvm/txs/fee/dynamic_calculator.go index f6c7d9220843..24e858a932fe 100644 --- a/vms/platformvm/txs/fee/dynamic_calculator.go +++ b/vms/platformvm/txs/fee/dynamic_calculator.go @@ -25,16 +25,16 @@ var ( func NewDynamicCalculator(gasPrice fee.GasPrice, gasCap fee.Gas) *Calculator { return &Calculator{ b: &dynamicCalculator{ - feeManager: fee.NewCalculator(gasPrice, gasCap), - // credentials are set when CalculateFee is called + fc: fee.NewCalculator(gasPrice, gasCap), + // credentials are set when computeFee is called }, } } type dynamicCalculator struct { // inputs - feeManager *fee.Calculator - credentials []verify.Verifiable + fc *fee.Calculator + cred []verify.Verifiable // outputs of visitor execution fee uint64 @@ -201,7 +201,7 @@ func (c *dynamicCalculator) meterTx( // 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.credentials { + 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) @@ -246,7 +246,7 @@ func (c *dynamicCalculator) meterTx( } func (c *dynamicCalculator) addFeesFor(complexity fee.Dimensions) (uint64, error) { - if c.feeManager == nil || complexity == fee.Empty { + if c.fc == nil || complexity == fee.Empty { return 0, nil } @@ -259,10 +259,10 @@ func (c *dynamicCalculator) addFeesFor(complexity fee.Dimensions) (uint64, error return 0, fmt.Errorf("failed adding fees: %w", err) } - if err := c.feeManager.CumulateGas(txGas); err != nil { + if err := c.fc.CumulateGas(txGas); err != nil { return 0, fmt.Errorf("failed cumulating complexity: %w", err) } - fee, err := c.feeManager.CalculateFee(txGas) + fee, err := c.fc.CalculateFee(txGas) if err != nil { return 0, fmt.Errorf("%w: %w", errFailedFeeCalculation, err) } @@ -272,7 +272,7 @@ func (c *dynamicCalculator) addFeesFor(complexity fee.Dimensions) (uint64, error } func (c *dynamicCalculator) removeFeesFor(unitsToRm fee.Dimensions) (uint64, error) { - if c.feeManager == nil || unitsToRm == fee.Empty { + if c.fc == nil || unitsToRm == fee.Empty { return 0, nil } @@ -285,10 +285,10 @@ func (c *dynamicCalculator) removeFeesFor(unitsToRm fee.Dimensions) (uint64, err return 0, fmt.Errorf("failed adding fees: %w", err) } - if err := c.feeManager.RemoveGas(txGas); err != nil { + if err := c.fc.RemoveGas(txGas); err != nil { return 0, fmt.Errorf("failed removing units: %w", err) } - fee, err := c.feeManager.CalculateFee(txGas) + fee, err := c.fc.CalculateFee(txGas) if err != nil { return 0, fmt.Errorf("%w: %w", errFailedFeeCalculation, err) } @@ -312,29 +312,14 @@ func (c *dynamicCalculator) computeFee(tx txs.UnsignedTx, creds []verify.Verifia return c.fee, err } -func (c *dynamicCalculator) getGasPrice() fee.GasPrice { - if c.feeManager != nil { - return c.feeManager.GetGasPrice() - } - return fee.ZeroGasPrice -} +func (c *dynamicCalculator) getGasPrice() fee.GasPrice { return c.fc.GetGasPrice() } -func (c *dynamicCalculator) getBlockGas() fee.Gas { - if c.feeManager != nil { - return c.feeManager.GetBlockGas() - } - return fee.ZeroGas -} +func (c *dynamicCalculator) getBlockGas() fee.Gas { return c.fc.GetBlockGas() } -func (c *dynamicCalculator) getGasCap() fee.Gas { - if c.feeManager != nil { - return c.feeManager.GetGasCap() - } - return fee.ZeroGas -} +func (c *dynamicCalculator) getGasCap() fee.Gas { return c.fc.GetGasCap() } func (c *dynamicCalculator) setCredentials(creds []verify.Verifiable) { - c.credentials = creds + c.cred = creds } func (*dynamicCalculator) isEActive() bool { return true } From 1548cffd5ff51e5989474b3522be3bd09cdd599a Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 20 Jun 2024 15:01:33 +0200 Subject: [PATCH 116/120] minor code consolidation --- vms/components/fee/dimensions.go | 6 ++-- vms/components/fee/helpers.go | 21 +++++++------ wallet/chain/p/builder/builder.go | 30 +++++++++---------- .../fee => wallet/chain/p/builder}/helpers.go | 30 ++++++++++--------- 4 files changed, 44 insertions(+), 43 deletions(-) rename {vms/platformvm/txs/fee => wallet/chain/p/builder}/helpers.go (50%) diff --git a/vms/components/fee/dimensions.go b/vms/components/fee/dimensions.go index 2be2c10a9d9e..fc59c70145d5 100644 --- a/vms/components/fee/dimensions.go +++ b/vms/components/fee/dimensions.go @@ -9,9 +9,9 @@ import ( const ( Bandwidth Dimension = 0 - UTXORead Dimension = 1 - UTXOWrite Dimension = 2 // includes delete - Compute Dimension = 3 // signatures checks, tx-specific + DBRead Dimension = 1 + DBWrite Dimension = 2 // includes deletes + Compute Dimension = 3 FeeDimensions = 4 ) diff --git a/vms/components/fee/helpers.go b/vms/components/fee/helpers.go index 192215b282a1..26cc300b3cc9 100644 --- a/vms/components/fee/helpers.go +++ b/vms/components/fee/helpers.go @@ -15,41 +15,39 @@ import ( ) func MeterInput(c codec.Manager, v uint16, in *avax.TransferableInput) (Dimensions, error) { - var complexity Dimensions cost, err := in.In.Cost() if err != nil { - return complexity, fmt.Errorf("failed retrieving cost of input %s: %w", in.ID, err) + return Empty, fmt.Errorf("failed retrieving cost of input %s: %w", in.ID, err) } inSize, err := c.Size(v, in) if err != nil { - return complexity, fmt.Errorf("failed retrieving size of input %s: %w", in.ID, err) + 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[UTXORead] += uInSize // inputs are read - complexity[UTXOWrite] += uInSize // inputs are deleted + 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) { - var complexity Dimensions outSize, err := c.Size(v, out) if err != nil { - return complexity, fmt.Errorf("failed retrieving size of output %s: %w", out.ID, err) + 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[UTXOWrite] += uOutSize + complexity[DBWrite] += uOutSize return complexity, nil } func MeterCredential(c codec.Manager, v uint16, keysCount int) (Dimensions, error) { - var complexity Dimensions - // Ensure that codec picks interface instead of the pointer to evaluate size. creds := make([]verify.Verifiable, 0, 1) creds = append(creds, &secp256k1fx.Credential{ @@ -58,10 +56,11 @@ func MeterCredential(c codec.Manager, v uint16, keysCount int) (Dimensions, erro credSize, err := c.Size(v, creds) if err != nil { - return complexity, fmt.Errorf("failed retrieving size of credentials: %w", err) + 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/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index 4f712cc119c1..b601fb19bfd9 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -444,7 +444,7 @@ func (b *builder) NewAddSubnetValidatorTx( } // update fees to account for the auth credentials to be added upon tx signing - if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + if _, err = FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -492,7 +492,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( } // update fees to account for the auth credentials to be added upon tx signing - if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + if _, err = FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -591,7 +591,7 @@ func (b *builder) NewCreateChainTx( } // update fees to account for the auth credentials to be added upon tx signing - if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + if _, err = FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -679,7 +679,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( } // update fees to account for the auth credentials to be added upon tx signing - if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + if _, err = FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -793,7 +793,7 @@ func (b *builder) NewImportTx( } for _, sigIndices := range importedSigIndices { - if _, err = fee.FinanceCredential(feeCalc, len(sigIndices)); err != nil { + if _, err = FinanceCredential(feeCalc, len(sigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } } @@ -818,7 +818,7 @@ func (b *builder) NewImportTx( } // update fees to target given the extra output added - _, outDimensions, err := fee.FinanceOutput(feeCalc, changeOut) + _, outDimensions, err := FinanceOutput(feeCalc, changeOut) if err != nil { return nil, fmt.Errorf("account for output fees: %w", err) } @@ -967,7 +967,7 @@ func (b *builder) NewTransformSubnetTx( } // update fees to account for the auth credentials to be added upon tx signing - if _, err = fee.FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + if _, err = FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -1235,13 +1235,13 @@ func (b *builder) financeTx( }, } - addedFees, err := fee.FinanceInput(feeCalc, input) + addedFees, err := FinanceInput(feeCalc, input) if err != nil { return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } amountsToBurn[avaxAssetID] += addedFees - addedFees, err = fee.FinanceCredential(feeCalc, len(inputSigIndices)) + addedFees, err = FinanceCredential(feeCalc, len(inputSigIndices)) if err != nil { return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } @@ -1267,7 +1267,7 @@ func (b *builder) financeTx( }, } - addedFees, _, err = fee.FinanceOutput(feeCalc, stakeOut) + addedFees, _, err = FinanceOutput(feeCalc, stakeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } @@ -1290,7 +1290,7 @@ func (b *builder) financeTx( } // update fees to account for the change output - addedFees, _, err = fee.FinanceOutput(feeCalc, changeOut) + addedFees, _, err = FinanceOutput(feeCalc, changeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } @@ -1342,13 +1342,13 @@ func (b *builder) financeTx( }, } - addedFees, err := fee.FinanceInput(feeCalc, input) + addedFees, err := FinanceInput(feeCalc, input) if err != nil { return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } amountsToBurn[avaxAssetID] += addedFees - addedFees, err = fee.FinanceCredential(feeCalc, len(inputSigIndices)) + addedFees, err = FinanceCredential(feeCalc, len(inputSigIndices)) if err != nil { return nil, nil, nil, fmt.Errorf("account for credential fees: %w", err) } @@ -1374,7 +1374,7 @@ func (b *builder) financeTx( stakeOutputs = append(stakeOutputs, stakeOut) - addedFees, _, err = fee.FinanceOutput(feeCalc, stakeOut) + addedFees, _, err = FinanceOutput(feeCalc, stakeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } @@ -1398,7 +1398,7 @@ func (b *builder) financeTx( } // update fees to account for the change output - addedFees, _, err = fee.FinanceOutput(feeCalc, changeOut) + addedFees, _, err = FinanceOutput(feeCalc, changeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } diff --git a/vms/platformvm/txs/fee/helpers.go b/wallet/chain/p/builder/helpers.go similarity index 50% rename from vms/platformvm/txs/fee/helpers.go rename to wallet/chain/p/builder/helpers.go index e2cda9454d36..2edaa6985624 100644 --- a/vms/platformvm/txs/fee/helpers.go +++ b/wallet/chain/p/builder/helpers.go @@ -1,22 +1,24 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package fee +package builder import ( "fmt" "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) -func FinanceInput(feeCalc *Calculator, input *avax.TransferableInput) (uint64, error) { - if !feeCalc.b.isEActive() { +func FinanceInput(feeCalc *fee.Calculator, input *avax.TransferableInput) (uint64, error) { + if !feeCalc.IsEActive() { return 0, nil // pre E-upgrade we have a fixed fee regardless how complex the input is } - inDimensions, err := fee.MeterInput(txs.Codec, txs.CodecVersion, input) + inDimensions, err := commonfee.MeterInput(txs.Codec, txs.CodecVersion, input) if err != nil { return 0, fmt.Errorf("failed calculating input size: %w", err) } @@ -27,28 +29,28 @@ func FinanceInput(feeCalc *Calculator, input *avax.TransferableInput) (uint64, e return addedFees, nil } -func FinanceOutput(feeCalc *Calculator, output *avax.TransferableOutput) (uint64, fee.Dimensions, error) { - if !feeCalc.b.isEActive() { - return 0, fee.Empty, nil // pre E-upgrade we have a fixed fee regardless how complex the output is +func FinanceOutput(feeCalc *fee.Calculator, output *avax.TransferableOutput) (uint64, commonfee.Dimensions, error) { + if !feeCalc.IsEActive() { + return 0, commonfee.Empty, nil // pre E-upgrade we have a fixed fee regardless how complex the output is } - outDimensions, err := fee.MeterOutput(txs.Codec, txs.CodecVersion, output) + outDimensions, err := commonfee.MeterOutput(txs.Codec, txs.CodecVersion, output) if err != nil { - return 0, fee.Empty, fmt.Errorf("failed calculating changeOut size: %w", err) + return 0, commonfee.Empty, fmt.Errorf("failed calculating changeOut size: %w", err) } addedFees, err := feeCalc.AddFeesFor(outDimensions) if err != nil { - return 0, fee.Empty, fmt.Errorf("account for stakedOut fees: %w", err) + return 0, commonfee.Empty, fmt.Errorf("account for stakedOut fees: %w", err) } return addedFees, outDimensions, nil } -func FinanceCredential(feeCalc *Calculator, keysCount int) (uint64, error) { - if !feeCalc.b.isEActive() { +func FinanceCredential(feeCalc *fee.Calculator, keysCount int) (uint64, error) { + if !feeCalc.IsEActive() { return 0, nil // pre E-upgrade we have a fixed fee regardless how complex the credentials are } - credDimensions, err := fee.MeterCredential(txs.Codec, txs.CodecVersion, keysCount) + credDimensions, err := commonfee.MeterCredential(txs.Codec, txs.CodecVersion, keysCount) if err != nil { return 0, fmt.Errorf("failed calculating input size: %w", err) } From 6f61cc330569212fb084a942c0aeaa880ed4d978 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 20 Jun 2024 15:51:54 +0200 Subject: [PATCH 117/120] added stakers state lookup cost --- vms/platformvm/txs/fee/calculator_test.go | 24 ++++++++++---------- vms/platformvm/txs/fee/dynamic_calculator.go | 6 +++++ wallet/chain/p/builder_test.go | 9 ++++---- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/vms/platformvm/txs/fee/calculator_test.go b/vms/platformvm/txs/fee/calculator_test.go index dad23b99d340..8ae7c06706eb 100644 --- a/vms/platformvm/txs/fee/calculator_test.go +++ b/vms/platformvm/txs/fee/calculator_test.go @@ -141,8 +141,8 @@ func TestTxFees(t *testing.T) { expectedError: nil, unsignedAndSignedTx: addSubnetValidatorTx, checksF: func(t *testing.T, c *Calculator) { - require.Equal(t, 19_110*units.NanoAvax, c.GetFee()) - require.Equal(t, fee.Gas(1911), c.GetBlockGas()) + require.Equal(t, 29_110*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(2_911), c.GetBlockGas()) }, }, { @@ -256,8 +256,8 @@ func TestTxFees(t *testing.T) { unsignedAndSignedTx: removeSubnetValidatorTx, expectedError: nil, checksF: func(t *testing.T, c *Calculator) { - require.Equal(t, 18_870*units.NanoAvax, c.GetFee()) - require.Equal(t, fee.Gas(1_887), c.GetBlockGas()) + require.Equal(t, 28_870*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(2_887), c.GetBlockGas()) }, }, { @@ -356,8 +356,8 @@ func TestTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, c *Calculator) { - require.Equal(t, 23_170*units.NanoAvax, c.GetFee()) - require.Equal(t, fee.Gas(2_317), c.GetBlockGas()) + require.Equal(t, 33_170*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(3_317), c.GetBlockGas()) }, }, { @@ -370,8 +370,8 @@ func TestTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, c *Calculator) { - require.Equal(t, 23_170*units.NanoAvax, c.GetFee()) - require.Equal(t, fee.Gas(2_317), c.GetBlockGas()) + require.Equal(t, 33_170*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(3_317), c.GetBlockGas()) }, }, { @@ -417,8 +417,8 @@ func TestTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, c *Calculator) { - require.Equal(t, 21_250*units.NanoAvax, c.GetFee()) - require.Equal(t, fee.Gas(2_125), c.GetBlockGas()) + require.Equal(t, 31_250*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(3_125), c.GetBlockGas()) }, }, { @@ -429,8 +429,8 @@ func TestTxFees(t *testing.T) { }, expectedError: nil, checksF: func(t *testing.T, c *Calculator) { - require.Equal(t, 21_250*units.NanoAvax, c.GetFee()) - require.Equal(t, fee.Gas(2_125), c.GetBlockGas()) + require.Equal(t, 31_250*units.NanoAvax, c.GetFee()) + require.Equal(t, fee.Gas(3_125), c.GetBlockGas()) }, }, { diff --git a/vms/platformvm/txs/fee/dynamic_calculator.go b/vms/platformvm/txs/fee/dynamic_calculator.go index 24e858a932fe..8efec7d88c4d 100644 --- a/vms/platformvm/txs/fee/dynamic_calculator.go +++ b/vms/platformvm/txs/fee/dynamic_calculator.go @@ -16,6 +16,8 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) +const StakerLookupCost uint64 = 1000 // equal to secp256k1fx.CostPerSignature + var ( _ backend = (*dynamicCalculator)(nil) @@ -50,6 +52,7 @@ func (c *dynamicCalculator) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) e if err != nil { return err } + complexity[fee.Compute] += StakerLookupCost _, err = c.addFeesFor(complexity) return err @@ -95,6 +98,7 @@ func (c *dynamicCalculator) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidato if err != nil { return err } + complexity[fee.Compute] += StakerLookupCost _, err = c.addFeesFor(complexity) return err @@ -129,6 +133,7 @@ func (c *dynamicCalculator) AddPermissionlessValidatorTx(tx *txs.AddPermissionle if err != nil { return err } + complexity[fee.Compute] += StakerLookupCost _, err = c.addFeesFor(complexity) return err @@ -143,6 +148,7 @@ func (c *dynamicCalculator) AddPermissionlessDelegatorTx(tx *txs.AddPermissionle if err != nil { return err } + complexity[fee.Compute] += StakerLookupCost _, err = c.addFeesFor(complexity) return err diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 3ac7049da955..901361959ca0 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -30,6 +30,7 @@ import ( "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" stdcontext "context" + commonfee "github.com/ava-labs/avalanchego/vms/components/fee" blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) @@ -209,7 +210,7 @@ func TestAddSubnetValidatorTx(t *testing.T) { fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(30_610*units.MicroAvax, fee) + require.Equal(40_610*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -301,7 +302,7 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(30_370*units.MicroAvax, fee) + require.Equal(40_370*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -1014,7 +1015,7 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(65_240*units.MicroAvax, fee) + require.Equal(75_240*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins @@ -1130,7 +1131,7 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { fc := fee.NewDynamicCalculator(testGasPrice, testBlockMaxGas) fee, err := fc.ComputeFee(utx, tx.Creds) require.NoError(err) - require.Equal(63_320*units.MicroAvax, fee) + require.Equal(73_320*units.MicroAvax, fee) // check UTXOs selection and fee financing ins := utx.Ins From 30379a3fa01c339741e8f81620c211651c19fc0b Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 20 Jun 2024 15:57:01 +0200 Subject: [PATCH 118/120] nit --- vms/platformvm/txs/fee/dynamic_calculator.go | 4 ++-- wallet/chain/p/builder_test.go | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/vms/platformvm/txs/fee/dynamic_calculator.go b/vms/platformvm/txs/fee/dynamic_calculator.go index 8efec7d88c4d..3b53f2d07cb6 100644 --- a/vms/platformvm/txs/fee/dynamic_calculator.go +++ b/vms/platformvm/txs/fee/dynamic_calculator.go @@ -252,7 +252,7 @@ func (c *dynamicCalculator) meterTx( } func (c *dynamicCalculator) addFeesFor(complexity fee.Dimensions) (uint64, error) { - if c.fc == nil || complexity == fee.Empty { + if complexity == fee.Empty { return 0, nil } @@ -278,7 +278,7 @@ func (c *dynamicCalculator) addFeesFor(complexity fee.Dimensions) (uint64, error } func (c *dynamicCalculator) removeFeesFor(unitsToRm fee.Dimensions) (uint64, error) { - if c.fc == nil || unitsToRm == fee.Empty { + if unitsToRm == fee.Empty { return 0, nil } diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 901361959ca0..55067518e345 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -30,7 +30,6 @@ import ( "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" stdcontext "context" - commonfee "github.com/ava-labs/avalanchego/vms/components/fee" blssigner "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) From 0bf1e4f1974d922c2ffab4786677882257acab08 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 4 Jul 2024 09:58:00 +0200 Subject: [PATCH 119/120] nit --- wallet/chain/p/builder/builder.go | 30 +++++++++++++++--------------- wallet/chain/p/builder/helpers.go | 6 +++--- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index b8a6b9316456..ba1410e3598e 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -444,7 +444,7 @@ func (b *builder) NewAddSubnetValidatorTx( } // update fees to account for the auth credentials to be added upon tx signing - if _, err = FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + if _, err = financeCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -492,7 +492,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( } // update fees to account for the auth credentials to be added upon tx signing - if _, err = FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + if _, err = financeCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -591,7 +591,7 @@ func (b *builder) NewCreateChainTx( } // update fees to account for the auth credentials to be added upon tx signing - if _, err = FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + if _, err = financeCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -679,7 +679,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( } // update fees to account for the auth credentials to be added upon tx signing - if _, err = FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + if _, err = financeCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -793,7 +793,7 @@ func (b *builder) NewImportTx( } for _, sigIndices := range importedSigIndices { - if _, err = FinanceCredential(feeCalc, len(sigIndices)); err != nil { + if _, err = financeCredential(feeCalc, len(sigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } } @@ -818,7 +818,7 @@ func (b *builder) NewImportTx( } // update fees to target given the extra output added - _, outDimensions, err := FinanceOutput(feeCalc, changeOut) + _, outDimensions, err := financeOutput(feeCalc, changeOut) if err != nil { return nil, fmt.Errorf("account for output fees: %w", err) } @@ -967,7 +967,7 @@ func (b *builder) NewTransformSubnetTx( } // update fees to account for the auth credentials to be added upon tx signing - if _, err = FinanceCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { + if _, err = financeCredential(feeCalc, len(subnetAuth.SigIndices)); err != nil { return nil, fmt.Errorf("account for credential fees: %w", err) } @@ -1235,13 +1235,13 @@ func (b *builder) financeTx( }, } - addedFees, err := FinanceInput(feeCalc, input) + addedFees, err := financeInput(feeCalc, input) if err != nil { return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } amountsToBurn[avaxAssetID] += addedFees - addedFees, err = FinanceCredential(feeCalc, len(inputSigIndices)) + addedFees, err = financeCredential(feeCalc, len(inputSigIndices)) if err != nil { return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } @@ -1267,7 +1267,7 @@ func (b *builder) financeTx( }, } - addedFees, _, err = FinanceOutput(feeCalc, stakeOut) + addedFees, _, err = financeOutput(feeCalc, stakeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } @@ -1290,7 +1290,7 @@ func (b *builder) financeTx( } // update fees to account for the change output - addedFees, _, err = FinanceOutput(feeCalc, changeOut) + addedFees, _, err = financeOutput(feeCalc, changeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } @@ -1342,13 +1342,13 @@ func (b *builder) financeTx( }, } - addedFees, err := FinanceInput(feeCalc, input) + addedFees, err := financeInput(feeCalc, input) if err != nil { return nil, nil, nil, fmt.Errorf("account for input fees: %w", err) } amountsToBurn[avaxAssetID] += addedFees - addedFees, err = FinanceCredential(feeCalc, len(inputSigIndices)) + addedFees, err = financeCredential(feeCalc, len(inputSigIndices)) if err != nil { return nil, nil, nil, fmt.Errorf("account for credential fees: %w", err) } @@ -1374,7 +1374,7 @@ func (b *builder) financeTx( stakeOutputs = append(stakeOutputs, stakeOut) - addedFees, _, err = FinanceOutput(feeCalc, stakeOut) + addedFees, _, err = financeOutput(feeCalc, stakeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } @@ -1398,7 +1398,7 @@ func (b *builder) financeTx( } // update fees to account for the change output - addedFees, _, err = FinanceOutput(feeCalc, changeOut) + addedFees, _, err = financeOutput(feeCalc, changeOut) if err != nil { return nil, nil, nil, fmt.Errorf("account for output fees: %w", err) } diff --git a/wallet/chain/p/builder/helpers.go b/wallet/chain/p/builder/helpers.go index f681bbf2bc64..9167e7109d8c 100644 --- a/wallet/chain/p/builder/helpers.go +++ b/wallet/chain/p/builder/helpers.go @@ -13,7 +13,7 @@ import ( commonfee "github.com/ava-labs/avalanchego/vms/components/fee" ) -func FinanceInput(feeCalc fee.Calculator, input *avax.TransferableInput) (uint64, error) { +func financeInput(feeCalc fee.Calculator, input *avax.TransferableInput) (uint64, error) { if !feeCalc.IsEActive() { return 0, nil // pre E-upgrade we have a fixed fee regardless how complex the input is } @@ -29,7 +29,7 @@ func FinanceInput(feeCalc fee.Calculator, input *avax.TransferableInput) (uint64 return addedFees, nil } -func FinanceOutput(feeCalc fee.Calculator, output *avax.TransferableOutput) (uint64, commonfee.Dimensions, error) { +func financeOutput(feeCalc fee.Calculator, output *avax.TransferableOutput) (uint64, commonfee.Dimensions, error) { if !feeCalc.IsEActive() { return 0, commonfee.Empty, nil // pre E-upgrade we have a fixed fee regardless how complex the output is } @@ -45,7 +45,7 @@ func FinanceOutput(feeCalc fee.Calculator, output *avax.TransferableOutput) (uin return addedFees, outDimensions, nil } -func FinanceCredential(feeCalc fee.Calculator, keysCount int) (uint64, error) { +func financeCredential(feeCalc fee.Calculator, keysCount int) (uint64, error) { if !feeCalc.IsEActive() { return 0, nil // pre E-upgrade we have a fixed fee regardless how complex the credentials are } From 531b21f3ad2088ba4384b582c9f357315ab13340 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 4 Jul 2024 11:02:55 +0200 Subject: [PATCH 120/120] nit --- wallet/chain/p/builder/builder.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index ba1410e3598e..4f0dd1fe588a 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -798,18 +798,18 @@ func (b *builder) NewImportTx( } } - switch importedAVAX := importedAmounts[avaxAssetID]; { - case importedAVAX == feeCalc.GetFee(): + switch importedAVAX, currentFee := importedAmounts[avaxAssetID], feeCalc.GetFee(); { + case importedAVAX == currentFee: // imported inputs match exactly the fees to be paid avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs return utx, b.initCtx(utx) - case importedAVAX < feeCalc.GetFee(): + case importedAVAX < currentFee: // imported inputs can partially pay fees - feeCalc.ResetFee(feeCalc.GetFee() - importedAmounts[avaxAssetID]) + feeCalc.ResetFee(currentFee - importedAVAX) default: - // imported inputs may be enough to pay taxes by themselves + // imported inputs may be enough to pay fees by themselves changeOut := &avax.TransferableOutput{ Asset: avax.Asset{ID: avaxAssetID}, Out: &secp256k1fx.TransferOutput{ @@ -823,14 +823,14 @@ func (b *builder) NewImportTx( return nil, fmt.Errorf("account for output fees: %w", err) } - switch fee := feeCalc.GetFee(); { - case fee < importedAVAX: - changeOut.Out.(*secp256k1fx.TransferOutput).Amt = importedAVAX - fee + switch currentFee := feeCalc.GetFee(); { + case currentFee < importedAVAX: + changeOut.Out.(*secp256k1fx.TransferOutput).Amt = importedAVAX - currentFee utx.Outs = append(utx.Outs, changeOut) avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs return utx, b.initCtx(utx) - case fee == importedAVAX: + case currentFee == importedAVAX: // imported fees pays exactly the tx cost. We don't include the outputs avax.SortTransferableOutputs(utx.Outs, txs.Codec) // sort imported outputs return utx, b.initCtx(utx) @@ -841,7 +841,7 @@ func (b *builder) NewImportTx( if _, err := feeCalc.RemoveFeesFor(outDimensions); err != nil { return nil, fmt.Errorf("failed reverting change output: %w", err) } - feeCalc.ResetFee(fee - importedAVAX) + feeCalc.ResetFee(currentFee - importedAVAX) } }