From f5ff8d67902e8b1ff64e87e59414174817f52afe Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 19 Feb 2024 18:32:57 +0100 Subject: [PATCH 01/51] 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 626edf6e56e..03be8303c4f 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 8da002d2c5c..b7a5abfd1ee 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 6d968daa4df..dae8c5e08fc 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 6368d97c11c..39e688eb6ba 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 02/51] 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 00000000000..e864da0ec3d --- /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 bedbbdbf562..1902f99d2b7 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 7c9dd4cb95c..3e41a6952d7 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 5b8001808ce..ac42880451b 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 d8b118fa21b..7de12ce42fc 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 85f9b611101..7b51c3e7acc 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 44cc7e2a4da..6eab4bb2eab 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 4982e77f8a5..41be6109dc3 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 2b8d8b8eeec..3f1bd27be10 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 9aabf651cff..a84421cf84b 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 03/51] 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 03be8303c4f..63e5fcb03e9 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 00000000000..680bb47a6ea --- /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 fa394cee4d5..971aa54edd0 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 caec47b386c..a99f32f36db 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 04/51] 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 63e5fcb03e9..215aba10dab 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 971aa54edd0..cc495250510 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 a99f32f36db..21a45d4bc30 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 39e688eb6ba..562a2ca94e5 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 05/51] 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 00000000000..cce25523dfc --- /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 00000000000..0406db65f71 --- /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 1902f99d2b7..976442c8ee7 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 3e41a6952d7..5ae15131570 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 215aba10dab..49b241542b5 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 00000000000..b7fd6abcf83 --- /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 680bb47a6ea..058b1308264 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 cc495250510..b8b2c9deecb 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 21a45d4bc30..f9667cd94ce 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 e864da0ec3d..00000000000 --- 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 562a2ca94e5..019c1ca3d3b 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 ac42880451b..08c8c83737f 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 7de12ce42fc..d3668cac9f1 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 7b51c3e7acc..f90bdfb4a80 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 47310314754..16da083ea6a 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 2511a19a9db..235cf74a57f 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 6eab4bb2eab..d4b7667d632 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 41be6109dc3..4982e77f8a5 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 3c30b60d81c..2b5ef8c155c 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 3f1bd27be10..2b8d8b8eeec 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 a84421cf84b..6a0fc71ac71 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 06/51] 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 f90bdfb4a80..86cc3a782bb 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 0406db65f71..6b7cf5ee78d 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 16da083ea6a..43b5a10f60a 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 a402355b9e0..b99f774a426 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 235cf74a57f..f93513d640e 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 d4b7667d632..842a03f23e3 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 4982e77f8a5..62e8fb8e0d0 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 08f2cd538c2..f0f4b07c488 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 6a0fc71ac71..95a0fe82be8 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 07/51] 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 86cc3a782bb..1f625dbc5bd 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 6b7cf5ee78d..788d9fb4bcf 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 49b241542b5..352afe2de06 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 b7fd6abcf83..5ef3dce401d 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 b8b2c9deecb..d53166eafdd 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 1b16e72bf3c..7e3378ed045 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 08/51] 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 352afe2de06..92fd87bcf0f 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 09/51] 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 1f625dbc5bd..5d2eb710dae 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 92fd87bcf0f..63bf72d38e8 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 5ef3dce401d..ef832534292 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 058b1308264..dfc3b997897 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 d53166eafdd..25d5039091e 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 f9667cd94ce..6f315e3cf57 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 bc52fabc247..369ee960887 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 a6ecc21b405..d90288ac1c9 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 69ad018caa1..88129567581 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 7e3378ed045..4ec69c9b5ce 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 10/51] 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 9190f01e2c6..37573591265 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 825625b7c77..cf486fd7267 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 63bf72d38e8..34df225ab49 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 f319b19826a..e6f09f06c36 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 8c4801e06ea..db64477e304 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 11/51] 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 37573591265..eb61e6830c3 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 cf486fd7267..3c3ccf1474e 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 25d5039091e..5abc8e2567f 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 6f315e3cf57..7aae42ff09b 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 e6f09f06c36..71bf4753412 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 019c1ca3d3b..4adde447bad 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 d0224ed4666..24bb95e024d 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 db64477e304..deb2785f21f 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 12/51] 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 34df225ab49..ad8fcc4e090 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 ef832534292..14ecd83d4d4 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 dfc3b997897..79d396c5bb2 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 5abc8e2567f..5e51cc51ce9 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 7aae42ff09b..c4172f16e91 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 369ee960887..40ef33852fc 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 4ec69c9b5ce..f7bb612bb65 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 08c8c83737f..a241fde2225 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 d3668cac9f1..afbaad3a09a 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 43b5a10f60a..6f31a0af12b 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 b99f774a426..7bfaf004630 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 f93513d640e..862e2364525 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 842a03f23e3..1fd85e8cabe 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 62e8fb8e0d0..53067332dc4 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 2b5ef8c155c..0e559affc45 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 f0f4b07c488..df8d0bdf62d 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 95a0fe82be8..084f1bdff01 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 13/51] 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 a241fde2225..3cdafcef9d3 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 cce25523dfc..77caac1a94a 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 14/51] 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 976442c8ee7..ec5f70befe1 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 5ae15131570..5a237cfc499 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 15/51] 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 5b8001808ce..3cdafcef9d3 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 d8b118fa21b..afbaad3a09a 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 00000000000..77caac1a94a --- /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 85f9b611101..b82a91cc4bf 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 00000000000..788d9fb4bcf --- /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 bedbbdbf562..6b99cba60cf 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 7c9dd4cb95c..5a237cfc499 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 47310314754..6f31a0af12b 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 a402355b9e0..7bfaf004630 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 2511a19a9db..862e2364525 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 44cc7e2a4da..1fd85e8cabe 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 4982e77f8a5..53067332dc4 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 3c30b60d81c..0e559affc45 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 08f2cd538c2..df8d0bdf62d 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 9aabf651cff..47777eb25d1 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 16/51] 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 14ecd83d4d4..b21952543c9 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 d105ce4ebf8..9a7e6b5dea1 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 79d396c5bb2..00000000000 --- 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 9d611e69e05..2c918477f35 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 d9b7a3f2964..57595cda23e 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 17/51] 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 3c3ccf1474e..a1f44504a33 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 b21952543c9..bb7c36b5ab4 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 9a7e6b5dea1..e0b7dd1b19b 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 2c918477f35..f04516faf7b 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 57595cda23e..2b5396f432a 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 18/51] 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 e0b7dd1b19b..ea63e8f302e 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 19/51] 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 a1f44504a33..e5674bc7cb3 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 bb7c36b5ab4..be416b38de3 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 f04516faf7b..81552b074f4 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 20/51] 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 be416b38de3..06477cfd555 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 81552b074f4..8b51e098b7e 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 2b5396f432a..e8d88a541a4 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 21/51] 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 ea63e8f302e..8daacafefad 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 b82a91cc4bf..a3fb355749d 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 ebc1b505db295625c336bb9d3bd71d7de1a4da42 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 26 Feb 2024 14:02:28 +0100 Subject: [PATCH 22/51] 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 eb61e6830c3..bada93b97a0 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 e5674bc7cb3..6a774a3ade2 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 71bf4753412..5574751c951 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 deb2785f21f..70f0f01ff4c 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 16cf7c4c05145f87d04fd8a98d533508ca7b9096 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 18 Mar 2024 18:10:14 -0400 Subject: [PATCH 23/51] 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 24f76613330..d33a8808e0f 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 a9c70beacbf..f45a1f8c666 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 436d89675bc..e988cf43c2c 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 36072e327a2..a3f3e1e9f07 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 1819df44856..7b9e213acaa 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 3cdafcef9d3..ed8e6a4f883 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 afbaad3a09a..c7cec9544da 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 77caac1a94a..00000000000 --- 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 788d9fb4bcf..00000000000 --- 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 6c041f1fa60..70433b11dac 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 7bfaf004630..d831e0c76da 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 00000000000..4b03cd41dce --- /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 9f99202d33e..9f73b9e399b 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 862e2364525..057d5553ea0 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 6b99cba60cf..08b3a9d9963 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 5a237cfc499..58d6a5e0b3c 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 0647d7e8db3..e5952f1067c 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 53067332dc4..92965f2e4f1 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 0e559affc45..980eabbbe5c 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 987229d1ec2..8f0348f2b7c 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 32cdcf983ba..81b78ad5bc2 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 df8d0bdf62d..e190247515b 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 47777eb25d1..6a9e9d3124b 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 24/51] 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 70433b11dac..a9593940571 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 25/51] 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 06477cfd555..4fb4d890444 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 8daacafefad..d49f12edd5f 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 00000000000..78fcf87def4 --- /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 8b51e098b7e..7ab69b519ec 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 e8d88a541a4..bcf9a6b2e6d 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 40ef33852fc..5ac6a76354b 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 26/51] 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 bf43748e1bd..185b9e5201b 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 d9506ec34a5..b411efae8dd 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 4b03cd41dce..f465ae9fa86 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 27/51] 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 a9593940571..e142342dc48 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 4b03cd41dce..f465ae9fa86 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 28/51] 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 185b9e5201b..d1135ebc540 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 29/51] 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 d49f12edd5f..d33bc85829e 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 30/51] 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 f465ae9fa86..f0da23fdc5f 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 057d5553ea0..00000000000 --- 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 980eabbbe5c..7486cde263e 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 31/51] 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 58d6a5e0b3c..5dd4abe2b7d 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 32/51] 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 81b78ad5bc2..a6cf5c78604 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 33/51] 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 8f0348f2b7c..7c2b6c05585 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 34/51] 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 4f5c7a668b3..906ed5edcba 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 5d135978e04b991e6303fca980f1c8a0aa5556fc Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:44:58 -0400 Subject: [PATCH 35/51] nits (#2861) --- vms/platformvm/service.go | 3 +- vms/platformvm/service_test.go | 50 ++++---- vms/platformvm/validator_set_property_test.go | 29 ++++- vms/platformvm/vm.go | 16 +-- vms/platformvm/vm_regression_test.go | 108 ++++++++++-------- vms/platformvm/vm_test.go | 92 ++++++++------- 6 files changed, 165 insertions(+), 133 deletions(-) diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index 706fe8daced..8ef46eef265 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -68,6 +68,7 @@ type Service struct { vm *VM addrManager avax.AddressManager stakerAttributesCache *cache.LRU[ids.ID, *stakerAttributes] + atomicUtxosManager avax.AtomicUTXOManager } // All attributes are optional and may not be filled for each stakerTx. @@ -381,7 +382,7 @@ func (s *Service) GetUTXOs(_ *http.Request, args *api.GetUTXOsArgs, response *ap limit, ) } else { - utxos, endAddr, endUTXOID, err = s.vm.atomicUtxosManager.GetAtomicUTXOs( + utxos, endAddr, endUTXOID, err = s.atomicUtxosManager.GetAtomicUTXOs( sourceChain, addrSet, startAddr, diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 84ef2c60422..a2199eb7dc0 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -45,6 +45,7 @@ import ( 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" + txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" ) @@ -72,8 +73,8 @@ var ( } ) -func defaultService(t *testing.T) (*Service, *mutableSharedMemory) { - vm, _, mutableSharedMemory := defaultVM(t, latestFork) +func defaultService(t *testing.T) (*Service, *mutableSharedMemory, txbuilder.Builder) { + vm, txBuilder, _, mutableSharedMemory := defaultVM(t, latestFork) return &Service{ vm: vm, @@ -81,13 +82,14 @@ func defaultService(t *testing.T) (*Service, *mutableSharedMemory) { stakerAttributesCache: &cache.LRU[ids.ID, *stakerAttributes]{ Size: stakerAttributesCacheSize, }, - }, mutableSharedMemory + atomicUtxosManager: avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), + }, mutableSharedMemory, txBuilder } func TestExportKey(t *testing.T) { require := require.New(t) - service, _ := defaultService(t) + service, _, _ := defaultService(t) service.vm.ctx.Lock.Lock() ks := keystore.New(logging.NoLog{}, memdb.New()) @@ -117,7 +119,7 @@ func TestExportKey(t *testing.T) { // Test issuing a tx and accepted func TestGetTxStatus(t *testing.T) { require := require.New(t) - service, mutableSharedMemory := defaultService(t) + service, mutableSharedMemory, txBuilder := defaultService(t) service.vm.ctx.Lock.Lock() recipientKey, err := secp256k1.NewPrivateKey() @@ -164,7 +166,7 @@ func TestGetTxStatus(t *testing.T) { mutableSharedMemory.SharedMemory = sm - tx, err := service.vm.txBuilder.NewImportTx( + tx, err := txBuilder.NewImportTx( service.vm.ctx.XChainID, ids.ShortEmpty, []*secp256k1.PrivateKey{recipientKey}, @@ -207,14 +209,14 @@ func TestGetTxStatus(t *testing.T) { func TestGetTx(t *testing.T) { type test struct { description string - createTx func(service *Service) (*txs.Tx, error) + createTx func(service *Service, builder txbuilder.Builder) (*txs.Tx, error) } tests := []test{ { "standard block", - func(service *Service) (*txs.Tx, error) { - return service.vm.txBuilder.NewCreateChainTx( // Test GetTx works for standard blocks + func(_ *Service, builder txbuilder.Builder) (*txs.Tx, error) { + return builder.NewCreateChainTx( // Test GetTx works for standard blocks testSubnet1.ID(), []byte{}, constants.AVMID, @@ -228,11 +230,11 @@ func TestGetTx(t *testing.T) { }, { "proposal block", - func(service *Service) (*txs.Tx, error) { + func(service *Service, builder txbuilder.Builder) (*txs.Tx, error) { sk, err := bls.NewSecretKey() require.NoError(t, err) - return service.vm.txBuilder.NewAddPermissionlessValidatorTx( // Test GetTx works for proposal blocks + return builder.NewAddPermissionlessValidatorTx( // Test GetTx works for proposal blocks service.vm.MinValidatorStake, uint64(service.vm.clock.Time().Add(txexecutor.SyncBound).Unix()), uint64(service.vm.clock.Time().Add(txexecutor.SyncBound).Add(defaultMinStakingDuration).Unix()), @@ -248,8 +250,8 @@ func TestGetTx(t *testing.T) { }, { "atomic block", - func(service *Service) (*txs.Tx, error) { - return service.vm.txBuilder.NewExportTx( // Test GetTx works for proposal blocks + func(service *Service, builder txbuilder.Builder) (*txs.Tx, error) { + return builder.NewExportTx( // Test GetTx works for proposal blocks 100, service.vm.ctx.XChainID, ids.GenerateTestShortID(), @@ -269,10 +271,10 @@ func TestGetTx(t *testing.T) { ) t.Run(testName, func(t *testing.T) { require := require.New(t) - service, _ := defaultService(t) + service, _, txBuilder := defaultService(t) service.vm.ctx.Lock.Lock() - tx, err := test.createTx(service) + tx, err := test.createTx(service, txBuilder) require.NoError(err) service.vm.ctx.Lock.Unlock() @@ -333,7 +335,7 @@ func TestGetTx(t *testing.T) { func TestGetBalance(t *testing.T) { require := require.New(t) - service, _ := defaultService(t) + service, _, _ := defaultService(t) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) @@ -361,7 +363,7 @@ func TestGetBalance(t *testing.T) { func TestGetStake(t *testing.T) { require := require.New(t) - service, _ := defaultService(t) + service, _, txBuilder := defaultService(t) // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) @@ -433,7 +435,7 @@ func TestGetStake(t *testing.T) { delegatorNodeID := genesisNodeIDs[0] delegatorStartTime := defaultValidateStartTime delegatorEndTime := defaultGenesisTime.Add(defaultMinStakingDuration) - tx, err := service.vm.txBuilder.NewAddDelegatorTx( + tx, err := txBuilder.NewAddDelegatorTx( stakeAmount, uint64(delegatorStartTime.Unix()), uint64(delegatorEndTime.Unix()), @@ -488,7 +490,7 @@ func TestGetStake(t *testing.T) { stakeAmount = service.vm.MinValidatorStake + 54321 pendingStakerNodeID := ids.GenerateTestNodeID() pendingStakerEndTime := uint64(defaultGenesisTime.Add(defaultMinStakingDuration).Unix()) - tx, err = service.vm.txBuilder.NewAddValidatorTx( + tx, err = txBuilder.NewAddValidatorTx( stakeAmount, uint64(defaultGenesisTime.Unix()), pendingStakerEndTime, @@ -533,7 +535,7 @@ func TestGetStake(t *testing.T) { func TestGetCurrentValidators(t *testing.T) { require := require.New(t) - service, _ := defaultService(t) + service, _, txBuilder := defaultService(t) genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) @@ -567,7 +569,7 @@ func TestGetCurrentValidators(t *testing.T) { service.vm.ctx.Lock.Lock() - delTx, err := service.vm.txBuilder.NewAddDelegatorTx( + delTx, err := txBuilder.NewAddDelegatorTx( stakeAmount, uint64(delegatorStartTime.Unix()), uint64(delegatorEndTime.Unix()), @@ -659,7 +661,7 @@ func TestGetCurrentValidators(t *testing.T) { func TestGetTimestamp(t *testing.T) { require := require.New(t) - service, _ := defaultService(t) + service, _, _ := defaultService(t) reply := GetTimestampReply{} require.NoError(service.GetTimestamp(nil, nil, &reply)) @@ -695,13 +697,13 @@ func TestGetBlock(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { require := require.New(t) - service, _ := defaultService(t) + service, _, txBuilder := defaultService(t) service.vm.ctx.Lock.Lock() service.vm.Config.CreateAssetTxFee = 100 * defaultTxFee // Make a block an accept it, then check we can get it. - tx, err := service.vm.txBuilder.NewCreateChainTx( // Test GetTx works for standard blocks + tx, err := txBuilder.NewCreateChainTx( // Test GetTx works for standard blocks testSubnet1.ID(), []byte{}, constants.AVMID, diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index f0a257ebfe0..83b99578523 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -36,6 +36,7 @@ import ( "github.com/ava-labs/avalanchego/utils/json" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/config" @@ -45,6 +46,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" 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" ) @@ -253,8 +255,15 @@ func takeValidatorsSnapshotAtCurrentHeight(vm *VM, validatorsSetByHeightAndSubne } func addSubnetValidator(vm *VM, data *validatorInputData, subnetID ids.ID) (*state.Staker, error) { + txBuilder := txbuilder.New( + vm.ctx, + &vm.Config, + vm.state, + avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), + ) + addr := keys[0].PublicKey().Address() - signedTx, err := vm.txBuilder.NewAddSubnetValidatorTx( + signedTx, err := txBuilder.NewAddSubnetValidatorTx( vm.Config.MinValidatorStake, uint64(data.startTime.Unix()), uint64(data.endTime.Unix()), @@ -278,7 +287,14 @@ func addPrimaryValidatorWithBLSKey(vm *VM, data *validatorInputData) (*state.Sta return nil, fmt.Errorf("failed to generate BLS key: %w", err) } - signedTx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( + txBuilder := txbuilder.New( + vm.ctx, + &vm.Config, + vm.state, + avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), + ) + + signedTx, err := txBuilder.NewAddPermissionlessValidatorTx( vm.Config.MinValidatorStake, uint64(data.startTime.Unix()), uint64(data.endTime.Unix()), @@ -676,10 +692,17 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { return nil, ids.Empty, err } + txBuilder := txbuilder.New( + vm.ctx, + &vm.Config, + vm.state, + avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), + ) + // Create a subnet and store it in testSubnet1 // Note: following Banff activation, block acceptance will move // chain time ahead - testSubnet1, err = vm.txBuilder.NewCreateSubnetTx( + testSubnet1, err = txBuilder.NewCreateSubnetTx( 1, // threshold []ids.ShortID{keys[0].PublicKey().Address()}, []*secp256k1.PrivateKey{keys[len(keys)-1]}, // pays tx fee diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 733e4758cf4..63791e30d23 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -47,7 +47,6 @@ import ( snowmanblock "github.com/ava-labs/avalanchego/snow/engine/snowman/block" 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" pvalidators "github.com/ava-labs/avalanchego/vms/platformvm/validators" ) @@ -65,8 +64,7 @@ type VM struct { *network.Network validators.State - metrics metrics.Metrics - atomicUtxosManager avax.AtomicUTXOManager + metrics metrics.Metrics // Used to get time. Useful for faking time during tests. clock mockable.Clock @@ -85,8 +83,7 @@ type VM struct { // Bootstrapped remembers if this chain has finished bootstrapping or not bootstrapped utils.Atomic[bool] - txBuilder txbuilder.Builder - manager blockexecutor.Manager + manager blockexecutor.Manager // Cancelled on shutdown onShutdownCtx context.Context @@ -154,18 +151,10 @@ 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) 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) - vm.txBuilder = txbuilder.New( - vm.ctx, - &vm.Config, - vm.state, - vm.atomicUtxosManager, - ) - txExecutorBackend := &txexecutor.Backend{ Config: &vm.Config, Ctx: vm.ctx, @@ -466,6 +455,7 @@ func (vm *VM) CreateHandlers(context.Context) (map[string]http.Handler, error) { stakerAttributesCache: &cache.LRU[ids.ID, *stakerAttributes]{ Size: stakerAttributesCacheSize, }, + atomicUtxosManager: avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), } err := server.RegisterService(service, "platform") return map[string]http.Handler{ diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 7ea72c61800..9d2afc070df 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -47,11 +47,12 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" + txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" ) func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, cortina) + vm, txBuilder, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -62,7 +63,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { changeAddr := keys[0].PublicKey().Address() // create valid tx - addValidatorTx, err := vm.txBuilder.NewAddValidatorTx( + addValidatorTx, err := txBuilder.NewAddValidatorTx( vm.MinValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), @@ -98,7 +99,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { firstDelegatorEndTime := firstDelegatorStartTime.Add(vm.MinStakeDuration) // create valid tx - addFirstDelegatorTx, err := vm.txBuilder.NewAddDelegatorTx( + addFirstDelegatorTx, err := txBuilder.NewAddDelegatorTx( 4*vm.MinValidatorStake, // maximum amount of stake this delegator can provide uint64(firstDelegatorStartTime.Unix()), uint64(firstDelegatorEndTime.Unix()), @@ -135,7 +136,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { vm.clock.Set(secondDelegatorStartTime.Add(-10 * executor.SyncBound)) // create valid tx - addSecondDelegatorTx, err := vm.txBuilder.NewAddDelegatorTx( + addSecondDelegatorTx, err := txBuilder.NewAddDelegatorTx( vm.MinDelegatorStake, uint64(secondDelegatorStartTime.Unix()), uint64(secondDelegatorEndTime.Unix()), @@ -162,7 +163,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { thirdDelegatorEndTime := thirdDelegatorStartTime.Add(vm.MinStakeDuration) // create valid tx - addThirdDelegatorTx, err := vm.txBuilder.NewAddDelegatorTx( + addThirdDelegatorTx, err := txBuilder.NewAddDelegatorTx( vm.MinDelegatorStake, uint64(thirdDelegatorStartTime.Unix()), uint64(thirdDelegatorEndTime.Unix()), @@ -220,7 +221,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, apricotPhase3) + vm, txBuilder, _, _ := defaultVM(t, apricotPhase3) vm.ApricotPhase3Time = test.ap3Time vm.ctx.Lock.Lock() @@ -234,7 +235,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { changeAddr := keys[0].PublicKey().Address() // create valid tx - addValidatorTx, err := vm.txBuilder.NewAddValidatorTx( + addValidatorTx, err := txBuilder.NewAddValidatorTx( validatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), @@ -260,7 +261,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) // create valid tx - addFirstDelegatorTx, err := vm.txBuilder.NewAddDelegatorTx( + addFirstDelegatorTx, err := txBuilder.NewAddDelegatorTx( delegator1Stake, uint64(delegator1StartTime.Unix()), uint64(delegator1EndTime.Unix()), @@ -285,7 +286,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) // create valid tx - addSecondDelegatorTx, err := vm.txBuilder.NewAddDelegatorTx( + addSecondDelegatorTx, err := txBuilder.NewAddDelegatorTx( delegator2Stake, uint64(delegator2StartTime.Unix()), uint64(delegator2EndTime.Unix()), @@ -310,7 +311,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) // create valid tx - addThirdDelegatorTx, err := vm.txBuilder.NewAddDelegatorTx( + addThirdDelegatorTx, err := txBuilder.NewAddDelegatorTx( delegator3Stake, uint64(delegator3StartTime.Unix()), uint64(delegator3EndTime.Unix()), @@ -335,7 +336,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) // create valid tx - addFourthDelegatorTx, err := vm.txBuilder.NewAddDelegatorTx( + addFourthDelegatorTx, err := txBuilder.NewAddDelegatorTx( delegator4Stake, uint64(delegator4StartTime.Unix()), uint64(delegator4EndTime.Unix()), @@ -417,7 +418,14 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { addr0 := key0.PublicKey().Address() addr1 := key1.PublicKey().Address() - addSubnetTx0, err := vm.txBuilder.NewCreateSubnetTx( + txBuilder := txbuilder.New( + vm.ctx, + &vm.Config, + vm.state, + avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), + ) + + addSubnetTx0, err := txBuilder.NewCreateSubnetTx( 1, []ids.ShortID{addr0}, []*secp256k1.PrivateKey{key0}, @@ -426,7 +434,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { ) require.NoError(err) - addSubnetTx1, err := vm.txBuilder.NewCreateSubnetTx( + addSubnetTx1, err := txBuilder.NewCreateSubnetTx( 1, []ids.ShortID{addr1}, []*secp256k1.PrivateKey{key1}, @@ -435,7 +443,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { ) require.NoError(err) - addSubnetTx2, err := vm.txBuilder.NewCreateSubnetTx( + addSubnetTx2, err := txBuilder.NewCreateSubnetTx( 1, []ids.ShortID{addr1}, []*secp256k1.PrivateKey{key1}, @@ -496,7 +504,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { require := require.New(t) - vm, baseDB, mutableSharedMemory := defaultVM(t, cortina) + vm, txBuilder, baseDB, mutableSharedMemory := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -505,7 +513,7 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { newValidatorEndTime := newValidatorStartTime.Add(defaultMinStakingDuration) // Create the tx to add a new validator - addValidatorTx, err := vm.txBuilder.NewAddValidatorTx( + addValidatorTx, err := txBuilder.NewAddValidatorTx( vm.MinValidatorStake, uint64(newValidatorStartTime.Unix()), uint64(newValidatorEndTime.Unix()), @@ -702,7 +710,7 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { require := require.New(t) - vm, baseDB, mutableSharedMemory := defaultVM(t, cortina) + vm, txBuilder, baseDB, mutableSharedMemory := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -714,7 +722,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { nodeID0 := ids.GenerateTestNodeID() // Create the tx to add the first new validator - addValidatorTx0, err := vm.txBuilder.NewAddValidatorTx( + addValidatorTx0, err := txBuilder.NewAddValidatorTx( vm.MaxValidatorStake, uint64(newValidatorStartTime0.Unix()), uint64(newValidatorEndTime0.Unix()), @@ -887,7 +895,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { nodeID1 := ids.GenerateTestNodeID() // Create the tx to add the second new validator - addValidatorTx1, err := vm.txBuilder.NewAddValidatorTx( + addValidatorTx1, err := txBuilder.NewAddValidatorTx( vm.MaxValidatorStake, uint64(newValidatorStartTime1.Unix()), uint64(newValidatorEndTime1.Unix()), @@ -1016,7 +1024,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, cortina) + vm, txBuilder, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -1043,7 +1051,7 @@ func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { extraNodeID := ids.GenerateTestNodeID() // Create the tx to add the first new validator - addValidatorTx0, err := vm.txBuilder.NewAddValidatorTx( + addValidatorTx0, err := txBuilder.NewAddValidatorTx( vm.MaxValidatorStake, uint64(newValidatorStartTime0.Unix()), uint64(newValidatorEndTime0.Unix()), @@ -1153,7 +1161,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { delegator2EndTime := delegator2StartTime.Add(3 * defaultMinStakingDuration) delegator2Stake := defaultMaxValidatorStake - validatorStake - vm, _, _ := defaultVM(t, cortina) + vm, txBuilder, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -1165,7 +1173,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { changeAddr := keys[0].PublicKey().Address() // create valid tx - addValidatorTx, err := vm.txBuilder.NewAddValidatorTx( + addValidatorTx, err := txBuilder.NewAddValidatorTx( validatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), @@ -1191,7 +1199,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) // create valid tx - addFirstDelegatorTx, err := vm.txBuilder.NewAddDelegatorTx( + addFirstDelegatorTx, err := txBuilder.NewAddDelegatorTx( delegator1Stake, uint64(delegator1StartTime.Unix()), uint64(delegator1EndTime.Unix()), @@ -1216,7 +1224,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) // create valid tx - addSecondDelegatorTx, err := vm.txBuilder.NewAddDelegatorTx( + addSecondDelegatorTx, err := txBuilder.NewAddDelegatorTx( delegator2Stake, uint64(delegator2StartTime.Unix()), uint64(delegator2EndTime.Unix()), @@ -1242,7 +1250,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t validatorStartTime := latestForkTime.Add(executor.SyncBound).Add(1 * time.Second) validatorEndTime := validatorStartTime.Add(360 * 24 * time.Hour) - vm, _, _ := defaultVM(t, cortina) + vm, txBuilder, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -1253,7 +1261,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t nodeID := ids.GenerateTestNodeID() changeAddr := keys[0].PublicKey().Address() - addValidatorTx, err := vm.txBuilder.NewAddValidatorTx( + addValidatorTx, err := txBuilder.NewAddValidatorTx( defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), @@ -1277,7 +1285,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t require.NoError(addValidatorBlock.Accept(context.Background())) require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) - createSubnetTx, err := vm.txBuilder.NewCreateSubnetTx( + createSubnetTx, err := txBuilder.NewCreateSubnetTx( 1, []ids.ShortID{changeAddr}, []*secp256k1.PrivateKey{keys[0], keys[1]}, @@ -1297,7 +1305,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t require.NoError(createSubnetBlock.Accept(context.Background())) require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) - addSubnetValidatorTx, err := vm.txBuilder.NewAddSubnetValidatorTx( + addSubnetValidatorTx, err := txBuilder.NewAddSubnetValidatorTx( defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), @@ -1328,7 +1336,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t require.NoError(err) require.Empty(emptyValidatorSet) - removeSubnetValidatorTx, err := vm.txBuilder.NewRemoveSubnetValidatorTx( + removeSubnetValidatorTx, err := txBuilder.NewRemoveSubnetValidatorTx( nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, @@ -1367,7 +1375,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t validatorStartTime := latestForkTime.Add(executor.SyncBound).Add(1 * time.Second) validatorEndTime := validatorStartTime.Add(360 * 24 * time.Hour) - vm, _, _ := defaultVM(t, cortina) + vm, txBuilder, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -1378,7 +1386,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t nodeID := ids.GenerateTestNodeID() changeAddr := keys[0].PublicKey().Address() - addValidatorTx, err := vm.txBuilder.NewAddValidatorTx( + addValidatorTx, err := txBuilder.NewAddValidatorTx( defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), @@ -1402,7 +1410,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t require.NoError(addValidatorBlock.Accept(context.Background())) require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) - createSubnetTx, err := vm.txBuilder.NewCreateSubnetTx( + createSubnetTx, err := txBuilder.NewCreateSubnetTx( 1, []ids.ShortID{changeAddr}, []*secp256k1.PrivateKey{keys[0], keys[1]}, @@ -1422,7 +1430,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t require.NoError(createSubnetBlock.Accept(context.Background())) require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) - addSubnetValidatorTx, err := vm.txBuilder.NewAddSubnetValidatorTx( + addSubnetValidatorTx, err := txBuilder.NewAddSubnetValidatorTx( defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), @@ -1445,7 +1453,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t require.NoError(addSubnetValidatorBlock.Accept(context.Background())) require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) - removeSubnetValidatorTx, err := vm.txBuilder.NewRemoveSubnetValidatorTx( + removeSubnetValidatorTx, err := txBuilder.NewRemoveSubnetValidatorTx( nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, @@ -1475,7 +1483,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { // setup require := require.New(t) - vm, _, _ := defaultVM(t, cortina) + vm, txBuilder, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -1505,7 +1513,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) // build primary network validator with BLS key - primaryTx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( + primaryTx, err := txBuilder.NewAddPermissionlessValidatorTx( vm.MinValidatorStake, uint64(primaryStartTime.Unix()), uint64(primaryEndTime.Unix()), @@ -1538,7 +1546,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) // insert the subnet validator - subnetTx, err := vm.txBuilder.NewAddSubnetValidatorTx( + subnetTx, err := txBuilder.NewAddSubnetValidatorTx( 1, // Weight uint64(subnetStartTime.Unix()), // Start time uint64(subnetEndTime.Unix()), // end time @@ -1611,7 +1619,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) require.NotEqual(sk1, sk2) - primaryRestartTx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( + primaryRestartTx, err := txBuilder.NewAddPermissionlessValidatorTx( vm.MinValidatorStake, uint64(primaryReStartTime.Unix()), uint64(primaryReEndTime.Unix()), @@ -1700,7 +1708,7 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { // setup require := require.New(t) - vm, _, _ := defaultVM(t, cortina) + vm, txBuilder, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -1720,7 +1728,7 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { // Add a primary network validator with no BLS key nodeID := ids.GenerateTestNodeID() addr := keys[0].PublicKey().Address() - primaryTx1, err := vm.txBuilder.NewAddValidatorTx( + primaryTx1, err := txBuilder.NewAddValidatorTx( vm.MinValidatorStake, uint64(primaryStartTime1.Unix()), uint64(primaryEndTime1.Unix()), @@ -1781,7 +1789,7 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { sk2, err := bls.NewSecretKey() require.NoError(err) - primaryRestartTx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( + primaryRestartTx, err := txBuilder.NewAddPermissionlessValidatorTx( vm.MinValidatorStake, uint64(primaryStartTime2.Unix()), uint64(primaryEndTime2.Unix()), @@ -1829,7 +1837,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { // setup require := require.New(t) - vm, _, _ := defaultVM(t, cortina) + vm, txBuilder, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -1853,7 +1861,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { // Add a primary network validator with no BLS key nodeID := ids.GenerateTestNodeID() addr := keys[0].PublicKey().Address() - primaryTx1, err := vm.txBuilder.NewAddValidatorTx( + primaryTx1, err := txBuilder.NewAddValidatorTx( vm.MinValidatorStake, uint64(primaryStartTime1.Unix()), uint64(primaryEndTime1.Unix()), @@ -1884,7 +1892,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { require.NoError(err) // insert the subnet validator - subnetTx, err := vm.txBuilder.NewAddSubnetValidatorTx( + subnetTx, err := txBuilder.NewAddSubnetValidatorTx( 1, // Weight uint64(subnetStartTime.Unix()), // Start time uint64(subnetEndTime.Unix()), // end time @@ -1956,7 +1964,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { sk2, err := bls.NewSecretKey() require.NoError(err) - primaryRestartTx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( + primaryRestartTx, err := txBuilder.NewAddPermissionlessValidatorTx( vm.MinValidatorStake, uint64(primaryStartTime2.Unix()), uint64(primaryEndTime2.Unix()), @@ -2013,7 +2021,7 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { // setup require := require.New(t) - vm, _, _ := defaultVM(t, cortina) + vm, txBuilder, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -2035,7 +2043,7 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { // Add a primary network validator with no BLS key nodeID := ids.GenerateTestNodeID() addr := keys[0].PublicKey().Address() - primaryTx1, err := vm.txBuilder.NewAddValidatorTx( + primaryTx1, err := txBuilder.NewAddValidatorTx( vm.MinValidatorStake, uint64(primaryStartTime1.Unix()), uint64(primaryEndTime1.Unix()), @@ -2063,7 +2071,7 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { require.NoError(err) // insert the subnet validator - subnetTx, err := vm.txBuilder.NewAddSubnetValidatorTx( + subnetTx, err := txBuilder.NewAddSubnetValidatorTx( 1, // Weight uint64(subnetStartTime.Unix()), // Start time uint64(subnetEndTime.Unix()), // end time @@ -2133,7 +2141,7 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { func TestValidatorSetRaceCondition(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, cortina) + vm, _, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 832c4ba5a5c..b55c543bb18 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -66,6 +66,7 @@ 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" walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) @@ -201,7 +202,7 @@ func defaultGenesis(t *testing.T, avaxAssetID ids.ID) (*api.BuildGenesisArgs, [] return &buildGenesisArgs, genesisBytes } -func defaultVM(t *testing.T, f fork) (*VM, database.Database, *mutableSharedMemory) { +func defaultVM(t *testing.T, f fork) (*VM, txbuilder.Builder, database.Database, *mutableSharedMemory) { require := require.New(t) var ( apricotPhase3Time = mockable.MaxTime @@ -301,11 +302,18 @@ func defaultVM(t *testing.T, f fork) (*VM, database.Database, *mutableSharedMemo require.NoError(vm.SetState(context.Background(), snow.NormalOp)) + builder := txbuilder.New( + ctx, + &vm.Config, + vm.state, + avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), + ) + // Create a subnet and store it in testSubnet1 // Note: following Banff activation, block acceptance will move // chain time ahead var err error - testSubnet1, err = vm.txBuilder.NewCreateSubnetTx( + testSubnet1, err = builder.NewCreateSubnetTx( 2, // threshold; 2 sigs from keys[0], keys[1], keys[2] needed to add validator to this subnet // control keys are keys[0], keys[1], keys[2] []ids.ShortID{keys[0].PublicKey().Address(), keys[1].PublicKey().Address(), keys[2].PublicKey().Address()}, @@ -330,13 +338,13 @@ func defaultVM(t *testing.T, f fork) (*VM, database.Database, *mutableSharedMemo require.NoError(vm.Shutdown(context.Background())) }) - return vm, db, msm + return vm, builder, db, msm } // 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, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -389,7 +397,7 @@ func TestGenesis(t *testing.T) { // accept proposal to add validator to primary network func TestAddValidatorCommit(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, txBuilder, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -404,7 +412,7 @@ func TestAddValidatorCommit(t *testing.T) { require.NoError(err) // create valid tx - tx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( + tx, err := txBuilder.NewAddPermissionlessValidatorTx( vm.MinValidatorStake, uint64(startTime.Unix()), uint64(endTime.Unix()), @@ -441,7 +449,7 @@ func TestAddValidatorCommit(t *testing.T) { // verify invalid attempt to add validator to primary network func TestInvalidAddValidatorCommit(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, cortina) + vm, txBuilder, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -450,7 +458,7 @@ func TestInvalidAddValidatorCommit(t *testing.T) { endTime := startTime.Add(defaultMinStakingDuration) // create invalid tx - tx, err := vm.txBuilder.NewAddValidatorTx( + tx, err := txBuilder.NewAddValidatorTx( vm.MinValidatorStake, uint64(startTime.Unix()), uint64(endTime.Unix()), @@ -492,7 +500,7 @@ func TestInvalidAddValidatorCommit(t *testing.T) { // Reject attempt to add validator to primary network func TestAddValidatorReject(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, cortina) + vm, txBuilder, _, _ := defaultVM(t, cortina) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -504,7 +512,7 @@ func TestAddValidatorReject(t *testing.T) { ) // create valid tx - tx, err := vm.txBuilder.NewAddValidatorTx( + tx, err := txBuilder.NewAddValidatorTx( vm.MinValidatorStake, uint64(startTime.Unix()), uint64(endTime.Unix()), @@ -538,7 +546,7 @@ func TestAddValidatorReject(t *testing.T) { // Reject proposal to add validator to primary network func TestAddValidatorInvalidNotReissued(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, txBuilder, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -552,7 +560,7 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { require.NoError(err) // create valid tx - tx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( + tx, err := txBuilder.NewAddPermissionlessValidatorTx( vm.MinValidatorStake, uint64(startTime.Unix()), uint64(endTime.Unix()), @@ -576,7 +584,7 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { // Accept proposal to add validator to subnet func TestAddSubnetValidatorAccept(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, txBuilder, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -589,7 +597,7 @@ 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]) - tx, err := vm.txBuilder.NewAddSubnetValidatorTx( + tx, err := txBuilder.NewAddSubnetValidatorTx( defaultWeight, uint64(startTime.Unix()), uint64(endTime.Unix()), @@ -624,7 +632,7 @@ func TestAddSubnetValidatorAccept(t *testing.T) { // Reject proposal to add validator to subnet func TestAddSubnetValidatorReject(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, txBuilder, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -637,7 +645,7 @@ 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]) - tx, err := vm.txBuilder.NewAddSubnetValidatorTx( + tx, err := txBuilder.NewAddSubnetValidatorTx( defaultWeight, uint64(startTime.Unix()), uint64(endTime.Unix()), @@ -671,7 +679,7 @@ func TestAddSubnetValidatorReject(t *testing.T) { // Test case where primary network validator rewarded func TestRewardValidatorAccept(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, _, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -739,7 +747,7 @@ func TestRewardValidatorAccept(t *testing.T) { // Test case where primary network validator not rewarded func TestRewardValidatorReject(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, _, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -809,7 +817,7 @@ func TestRewardValidatorReject(t *testing.T) { // Ensure BuildBlock errors when there is no block to build func TestUnneededBuildBlock(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, _, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -820,11 +828,11 @@ func TestUnneededBuildBlock(t *testing.T) { // test acceptance of proposal to create a new chain func TestCreateChain(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, txBuilder, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() - tx, err := vm.txBuilder.NewCreateChainTx( + tx, err := txBuilder.NewCreateChainTx( testSubnet1.ID(), nil, ids.ID{'t', 'e', 's', 't', 'v', 'm'}, @@ -870,12 +878,12 @@ func TestCreateChain(t *testing.T) { // 3) Advance timestamp to validator's end time (removing validator from current) func TestCreateSubnet(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, txBuilder, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() nodeID := genesisNodeIDs[0] - createSubnetTx, err := vm.txBuilder.NewCreateSubnetTx( + createSubnetTx, err := txBuilder.NewCreateSubnetTx( 1, // threshold []ids.ShortID{ // control keys keys[0].PublicKey().Address(), @@ -919,7 +927,7 @@ func TestCreateSubnet(t *testing.T) { startTime := vm.clock.Time().Add(txexecutor.SyncBound).Add(1 * time.Second) endTime := startTime.Add(defaultMinStakingDuration) // [startTime, endTime] is subset of time keys[0] validates default subnet so tx is valid - addValidatorTx, err := vm.txBuilder.NewAddSubnetValidatorTx( + addValidatorTx, err := txBuilder.NewAddSubnetValidatorTx( defaultWeight, uint64(startTime.Unix()), uint64(endTime.Unix()), @@ -970,7 +978,7 @@ func TestCreateSubnet(t *testing.T) { // test asset import func TestAtomicImport(t *testing.T) { require := require.New(t) - vm, baseDB, mutableSharedMemory := defaultVM(t, latestFork) + vm, txBuilder, baseDB, mutableSharedMemory := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -986,7 +994,7 @@ func TestAtomicImport(t *testing.T) { mutableSharedMemory.SharedMemory = m.NewSharedMemory(vm.ctx.ChainID) peerSharedMemory := m.NewSharedMemory(vm.ctx.XChainID) - _, err := vm.txBuilder.NewImportTx( + _, err := txBuilder.NewImportTx( vm.ctx.XChainID, recipientKey.PublicKey().Address(), []*secp256k1.PrivateKey{keys[0]}, @@ -1026,7 +1034,7 @@ func TestAtomicImport(t *testing.T) { }, })) - tx, err := vm.txBuilder.NewImportTx( + tx, err := txBuilder.NewImportTx( vm.ctx.XChainID, recipientKey.PublicKey().Address(), []*secp256k1.PrivateKey{recipientKey}, @@ -1058,7 +1066,7 @@ func TestAtomicImport(t *testing.T) { // test optimistic asset import func TestOptimisticAtomicImport(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, apricotPhase3) + vm, _, _, _ := defaultVM(t, apricotPhase3) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -1702,7 +1710,7 @@ func TestUnverifiedParent(t *testing.T) { } func TestMaxStakeAmount(t *testing.T) { - vm, _, _ := defaultVM(t, latestFork) + vm, _, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -2009,7 +2017,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { validatorStartTime := latestForkTime.Add(txexecutor.SyncBound).Add(1 * time.Second) validatorEndTime := validatorStartTime.Add(360 * 24 * time.Hour) - vm, _, _ := defaultVM(t, latestFork) + vm, txBuilder, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -2021,7 +2029,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { sk, err := bls.NewSecretKey() require.NoError(err) - addValidatorTx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( + addValidatorTx, err := txBuilder.NewAddPermissionlessValidatorTx( defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), @@ -2046,7 +2054,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { require.NoError(addValidatorBlock.Accept(context.Background())) require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) - createSubnetTx, err := vm.txBuilder.NewCreateSubnetTx( + createSubnetTx, err := txBuilder.NewCreateSubnetTx( 1, []ids.ShortID{id}, []*secp256k1.PrivateKey{keys[0]}, @@ -2066,7 +2074,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { require.NoError(createSubnetBlock.Accept(context.Background())) require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) - addSubnetValidatorTx, err := vm.txBuilder.NewAddSubnetValidatorTx( + addSubnetValidatorTx, err := txBuilder.NewAddSubnetValidatorTx( defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), @@ -2078,7 +2086,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { ) require.NoError(err) - removeSubnetValidatorTx, err := vm.txBuilder.NewRemoveSubnetValidatorTx( + removeSubnetValidatorTx, err := txBuilder.NewRemoveSubnetValidatorTx( nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{key, keys[2]}, @@ -2111,12 +2119,12 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { func TestTransferSubnetOwnershipTx(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, txBuilder, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() // Create a subnet - createSubnetTx, err := vm.txBuilder.NewCreateSubnetTx( + createSubnetTx, err := txBuilder.NewCreateSubnetTx( 1, []ids.ShortID{keys[0].PublicKey().Address()}, []*secp256k1.PrivateKey{keys[0]}, @@ -2154,7 +2162,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { expectedOwner.InitCtx(ctx) require.Equal(expectedOwner, subnetOwner) - transferSubnetOwnershipTx, err := vm.txBuilder.NewTransferSubnetOwnershipTx( + transferSubnetOwnershipTx, err := txBuilder.NewTransferSubnetOwnershipTx( subnetID, 1, []ids.ShortID{keys[1].PublicKey().Address()}, @@ -2193,14 +2201,14 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { func TestBaseTx(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, txBuilder, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() sendAmt := uint64(100000) changeAddr := ids.ShortEmpty - baseTx, err := vm.txBuilder.NewBaseTx( + baseTx, err := txBuilder.NewBaseTx( sendAmt, secp256k1fx.OutputOwners{ Threshold: 1, @@ -2268,7 +2276,7 @@ func TestBaseTx(t *testing.T) { func TestPruneMempool(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t, latestFork) + vm, txBuilder, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() @@ -2276,7 +2284,7 @@ func TestPruneMempool(t *testing.T) { sendAmt := uint64(100000) changeAddr := ids.ShortEmpty - baseTx, err := vm.txBuilder.NewBaseTx( + baseTx, err := txBuilder.NewBaseTx( sendAmt, secp256k1fx.OutputOwners{ Threshold: 1, @@ -2308,7 +2316,7 @@ func TestPruneMempool(t *testing.T) { sk, err := bls.NewSecretKey() require.NoError(err) - addValidatorTx, err := vm.txBuilder.NewAddPermissionlessValidatorTx( + addValidatorTx, err := txBuilder.NewAddPermissionlessValidatorTx( defaultMinValidatorStake, uint64(startTime.Unix()), uint64(endTime.Unix()), From d695437b7946664ce9cc59a366e82ad45eb4c768 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:08:56 -0400 Subject: [PATCH 36/51] nits (#2874) --- vms/platformvm/block/builder/builder_test.go | 95 ++- vms/platformvm/block/builder/helpers_test.go | 21 +- .../block/builder/standard_block_test.go | 8 +- vms/platformvm/block/executor/helpers_test.go | 38 +- .../block/executor/proposal_block_test.go | 284 ++++--- .../block/executor/standard_block_test.go | 81 +- vms/platformvm/service_test.go | 141 ++-- vms/platformvm/txs/builder/builder.go | 610 +++------------ .../txs/executor/advance_time_test.go | 118 +-- .../txs/executor/create_chain_test.go | 8 - vms/platformvm/txs/executor/export_test.go | 17 +- vms/platformvm/txs/executor/helpers_test.go | 23 +- vms/platformvm/txs/executor/import_test.go | 8 +- .../txs/executor/proposal_tx_executor_test.go | 334 ++++---- .../txs/executor/reward_validator_test.go | 136 ++-- .../txs/executor/standard_tx_executor_test.go | 557 ++++++++------ vms/platformvm/validator_set_property_test.go | 63 +- vms/platformvm/vm_regression_test.go | 714 ++++++++++++------ vms/platformvm/vm_test.go | 344 ++++++--- 19 files changed, 1977 insertions(+), 1623 deletions(-) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index d457f150e94..64abd8a4685 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -24,6 +24,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/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" @@ -44,8 +46,6 @@ func TestBuildBlockBasic(t *testing.T) { nil, "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) txID := tx.ID() @@ -110,16 +110,31 @@ func TestBuildBlockShouldReward(t *testing.T) { // Create a valid [AddPermissionlessValidatorTx] tx, err := env.txBuilder.NewAddPermissionlessValidatorTx( - defaultValidatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: defaultValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - preFundedKeys[0].PublicKey().Address(), + env.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, - preFundedKeys[0].PublicKey().Address(), - nil, + common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }), ) require.NoError(err) txID := tx.ID() @@ -239,8 +254,6 @@ func TestBuildBlockForceAdvanceTime(t *testing.T) { nil, "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) txID := tx.ID() @@ -302,16 +315,31 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { require.NoError(err) tx1, err := env.txBuilder.NewAddPermissionlessValidatorTx( - defaultValidatorStake, - uint64(now.Unix()), - uint64(validatorEndTime.Unix()), - ids.GenerateTestNodeID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(now.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: defaultValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - preFundedKeys[0].PublicKey().Address(), + env.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, - preFundedKeys[0].PublicKey().Address(), - nil, + common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }), ) require.NoError(err) require.NoError(env.mempool.Add(tx1)) @@ -326,16 +354,31 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { require.NoError(err) tx2, err := env.txBuilder.NewAddPermissionlessValidatorTx( - defaultValidatorStake, - uint64(now.Unix()), - uint64(validator2EndTime.Unix()), - ids.GenerateTestNodeID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(now.Unix()), + End: uint64(validator2EndTime.Unix()), + Wght: defaultValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - preFundedKeys[2].PublicKey().Address(), + env.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[2].PublicKey().Address()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[2].PublicKey().Address()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[2]}, - preFundedKeys[2].PublicKey().Address(), - nil, + common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[2].PublicKey().Address()}, + }), ) require.NoError(err) require.NoError(env.mempool.Add(tx2)) @@ -380,8 +423,6 @@ func TestPreviouslyDroppedTxsCannotBeReAddedToMempool(t *testing.T) { nil, "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 71089e34996..0e32af73d31 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -52,6 +52,7 @@ import ( txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" pvalidators "github.com/ava-labs/avalanchego/vms/platformvm/validators" + walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) const ( @@ -117,7 +118,7 @@ type environment struct { atomicUTXOs avax.AtomicUTXOManager uptimes uptime.Manager utxosVerifier utxo.Verifier - txBuilder txbuilder.Builder + txBuilder *txbuilder.Builder backend txexecutor.Backend } @@ -244,15 +245,19 @@ func addSubnet(t *testing.T, env *environment) { // Create a subnet var err error testSubnet1, err = env.txBuilder.NewCreateSubnetTx( - 2, // threshold; 2 sigs from keys[0], keys[1], keys[2] needed to add validator to this subnet - []ids.ShortID{ // control keys - preFundedKeys[0].PublicKey().Address(), - preFundedKeys[1].PublicKey().Address(), - preFundedKeys[2].PublicKey().Address(), + &secp256k1fx.OutputOwners{ + Threshold: 2, + Addrs: []ids.ShortID{ + preFundedKeys[0].PublicKey().Address(), + preFundedKeys[1].PublicKey().Address(), + preFundedKeys[2].PublicKey().Address(), + }, }, []*secp256k1.PrivateKey{preFundedKeys[0]}, - preFundedKeys[0].PublicKey().Address(), - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }), ) require.NoError(err) diff --git a/vms/platformvm/block/builder/standard_block_test.go b/vms/platformvm/block/builder/standard_block_test.go index fa1a07fb3f0..55c76bd7c58 100644 --- a/vms/platformvm/block/builder/standard_block_test.go +++ b/vms/platformvm/block/builder/standard_block_test.go @@ -64,10 +64,12 @@ func TestAtomicTxImports(t *testing.T) { tx, err := env.txBuilder.NewImportTx( env.ctx.XChainID, - recipientKey.PublicKey().Address(), + &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{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 3ad76b2f082..167611e3c57 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -51,6 +51,7 @@ import ( p_tx_builder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" pvalidators "github.com/ava-labs/avalanchego/vms/platformvm/validators" + walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) const ( @@ -129,7 +130,7 @@ type environment struct { atomicUTXOs avax.AtomicUTXOManager uptimes uptime.Manager utxosVerifier utxo.Verifier - txBuilder p_tx_builder.Builder + txBuilder *p_tx_builder.Builder backend *executor.Backend } @@ -256,15 +257,19 @@ func addSubnet(env *environment) { // Create a subnet var err error testSubnet1, err = env.txBuilder.NewCreateSubnetTx( - 2, // threshold; 2 sigs from keys[0], keys[1], keys[2] needed to add validator to this subnet - []ids.ShortID{ // control keys - preFundedKeys[0].PublicKey().Address(), - preFundedKeys[1].PublicKey().Address(), - preFundedKeys[2].PublicKey().Address(), + &secp256k1fx.OutputOwners{ + Threshold: 2, + Addrs: []ids.ShortID{ + preFundedKeys[0].PublicKey().Address(), + preFundedKeys[1].PublicKey().Address(), + preFundedKeys[2].PublicKey().Address(), + }, }, []*secp256k1.PrivateKey{preFundedKeys[0]}, - preFundedKeys[0].PublicKey().Address(), - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }), ) if err != nil { panic(err) @@ -490,15 +495,18 @@ func addPendingValidator( keys []*secp256k1.PrivateKey, ) (*txs.Tx, error) { addPendingValidatorTx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, - uint64(startTime.Unix()), - uint64(endTime.Unix()), - nodeID, - rewardAddress, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, + }, 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 7d987f95219..11fb2f571ec 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -535,15 +535,18 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { for _, staker := range test.stakers { tx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, - uint64(staker.startTime.Unix()), - uint64(staker.endTime.Unix()), - staker.nodeID, - staker.rewardAddress, + &txs.Validator{ + NodeID: staker.nodeID, + Start: uint64(staker.startTime.Unix()), + End: uint64(staker.endTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{staker.rewardAddress}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -560,14 +563,16 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { for _, subStaker := range test.subnetStakers { tx, err := env.txBuilder.NewAddSubnetValidatorTx( - 10, // Weight - uint64(subStaker.startTime.Unix()), - uint64(subStaker.endTime.Unix()), - subStaker.nodeID, // validator ID - subnetID, // Subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: subStaker.nodeID, + Start: uint64(subStaker.startTime.Unix()), + End: uint64(subStaker.endTime.Unix()), + Wght: 10, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -589,15 +594,18 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { // so to allow proposalBlk issuance staker0.endTime = newTime addStaker0, err := env.txBuilder.NewAddValidatorTx( - 10, - uint64(staker0.startTime.Unix()), - uint64(staker0.endTime.Unix()), - staker0.nodeID, - staker0.rewardAddress, + &txs.Validator{ + NodeID: staker0.nodeID, + Start: uint64(staker0.startTime.Unix()), + End: uint64(staker0.endTime.Unix()), + Wght: 10, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{staker0.rewardAddress}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -690,14 +698,16 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { subnetVdr1StartTime := defaultValidateStartTime subnetVdr1EndTime := defaultValidateStartTime.Add(defaultMinStakingDuration) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetVdr1StartTime.Unix()), // Start time - uint64(subnetVdr1EndTime.Unix()), // end time - subnetValidatorNodeID, // Node ID - subnetID, // Subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: subnetValidatorNodeID, + Start: uint64(subnetVdr1StartTime.Unix()), + End: uint64(subnetVdr1EndTime.Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -719,14 +729,16 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { // Queue a staker that joins the staker set after the above validator leaves subnetVdr2NodeID := genesisNodeIDs[1] tx, err = env.txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetVdr1EndTime.Add(time.Second).Unix()), // Start time - uint64(subnetVdr1EndTime.Add(time.Second).Add(defaultMinStakingDuration).Unix()), // end time - subnetVdr2NodeID, // Node ID - subnetID, // Subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: subnetVdr2NodeID, + Start: uint64(subnetVdr1EndTime.Add(time.Second).Unix()), + End: uint64(subnetVdr1EndTime.Add(time.Second).Add(defaultMinStakingDuration).Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -750,15 +762,18 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { staker0StartTime := defaultValidateStartTime staker0EndTime := subnetVdr1EndTime addStaker0, err := env.txBuilder.NewAddValidatorTx( - 10, - uint64(staker0StartTime.Unix()), - uint64(staker0EndTime.Unix()), - ids.GenerateTestNodeID(), - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(staker0StartTime.Unix()), + End: uint64(staker0EndTime.Unix()), + Wght: 10, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -834,14 +849,16 @@ func TestBanffProposalBlockTrackedSubnet(t *testing.T) { subnetVdr1StartTime := defaultGenesisTime.Add(1 * time.Minute) subnetVdr1EndTime := defaultGenesisTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetVdr1StartTime.Unix()), // Start time - uint64(subnetVdr1EndTime.Unix()), // end time - subnetValidatorNodeID, // Node ID - subnetID, // Subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: subnetValidatorNodeID, + Start: uint64(subnetVdr1StartTime.Unix()), + End: uint64(subnetVdr1EndTime.Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -863,15 +880,18 @@ func TestBanffProposalBlockTrackedSubnet(t *testing.T) { staker0StartTime := defaultGenesisTime staker0EndTime := subnetVdr1StartTime addStaker0, err := env.txBuilder.NewAddValidatorTx( - 10, - uint64(staker0StartTime.Unix()), - uint64(staker0EndTime.Unix()), - ids.GenerateTestNodeID(), - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(staker0StartTime.Unix()), + End: uint64(staker0EndTime.Unix()), + Wght: 10, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -949,15 +969,18 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { staker0StartTime := defaultGenesisTime staker0EndTime := pendingValidatorStartTime addStaker0, err := env.txBuilder.NewAddValidatorTx( - 10, - uint64(staker0StartTime.Unix()), - uint64(staker0EndTime.Unix()), - ids.GenerateTestNodeID(), - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(staker0StartTime.Unix()), + End: uint64(staker0EndTime.Unix()), + Wght: 10, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -1015,18 +1038,21 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { pendingDelegatorEndTime := pendingDelegatorStartTime.Add(1 * time.Second) addDelegatorTx, err := env.txBuilder.NewAddDelegatorTx( - env.config.MinDelegatorStake, - uint64(pendingDelegatorStartTime.Unix()), - uint64(pendingDelegatorEndTime.Unix()), - nodeID, - preFundedKeys[0].PublicKey().Address(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(pendingDelegatorStartTime.Unix()), + End: uint64(pendingDelegatorEndTime.Unix()), + Wght: env.config.MinDelegatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{ preFundedKeys[0], preFundedKeys[1], preFundedKeys[4], }, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -1045,15 +1071,18 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { // so to allow proposalBlk issuance staker0EndTime = pendingDelegatorStartTime addStaker0, err = env.txBuilder.NewAddValidatorTx( - 10, - uint64(staker0StartTime.Unix()), - uint64(staker0EndTime.Unix()), - ids.GenerateTestNodeID(), - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(staker0StartTime.Unix()), + End: uint64(staker0EndTime.Unix()), + Wght: 10, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -1135,15 +1164,18 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { staker0StartTime := defaultGenesisTime staker0EndTime := pendingValidatorStartTime addStaker0, err := env.txBuilder.NewAddValidatorTx( - 10, - uint64(staker0StartTime.Unix()), - uint64(staker0EndTime.Unix()), - ids.GenerateTestNodeID(), - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(staker0StartTime.Unix()), + End: uint64(staker0EndTime.Unix()), + Wght: 10, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -1200,18 +1232,21 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { pendingDelegatorStartTime := pendingValidatorStartTime.Add(1 * time.Second) pendingDelegatorEndTime := pendingDelegatorStartTime.Add(defaultMinStakingDuration) addDelegatorTx, err := env.txBuilder.NewAddDelegatorTx( - env.config.MinDelegatorStake, - uint64(pendingDelegatorStartTime.Unix()), - uint64(pendingDelegatorEndTime.Unix()), - nodeID, - preFundedKeys[0].PublicKey().Address(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(pendingDelegatorStartTime.Unix()), + End: uint64(pendingDelegatorEndTime.Unix()), + Wght: env.config.MinDelegatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{ preFundedKeys[0], preFundedKeys[1], preFundedKeys[4], }, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -1230,15 +1265,18 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { // so to allow proposalBlk issuance staker0EndTime = pendingDelegatorStartTime addStaker0, err = env.txBuilder.NewAddValidatorTx( - 10, - uint64(staker0StartTime.Unix()), - uint64(staker0EndTime.Unix()), - ids.GenerateTestNodeID(), - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(staker0StartTime.Unix()), + End: uint64(staker0EndTime.Unix()), + Wght: 10, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -1309,20 +1347,31 @@ func TestAddValidatorProposalBlock(t *testing.T) { require.NoError(err) addValidatorTx, err := env.txBuilder.NewAddPermissionlessValidatorTx( - env.config.MinValidatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - preFundedKeys[0].PublicKey().Address(), + env.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, 10000, []*secp256k1.PrivateKey{ preFundedKeys[0], preFundedKeys[1], preFundedKeys[4], }, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -1385,20 +1434,31 @@ func TestAddValidatorProposalBlock(t *testing.T) { require.NoError(err) addValidatorTx2, err := env.txBuilder.NewAddPermissionlessValidatorTx( - env.config.MinValidatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - preFundedKeys[0].PublicKey().Address(), + env.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, 10000, []*secp256k1.PrivateKey{ preFundedKeys[0], preFundedKeys[1], 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 b77846351bc..880b706884e 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -509,14 +509,16 @@ func TestBanffStandardBlockUpdateStakers(t *testing.T) { for _, staker := range test.subnetStakers { tx, err := env.txBuilder.NewAddSubnetValidatorTx( - 10, // Weight - uint64(staker.startTime.Unix()), - uint64(staker.endTime.Unix()), - staker.nodeID, // validator ID - subnetID, // Subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: staker.nodeID, + Start: uint64(staker.startTime.Unix()), + End: uint64(staker.endTime.Unix()), + Wght: 10, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -599,14 +601,16 @@ func TestBanffStandardBlockRemoveSubnetValidator(t *testing.T) { subnetVdr1StartTime := defaultValidateStartTime subnetVdr1EndTime := defaultValidateStartTime.Add(defaultMinStakingDuration) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetVdr1StartTime.Unix()), // Start time - uint64(subnetVdr1EndTime.Unix()), // end time - subnetValidatorNodeID, // Node ID - subnetID, // Subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: subnetValidatorNodeID, + Start: uint64(subnetVdr1StartTime.Unix()), + End: uint64(subnetVdr1EndTime.Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -628,14 +632,16 @@ func TestBanffStandardBlockRemoveSubnetValidator(t *testing.T) { // Queue a staker that joins the staker set after the above validator leaves subnetVdr2NodeID := genesisNodeIDs[1] tx, err = env.txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetVdr1EndTime.Add(time.Second).Unix()), // Start time - uint64(subnetVdr1EndTime.Add(time.Second).Add(defaultMinStakingDuration).Unix()), // end time - subnetVdr2NodeID, // Node ID - subnetID, // Subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: subnetVdr2NodeID, + Start: uint64(subnetVdr1EndTime.Add(time.Second).Unix()), + End: uint64(subnetVdr1EndTime.Add(time.Second).Add(defaultMinStakingDuration).Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -698,14 +704,16 @@ func TestBanffStandardBlockTrackedSubnet(t *testing.T) { subnetVdr1StartTime := defaultGenesisTime.Add(1 * time.Minute) subnetVdr1EndTime := defaultGenesisTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetVdr1StartTime.Unix()), // Start time - uint64(subnetVdr1EndTime.Unix()), // end time - subnetValidatorNodeID, // Node ID - subnetID, // Subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: subnetValidatorNodeID, + Start: uint64(subnetVdr1StartTime.Unix()), + End: uint64(subnetVdr1EndTime.Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -789,18 +797,21 @@ func TestBanffStandardBlockDelegatorStakerWeight(t *testing.T) { pendingDelegatorEndTime := pendingDelegatorStartTime.Add(1 * time.Second) addDelegatorTx, err := env.txBuilder.NewAddDelegatorTx( - env.config.MinDelegatorStake, - uint64(pendingDelegatorStartTime.Unix()), - uint64(pendingDelegatorEndTime.Unix()), - nodeID, - preFundedKeys[0].PublicKey().Address(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(pendingDelegatorStartTime.Unix()), + End: uint64(pendingDelegatorEndTime.Unix()), + Wght: env.config.MinDelegatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{ preFundedKeys[0], preFundedKeys[1], preFundedKeys[4], }, - ids.ShortEmpty, - nil, ) require.NoError(err) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index a2199eb7dc0..a14a0d47f70 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -40,6 +40,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/subnet/primary/common" avajson "github.com/ava-labs/avalanchego/utils/json" vmkeystore "github.com/ava-labs/avalanchego/vms/components/keystore" @@ -73,7 +74,7 @@ var ( } ) -func defaultService(t *testing.T) (*Service, *mutableSharedMemory, txbuilder.Builder) { +func defaultService(t *testing.T) (*Service, *mutableSharedMemory, *txbuilder.Builder) { vm, txBuilder, _, mutableSharedMemory := defaultVM(t, latestFork) return &Service{ @@ -168,10 +169,12 @@ func TestGetTxStatus(t *testing.T) { tx, err := txBuilder.NewImportTx( service.vm.ctx.XChainID, - ids.ShortEmpty, + &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, []*secp256k1.PrivateKey{recipientKey}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -209,13 +212,13 @@ func TestGetTxStatus(t *testing.T) { func TestGetTx(t *testing.T) { type test struct { description string - createTx func(service *Service, builder txbuilder.Builder) (*txs.Tx, error) + createTx func(service *Service, builder *txbuilder.Builder) (*txs.Tx, error) } tests := []test{ { "standard block", - func(_ *Service, builder txbuilder.Builder) (*txs.Tx, error) { + func(_ *Service, builder *txbuilder.Builder) (*txs.Tx, error) { return builder.NewCreateChainTx( // Test GetTx works for standard blocks testSubnet1.ID(), []byte{}, @@ -223,41 +226,68 @@ func TestGetTx(t *testing.T) { []ids.ID{}, "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - keys[0].PublicKey().Address(), // change addr - nil, + common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) }, }, { "proposal block", - func(service *Service, builder txbuilder.Builder) (*txs.Tx, error) { + func(service *Service, builder *txbuilder.Builder) (*txs.Tx, error) { sk, err := bls.NewSecretKey() require.NoError(t, err) + rewardsOwner := &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + } + return builder.NewAddPermissionlessValidatorTx( // Test GetTx works for proposal blocks - service.vm.MinValidatorStake, - uint64(service.vm.clock.Time().Add(txexecutor.SyncBound).Unix()), - uint64(service.vm.clock.Time().Add(txexecutor.SyncBound).Add(defaultMinStakingDuration).Unix()), - ids.GenerateTestNodeID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(service.vm.clock.Time().Add(txexecutor.SyncBound).Unix()), + End: uint64(service.vm.clock.Time().Add(txexecutor.SyncBound).Add(defaultMinStakingDuration).Unix()), + Wght: service.vm.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - ids.GenerateTestShortID(), + service.vm.ctx.AVAXAssetID, + rewardsOwner, + rewardsOwner, 0, []*secp256k1.PrivateKey{keys[0]}, - keys[0].PublicKey().Address(), // change addr - nil, + common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) }, }, { "atomic block", - func(service *Service, builder txbuilder.Builder) (*txs.Tx, error) { + func(service *Service, builder *txbuilder.Builder) (*txs.Tx, error) { return builder.NewExportTx( // Test GetTx works for proposal blocks - 100, service.vm.ctx.XChainID, - ids.GenerateTestShortID(), + []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: service.vm.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: 100, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + }, + }}, []*secp256k1.PrivateKey{keys[0]}, - keys[0].PublicKey().Address(), // change addr - nil, + common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) }, }, @@ -436,14 +466,21 @@ func TestGetStake(t *testing.T) { delegatorStartTime := defaultValidateStartTime delegatorEndTime := defaultGenesisTime.Add(defaultMinStakingDuration) tx, err := txBuilder.NewAddDelegatorTx( - stakeAmount, - uint64(delegatorStartTime.Unix()), - uint64(delegatorEndTime.Unix()), - delegatorNodeID, - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: delegatorNodeID, + Start: uint64(delegatorStartTime.Unix()), + End: uint64(delegatorEndTime.Unix()), + Wght: stakeAmount, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, []*secp256k1.PrivateKey{keys[0]}, - keys[0].PublicKey().Address(), // change addr - nil, + common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) require.NoError(err) @@ -491,15 +528,22 @@ func TestGetStake(t *testing.T) { pendingStakerNodeID := ids.GenerateTestNodeID() pendingStakerEndTime := uint64(defaultGenesisTime.Add(defaultMinStakingDuration).Unix()) tx, err = txBuilder.NewAddValidatorTx( - stakeAmount, - uint64(defaultGenesisTime.Unix()), - pendingStakerEndTime, - pendingStakerNodeID, - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: pendingStakerNodeID, + Start: uint64(defaultGenesisTime.Unix()), + End: pendingStakerEndTime, + Wght: stakeAmount, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, 0, []*secp256k1.PrivateKey{keys[0]}, - keys[0].PublicKey().Address(), // change addr - nil, + common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) require.NoError(err) @@ -570,14 +614,21 @@ func TestGetCurrentValidators(t *testing.T) { service.vm.ctx.Lock.Lock() delTx, err := txBuilder.NewAddDelegatorTx( - stakeAmount, - uint64(delegatorStartTime.Unix()), - uint64(delegatorEndTime.Unix()), - validatorNodeID, - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: validatorNodeID, + Start: uint64(delegatorStartTime.Unix()), + End: uint64(delegatorEndTime.Unix()), + Wght: stakeAmount, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, []*secp256k1.PrivateKey{keys[0]}, - keys[0].PublicKey().Address(), // change addr - nil, + common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) require.NoError(err) @@ -710,8 +761,10 @@ func TestGetBlock(t *testing.T) { []ids.ID{}, "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - keys[0].PublicKey().Address(), // change addr - nil, + common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) require.NoError(err) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index d33bc85829e..5e645388274 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -10,8 +10,6 @@ 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" "github.com/ava-labs/avalanchego/vms/platformvm/config" @@ -28,369 +26,108 @@ import ( // Max number of items allowed in a page const MaxPageSize = 1024 -var _ Builder = (*builder)(nil) - -type Builder interface { - AtomicTxBuilder - DecisionTxBuilder - ProposalTxBuilder -} - -type AtomicTxBuilder interface { - // chainID: chain to import UTXOs from - // to: address of recipient - // keys: keys to import the funds - // changeAddr: address to send change to, if there is any - NewImportTx( - chainID ids.ID, - to ids.ShortID, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, - ) (*txs.Tx, error) - - // amount: amount of tokens to export - // chainID: chain to send the UTXOs to - // to: address of recipient - // keys: keys to pay the fee and provide the tokens - // changeAddr: address to send change to, if there is any - NewExportTx( - amount uint64, - chainID ids.ID, - to ids.ShortID, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, - ) (*txs.Tx, error) -} - -type DecisionTxBuilder interface { - // subnetID: ID of the subnet that validates the new chain - // genesisData: byte repr. of genesis state of the new chain - // vmID: ID of VM this chain runs - // fxIDs: ids of features extensions this chain supports - // chainName: name of the chain - // keys: keys to sign the tx - // changeAddr: address to send change to, if there is any - NewCreateChainTx( - subnetID ids.ID, - genesisData []byte, - vmID ids.ID, - fxIDs []ids.ID, - chainName string, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, - ) (*txs.Tx, error) - - // threshold: [threshold] of [ownerAddrs] needed to manage this subnet - // ownerAddrs: control addresses for the new subnet - // keys: keys to pay the fee - // changeAddr: address to send change to, if there is any - NewCreateSubnetTx( - threshold uint32, - ownerAddrs []ids.ShortID, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - 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 - // changeAddr: address to send change to, if there is any - NewBaseTx( - amount uint64, - owner secp256k1fx.OutputOwners, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, - ) (*txs.Tx, error) -} - -type ProposalTxBuilder interface { - // stakeAmount: amount the validator stakes - // startTime: unix time they start validating - // endTime: unix time they stop validating - // nodeID: ID of the node we want to validate with - // rewardAddress: address to send reward to, if applicable - // shares: 10,000 times percentage of reward taken from delegators - // keys: Keys providing the staked tokens - // changeAddr: Address to send change to, if there is any - NewAddValidatorTx( - stakeAmount, - startTime, - endTime uint64, - nodeID ids.NodeID, - rewardAddress ids.ShortID, - shares uint32, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, - ) (*txs.Tx, error) - - // stakeAmount: amount the validator stakes - // startTime: unix time they start validating - // endTime: unix time they stop validating - // nodeID: ID of the node we want to validate with - // pop: the node proof of possession - // rewardAddress: address to send reward to, if applicable - // shares: 10,000 times percentage of reward taken from delegators - // keys: Keys providing the staked tokens - // changeAddr: Address to send change to, if there is any - NewAddPermissionlessValidatorTx( - stakeAmount, - startTime, - endTime uint64, - nodeID ids.NodeID, - pop *vmsigner.ProofOfPossession, - rewardAddress ids.ShortID, - shares uint32, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, - ) (*txs.Tx, error) - - // stakeAmount: amount the delegator stakes - // startTime: unix time they start delegating - // endTime: unix time they stop delegating - // nodeID: ID of the node we are delegating to - // rewardAddress: address to send reward to, if applicable - // keys: keys providing the staked tokens - // changeAddr: address to send change to, if there is any - NewAddDelegatorTx( - stakeAmount, - startTime, - endTime uint64, - nodeID ids.NodeID, - rewardAddress ids.ShortID, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, - ) (*txs.Tx, error) - - // stakeAmount: amount the delegator stakes - // startTime: unix time they start delegating - // endTime: unix time they stop delegating - // nodeID: ID of the node we are delegating to - // rewardAddress: address to send reward to, if applicable - // keys: keys providing the staked tokens - // changeAddr: address to send change to, if there is any - NewAddPermissionlessDelegatorTx( - stakeAmount, - startTime, - endTime uint64, - nodeID ids.NodeID, - rewardAddress ids.ShortID, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, - ) (*txs.Tx, error) - - // weight: sampling weight of the new validator - // startTime: unix time they start delegating - // endTime: unix time they top delegating - // nodeID: ID of the node validating - // subnetID: ID of the subnet the validator will validate - // keys: keys to use for adding the validator - // changeAddr: address to send change to, if there is any - NewAddSubnetValidatorTx( - weight, - startTime, - endTime uint64, - nodeID ids.NodeID, - subnetID ids.ID, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, - ) (*txs.Tx, error) - - // Creates a transaction that removes [nodeID] - // as a validator from [subnetID] - // keys: keys to use for removing the validator - // changeAddr: address to send change to, if there is any - NewRemoveSubnetValidatorTx( - nodeID ids.NodeID, - subnetID ids.ID, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, - ) (*txs.Tx, error) - - // Creates a transaction that transfers ownership of [subnetID] - // threshold: [threshold] of [ownerAddrs] needed to manage this subnet - // ownerAddrs: control addresses for the new subnet - // keys: keys to use for modifying the subnet - // changeAddr: address to send change to, if there is any - NewTransferSubnetOwnershipTx( - subnetID ids.ID, - threshold uint32, - ownerAddrs []ids.ShortID, - keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, - ) (*txs.Tx, error) -} - func New( ctx *snow.Context, cfg *config.Config, state state.State, atomicUTXOManager avax.AtomicUTXOManager, -) Builder { - return &builder{ +) *Builder { + return &Builder{ ctx: ctx, backend: NewBackend(cfg, state, atomicUTXOManager), } } -type builder struct { +type Builder struct { ctx *snow.Context backend *Backend } -func (b *builder) NewImportTx( - from ids.ID, - to ids.ShortID, +func (b *Builder) NewImportTx( + chainID ids.ID, + to *secp256k1fx.OutputOwners, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) - outOwner := &secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{to}, - } - utx, err := pBuilder.NewImportTx( - from, - outOwner, - options(changeAddr, memo)..., + chainID, + to, + options..., ) if err != nil { return nil, fmt.Errorf("failed building import tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -// TODO: should support other assets than AVAX -func (b *builder) NewExportTx( - amount uint64, +func (b *Builder) NewExportTx( chainID ids.ID, - to ids.ShortID, + outputs []*avax.TransferableOutput, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) - 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)..., + options..., ) if err != nil { return nil, fmt.Errorf("failed building export tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) NewCreateChainTx( +func (b *Builder) NewCreateChainTx( subnetID ids.ID, - genesisData []byte, + genesis []byte, vmID ids.ID, fxIDs []ids.ID, chainName string, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) - utx, err := pBuilder.NewCreateChainTx(subnetID, genesisData, vmID, fxIDs, chainName, options(changeAddr, memo)...) + utx, err := pBuilder.NewCreateChainTx( + subnetID, + genesis, + vmID, + fxIDs, + chainName, + options..., + ) if err != nil { return nil, fmt.Errorf("failed building create chain tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) NewCreateSubnetTx( - threshold uint32, - ownerAddrs []ids.ShortID, +func (b *Builder) NewCreateSubnetTx( + owner *secp256k1fx.OutputOwners, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) - utils.Sort(ownerAddrs) // sort control addresses - subnetOwner := &secp256k1fx.OutputOwners{ - Threshold: threshold, - Addrs: ownerAddrs, - } - - utx, err := pBuilder.NewCreateSubnetTx(subnetOwner, options(changeAddr, memo)...) + utx, err := pBuilder.NewCreateSubnetTx( + owner, + options..., + ) if err != nil { return nil, fmt.Errorf("failed building create subnet tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) NewTransformSubnetTx( +func (b *Builder) NewTransformSubnetTx( subnetID ids.ID, assetID ids.ID, initialSupply uint64, @@ -406,8 +143,7 @@ func (b *builder) NewTransformSubnetTx( maxValidatorWeightFactor byte, uptimeRequirement uint32, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) @@ -426,316 +162,184 @@ func (b *builder) NewTransformSubnetTx( minDelegatorStake, maxValidatorWeightFactor, uptimeRequirement, - options(changeAddr, memo)..., + options..., ) if err != nil { return nil, fmt.Errorf("failed building transform subnet tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) NewAddValidatorTx( - stakeAmount, - startTime, - endTime uint64, - nodeID ids.NodeID, - rewardAddress ids.ShortID, +func (b *Builder) NewAddValidatorTx( + vdr *txs.Validator, + rewardsOwner *secp256k1fx.OutputOwners, shares uint32, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) - vdr := &txs.Validator{ - NodeID: nodeID, - Start: startTime, - End: endTime, - Wght: stakeAmount, - } - - rewardOwner := &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardAddress}, - } - - utx, err := pBuilder.NewAddValidatorTx(vdr, rewardOwner, shares, options(changeAddr, memo)...) + utx, err := pBuilder.NewAddValidatorTx( + vdr, + rewardsOwner, + shares, + options..., + ) if err != nil { return nil, fmt.Errorf("failed building add validator tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) NewAddPermissionlessValidatorTx( - stakeAmount, - startTime, - endTime uint64, - nodeID ids.NodeID, - pop *vmsigner.ProofOfPossession, - rewardAddress ids.ShortID, +func (b *Builder) NewAddPermissionlessValidatorTx( + vdr *txs.SubnetValidator, + signer vmsigner.Signer, + assetID ids.ID, + validationRewardsOwner *secp256k1fx.OutputOwners, + delegationRewardsOwner *secp256k1fx.OutputOwners, shares uint32, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) - vdr := &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - Start: startTime, - End: endTime, - Wght: stakeAmount, - }, - 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 + signer, + assetID, + validationRewardsOwner, + delegationRewardsOwner, shares, - options(changeAddr, memo)..., + options..., ) if err != nil { return nil, fmt.Errorf("failed building add permissionless validator tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) NewAddDelegatorTx( - stakeAmount, - startTime, - endTime uint64, - nodeID ids.NodeID, - rewardAddress ids.ShortID, +func (b *Builder) NewAddDelegatorTx( + vdr *txs.Validator, + rewardsOwner *secp256k1fx.OutputOwners, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) - vdr := &txs.Validator{ - NodeID: nodeID, - Start: startTime, - End: endTime, - Wght: stakeAmount, - } - - rewardOwner := &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardAddress}, - } - utx, err := pBuilder.NewAddDelegatorTx( vdr, - rewardOwner, - options(changeAddr, memo)..., + rewardsOwner, + options..., ) if err != nil { return nil, fmt.Errorf("failed building add delegator tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) NewAddPermissionlessDelegatorTx( - stakeAmount, - startTime, - endTime uint64, - nodeID ids.NodeID, - rewardAddress ids.ShortID, +func (b *Builder) NewAddPermissionlessDelegatorTx( + vdr *txs.SubnetValidator, + assetID ids.ID, + rewardsOwner *secp256k1fx.OutputOwners, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) - vdr := &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - Start: startTime, - End: endTime, - Wght: stakeAmount, - }, - Subnet: constants.PrimaryNetworkID, - } - - rewardOwner := &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardAddress}, - } - utx, err := pBuilder.NewAddPermissionlessDelegatorTx( vdr, - b.ctx.AVAXAssetID, - rewardOwner, - options(changeAddr, memo)..., + assetID, + rewardsOwner, + options..., ) if err != nil { return nil, fmt.Errorf("failed building add permissionless delegator tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) NewAddSubnetValidatorTx( - weight, - startTime, - endTime uint64, - nodeID ids.NodeID, - subnetID ids.ID, +func (b *Builder) NewAddSubnetValidatorTx( + vdr *txs.SubnetValidator, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) - vdr := &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - Start: startTime, - End: endTime, - Wght: weight, - }, - Subnet: subnetID, - } - utx, err := pBuilder.NewAddSubnetValidatorTx( vdr, - options(changeAddr, memo)..., + options..., ) if err != nil { return nil, fmt.Errorf("failed building add subnet validator tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) NewRemoveSubnetValidatorTx( +func (b *Builder) NewRemoveSubnetValidatorTx( nodeID ids.NodeID, subnetID ids.ID, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) utx, err := pBuilder.NewRemoveSubnetValidatorTx( nodeID, subnetID, - options(changeAddr, memo)..., + options..., ) if err != nil { return nil, fmt.Errorf("failed building remove subnet validator tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) NewTransferSubnetOwnershipTx( +func (b *Builder) NewTransferSubnetOwnershipTx( subnetID ids.ID, - threshold uint32, - ownerAddrs []ids.ShortID, + owner *secp256k1fx.OutputOwners, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) - utils.Sort(ownerAddrs) // sort control addresses - newOwner := &secp256k1fx.OutputOwners{ - Threshold: threshold, - Addrs: ownerAddrs, - } - utx, err := pBuilder.NewTransferSubnetOwnershipTx( subnetID, - newOwner, - options(changeAddr, memo)..., + owner, + options..., ) if err != nil { return nil, fmt.Errorf("failed building transfer subnet ownership tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) NewBaseTx( - amount uint64, - owner secp256k1fx.OutputOwners, +func (b *Builder) NewBaseTx( + outputs []*avax.TransferableOutput, keys []*secp256k1.PrivateKey, - changeAddr ids.ShortID, - memo []byte, + options ...common.Option, ) (*txs.Tx, error) { pBuilder, pSigner := b.builders(keys) - out := &avax.TransferableOutput{ - Asset: avax.Asset{ID: b.ctx.AVAXAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: amount, - OutputOwners: owner, - }, - } - utx, err := pBuilder.NewBaseTx( - []*avax.TransferableOutput{out}, - options(changeAddr, memo)..., + outputs, + options..., ) if err != nil { return nil, fmt.Errorf("failed building base tx: %w", err) } - tx, err := walletsigner.SignUnsigned(context.Background(), pSigner, utx) - if err != nil { - return nil, err - } - return tx, tx.SyntacticVerify(b.ctx) + return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, walletsigner.Signer) { +func (b *Builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, walletsigner.Signer) { var ( kc = secp256k1fx.NewKeychain(keys...) addrs = kc.Addresses() @@ -747,13 +351,3 @@ func (b *builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, return builder, signer } - -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)}, - ) -} diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index 4e106a82de1..ea36af13e93 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) func newAdvanceTimeTx(t testing.TB, timestamp time.Time) (*txs.Tx, error) { @@ -376,14 +377,16 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { for _, staker := range test.subnetStakers { tx, err := env.txBuilder.NewAddSubnetValidatorTx( - 10, // Weight - uint64(staker.startTime.Unix()), - uint64(staker.endTime.Unix()), - staker.nodeID, // validator ID - subnetID, // Subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: staker.nodeID, + Start: uint64(staker.startTime.Unix()), + End: uint64(staker.endTime.Unix()), + Wght: 10, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -471,14 +474,16 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { subnetVdr1StartTime := defaultValidateStartTime subnetVdr1EndTime := defaultValidateStartTime.Add(defaultMinStakingDuration) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetVdr1StartTime.Unix()), // Start time - uint64(subnetVdr1EndTime.Unix()), // end time - subnetValidatorNodeID, // Node ID - subnetID, // Subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: subnetValidatorNodeID, + Start: uint64(subnetVdr1StartTime.Unix()), + End: uint64(subnetVdr1EndTime.Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -501,14 +506,16 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { // Queue a staker that joins the staker set after the above validator leaves subnetVdr2NodeID := genesisNodeIDs[1] tx, err = env.txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetVdr1EndTime.Add(time.Second).Unix()), // Start time - uint64(subnetVdr1EndTime.Add(time.Second).Add(defaultMinStakingDuration).Unix()), // end time - subnetVdr2NodeID, // Node ID - subnetID, // Subnet ID - []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, // Keys - ids.ShortEmpty, // reward address - nil, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: subnetVdr2NodeID, + Start: uint64(subnetVdr1EndTime.Add(time.Second).Unix()), + End: uint64(subnetVdr1EndTime.Add(time.Second).Add(defaultMinStakingDuration).Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, + []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ) require.NoError(err) @@ -578,14 +585,16 @@ func TestTrackedSubnet(t *testing.T) { subnetVdr1StartTime := defaultValidateStartTime.Add(1 * time.Minute) subnetVdr1EndTime := defaultValidateStartTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetVdr1StartTime.Unix()), // Start time - uint64(subnetVdr1EndTime.Unix()), // end time - subnetValidatorNodeID, // Node ID - subnetID, // Subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: subnetValidatorNodeID, + Start: uint64(subnetVdr1StartTime.Unix()), + End: uint64(subnetVdr1EndTime.Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -681,18 +690,21 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { pendingDelegatorEndTime := pendingDelegatorStartTime.Add(1 * time.Second) addDelegatorTx, err := env.txBuilder.NewAddDelegatorTx( - env.config.MinDelegatorStake, - uint64(pendingDelegatorStartTime.Unix()), - uint64(pendingDelegatorEndTime.Unix()), - nodeID, - preFundedKeys[0].PublicKey().Address(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(pendingDelegatorStartTime.Unix()), + End: uint64(pendingDelegatorEndTime.Unix()), + Wght: env.config.MinDelegatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{ preFundedKeys[0], preFundedKeys[1], preFundedKeys[4], }, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -780,14 +792,17 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { pendingDelegatorStartTime := pendingValidatorStartTime.Add(1 * time.Second) pendingDelegatorEndTime := pendingDelegatorStartTime.Add(defaultMinStakingDuration) addDelegatorTx, err := env.txBuilder.NewAddDelegatorTx( - env.config.MinDelegatorStake, - uint64(pendingDelegatorStartTime.Unix()), - uint64(pendingDelegatorEndTime.Unix()), - nodeID, - preFundedKeys[0].PublicKey().Address(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(pendingDelegatorStartTime.Unix()), + End: uint64(pendingDelegatorEndTime.Unix()), + Wght: env.config.MinDelegatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1], preFundedKeys[4]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -893,15 +908,18 @@ func addPendingValidator( keys []*secp256k1.PrivateKey, ) (*txs.Tx, error) { addPendingValidatorTx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, - uint64(startTime.Unix()), - uint64(endTime.Unix()), - nodeID, - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, 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 7ab69b519ec..176e6b80615 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -41,8 +41,6 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { nil, "chain name", []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -75,8 +73,6 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { nil, "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -116,8 +112,6 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { nil, "chain name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -149,8 +143,6 @@ func TestCreateChainTxValid(t *testing.T) { nil, "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 0ee1966e608..d45a52b486d 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -11,7 +11,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/state" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) func TestNewExportTx(t *testing.T) { @@ -49,12 +51,19 @@ func TestNewExportTx(t *testing.T) { require := require.New(t) tx, err := env.txBuilder.NewExportTx( - defaultBalance-defaultTxFee, // Amount of tokens to export tt.destinationChainID, - to, + []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: env.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: defaultBalance - defaultTxFee, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{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 bfd556ae50d..e6b522fd539 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -45,6 +45,7 @@ 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" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) const ( @@ -104,7 +105,7 @@ type environment struct { atomicUTXOs avax.AtomicUTXOManager uptimes uptime.Manager utxosHandler utxo.Verifier - txBuilder builder.Builder + txBuilder *builder.Builder backend Backend } @@ -211,22 +212,26 @@ func newEnvironment(t *testing.T, f fork) *environment { func addSubnet( t *testing.T, env *environment, - txBuilder builder.Builder, + txBuilder *builder.Builder, ) { require := require.New(t) // Create a subnet var err error testSubnet1, err = txBuilder.NewCreateSubnetTx( - 2, // threshold; 2 sigs from keys[0], keys[1], keys[2] needed to add validator to this subnet - []ids.ShortID{ // control keys - preFundedKeys[0].PublicKey().Address(), - preFundedKeys[1].PublicKey().Address(), - preFundedKeys[2].PublicKey().Address(), + &secp256k1fx.OutputOwners{ + Threshold: 2, + Addrs: []ids.ShortID{ + preFundedKeys[0].PublicKey().Address(), + preFundedKeys[1].PublicKey().Address(), + preFundedKeys[2].PublicKey().Address(), + }, }, []*secp256k1.PrivateKey{preFundedKeys[0]}, - preFundedKeys[0].PublicKey().Address(), - nil, + common.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, + }), ) require.NoError(err) diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index 5ac6a76354b..d70b7828d67 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -106,7 +106,11 @@ func TestNewImportTx(t *testing.T) { }, } - to := ids.GenerateTestShortID() + to := &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { require := require.New(t) @@ -116,8 +120,6 @@ func TestNewImportTx(t *testing.T) { tt.sourceChainID, 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 e785f387de1..582e622b222 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -34,15 +34,18 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { // pending validator set with the minimum staking amount addMinStakeValidator := func(target *environment) { tx, err := target.txBuilder.NewAddValidatorTx( - target.config.MinValidatorStake, // stake amount - newValidatorStartTime, // start time - newValidatorEndTime, // end time - newValidatorID, // node ID - rewardAddress, // Reward Address - reward.PercentDenominator, // Shares + &txs.Validator{ + NodeID: newValidatorID, + Start: newValidatorStartTime, + End: newValidatorEndTime, + Wght: target.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, + }, + reward.PercentDenominator, // Shares []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(t, err) @@ -65,15 +68,18 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { // pending validator set with the maximum staking amount addMaxStakeValidator := func(target *environment) { tx, err := target.txBuilder.NewAddValidatorTx( - target.config.MaxValidatorStake, // stake amount - newValidatorStartTime, // start time - newValidatorEndTime, // end time - newValidatorID, // node ID - rewardAddress, // Reward Address - reward.PercentDenominator, // Shared + &txs.Validator{ + NodeID: newValidatorID, + Start: newValidatorStartTime, + End: newValidatorEndTime, + Wght: target.config.MaxValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, + }, + reward.PercentDenominator, // Shared []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(t, err) @@ -238,14 +244,17 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { freshTH.config.ApricotPhase3Time = tt.AP3Time tx, err := freshTH.txBuilder.NewAddDelegatorTx( - tt.stakeAmount, - tt.startTime, - tt.endTime, - tt.nodeID, - tt.rewardAddress, + &txs.Validator{ + NodeID: tt.nodeID, + Start: tt.startTime, + End: tt.endTime, + Wght: tt.stakeAmount, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{tt.rewardAddress}, + }, tt.feeKeys, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -283,14 +292,16 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // but stops validating subnet after stops validating primary network // (note that keys[0] is a genesis validator) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(defaultValidateStartTime.Unix())+1, - uint64(defaultValidateEndTime.Unix())+1, - nodeID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(defaultValidateStartTime.Unix()) + 1, + End: uint64(defaultValidateEndTime.Unix()) + 1, + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -316,14 +327,16 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // primary network validation period // (note that keys[0] is a genesis validator) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(defaultValidateStartTime.Unix())+1, - uint64(defaultValidateEndTime.Unix()), - nodeID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(defaultValidateStartTime.Unix()) + 1, + End: uint64(defaultValidateEndTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -349,29 +362,34 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { dsEndTime := dsStartTime.Add(5 * defaultMinStakingDuration) addDSTx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, // stake amount - uint64(dsStartTime.Unix()), // start time - uint64(dsEndTime.Unix()), // end time - pendingDSValidatorID, // node ID - ids.GenerateTestShortID(), // reward address - reward.PercentDenominator, // shares + &txs.Validator{ + NodeID: pendingDSValidatorID, + Start: uint64(dsStartTime.Unix()), + End: uint64(dsEndTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + reward.PercentDenominator, // shares []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(err) { // Case: Proposed validator isn't in pending or current validator sets tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(dsStartTime.Unix()), // start validating subnet before primary network - uint64(dsEndTime.Unix()), - pendingDSValidatorID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: pendingDSValidatorID, + Start: uint64(dsStartTime.Unix()), // start validating subnet before primary network + End: uint64(dsEndTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -412,14 +430,16 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // Case: Proposed validator is pending validator of primary network // but starts validating subnet before primary network tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(dsStartTime.Unix())-1, // start validating subnet before primary network - uint64(dsEndTime.Unix()), - pendingDSValidatorID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: pendingDSValidatorID, + Start: uint64(dsStartTime.Unix()) - 1, // start validating subnet before primary network + End: uint64(dsEndTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -443,14 +463,16 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // Case: Proposed validator is pending validator of primary network // but stops validating subnet after primary network tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(dsStartTime.Unix()), - uint64(dsEndTime.Unix())+1, // stop validating subnet after stopping validating primary network - pendingDSValidatorID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: pendingDSValidatorID, + Start: uint64(dsStartTime.Unix()), + End: uint64(dsEndTime.Unix()) + 1, // stop validating subnet after stopping validating primary network + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -474,14 +496,16 @@ 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 tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(dsStartTime.Unix()), // same start time as for primary network - uint64(dsEndTime.Unix()), // same end time as for primary network - pendingDSValidatorID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: pendingDSValidatorID, + Start: uint64(dsStartTime.Unix()), // same start time as for primary network + End: uint64(dsEndTime.Unix()), // same end time as for primary network + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -507,14 +531,16 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(newTimestamp.Unix()), // start time - uint64(newTimestamp.Add(defaultMinStakingDuration).Unix()), // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(newTimestamp.Unix()), + End: uint64(newTimestamp.Add(defaultMinStakingDuration).Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -540,14 +566,16 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // Case: Proposed validator already validating the subnet // First, add validator as validator of subnet subnetTx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(defaultValidateStartTime.Unix()), // start time - uint64(defaultValidateEndTime.Unix()), // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(defaultValidateStartTime.Unix()), + End: uint64(defaultValidateEndTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -568,14 +596,16 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Node with ID nodeIDKey.PublicKey().Address() now validating subnet with ID testSubnet1.ID duplicateSubnetTx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(defaultValidateStartTime.Unix())+1, // start time - uint64(defaultValidateEndTime.Unix()), // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(defaultValidateStartTime.Unix()) + 1, + End: uint64(defaultValidateEndTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -602,14 +632,16 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Case: Too few signatures tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(defaultValidateStartTime.Unix())+1, // start time - uint64(defaultValidateStartTime.Add(defaultMinStakingDuration).Unix())+1, // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(defaultValidateStartTime.Unix()) + 1, + End: uint64(defaultValidateStartTime.Add(defaultMinStakingDuration).Unix()) + 1, + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[2]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -639,14 +671,16 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Case: Control Signature from invalid key (keys[3] is not a control key) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(defaultValidateStartTime.Unix())+1, // start time - uint64(defaultValidateStartTime.Add(defaultMinStakingDuration).Unix())+1, // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(defaultValidateStartTime.Unix()) + 1, + End: uint64(defaultValidateStartTime.Add(defaultMinStakingDuration).Unix()) + 1, + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -675,14 +709,16 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // Case: Proposed validator in pending validator set for subnet // First, add validator to pending validator set of subnet tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(defaultValidateStartTime.Unix())+1, // start time - uint64(defaultValidateStartTime.Add(defaultMinStakingDuration).Unix())+1, // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(defaultValidateStartTime.Unix()) + 1, + End: uint64(defaultValidateStartTime.Add(defaultMinStakingDuration).Unix()) + 1, + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -729,15 +765,18 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { { // Case: Validator's start time too early tx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, - uint64(chainTime.Unix()), - uint64(defaultValidateEndTime.Unix()), - nodeID, - ids.ShortEmpty, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(chainTime.Unix()), + End: uint64(defaultValidateEndTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -762,15 +801,18 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { // Case: Validator already validating primary network tx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, - uint64(defaultValidateStartTime.Unix())+1, - uint64(defaultValidateEndTime.Unix()), - nodeID, - ids.ShortEmpty, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(defaultValidateStartTime.Unix()) + 1, + End: uint64(defaultValidateEndTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -794,15 +836,18 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { // Case: Validator in pending validator set of primary network startTime := defaultValidateStartTime.Add(1 * time.Second) tx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, // stake amount - uint64(startTime.Unix()), // start time - uint64(startTime.Add(defaultMinStakingDuration).Unix()), // end time - nodeID, - ids.ShortEmpty, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(startTime.Add(defaultMinStakingDuration).Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, // shares []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -840,15 +885,18 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { { // Case: Validator doesn't have enough tokens to cover stake amount tx, err := env.txBuilder.NewAddValidatorTx( // create the tx - env.config.MinValidatorStake, - uint64(defaultValidateStartTime.Unix())+1, - uint64(defaultValidateEndTime.Unix()), - ids.GenerateTestNodeID(), - ids.ShortEmpty, + &txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(defaultValidateStartTime.Unix()) + 1, + End: uint64(defaultValidateEndTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, 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 cbd7f7bdf4e..0e5a901e9a0 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -240,15 +240,18 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { vdrNodeID := ids.GenerateTestNodeID() vdrTx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, // stakeAmt - vdrStartTime, - vdrEndTime, - vdrNodeID, // node ID - vdrRewardAddress, // reward address + &txs.Validator{ + NodeID: vdrNodeID, // node ID + Start: vdrStartTime, + End: vdrEndTime, + Wght: env.config.MinValidatorStake, // stakeAmt + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{vdrRewardAddress}, + }, reward.PercentDenominator/4, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -256,14 +259,17 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { delEndTime := vdrEndTime delTx, err := env.txBuilder.NewAddDelegatorTx( - env.config.MinDelegatorStake, - delStartTime, - delEndTime, - vdrNodeID, - delRewardAddress, + &txs.Validator{ + NodeID: vdrNodeID, + Start: delStartTime, + End: delEndTime, + Wght: env.config.MinDelegatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{delRewardAddress}, + }, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // Change address - nil, ) require.NoError(err) @@ -363,15 +369,18 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { vdrNodeID := ids.GenerateTestNodeID() vdrTx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, - vdrStartTime, - vdrEndTime, - vdrNodeID, - vdrRewardAddress, + &txs.Validator{ + NodeID: vdrNodeID, + Start: vdrStartTime, + End: vdrEndTime, + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{vdrRewardAddress}, + }, reward.PercentDenominator/4, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, /*=changeAddr*/ - nil, ) require.NoError(err) @@ -379,14 +388,17 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { delEndTime := vdrEndTime delTx, err := env.txBuilder.NewAddDelegatorTx( - env.config.MinDelegatorStake, - delStartTime, - delEndTime, - vdrNodeID, - delRewardAddress, + &txs.Validator{ + NodeID: vdrNodeID, + Start: delStartTime, + End: delEndTime, + Wght: env.config.MinDelegatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{delRewardAddress}, + }, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, /*=changeAddr*/ - nil, ) require.NoError(err) @@ -581,15 +593,18 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * vdrNodeID := ids.GenerateTestNodeID() vdrTx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, // stakeAmt - vdrStartTime, - vdrEndTime, - vdrNodeID, // node ID - vdrRewardAddress, // reward address + &txs.Validator{ + NodeID: vdrNodeID, + Start: vdrStartTime, + End: vdrEndTime, + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{vdrRewardAddress}, + }, reward.PercentDenominator/4, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -597,14 +612,17 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * delEndTime := vdrEndTime delTx, err := env.txBuilder.NewAddDelegatorTx( - env.config.MinDelegatorStake, - delStartTime, - delEndTime, - vdrNodeID, - delRewardAddress, + &txs.Validator{ + NodeID: vdrNodeID, + Start: delStartTime, + End: delEndTime, + Wght: env.config.MinDelegatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{delRewardAddress}, + }, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // Change address - nil, ) require.NoError(err) @@ -745,29 +763,35 @@ func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { vdrNodeID := ids.GenerateTestNodeID() vdrTx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, // stakeAmt - vdrStartTime, - vdrEndTime, - vdrNodeID, // node ID - vdrRewardAddress, // reward address + &txs.Validator{ + NodeID: vdrNodeID, + Start: vdrStartTime, + End: vdrEndTime, + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{vdrRewardAddress}, + }, reward.PercentDenominator/4, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(err) delStartTime := vdrStartTime delEndTime := vdrEndTime delTx, err := env.txBuilder.NewAddDelegatorTx( - env.config.MinDelegatorStake, - delStartTime, - delEndTime, - vdrNodeID, - delRewardAddress, + &txs.Validator{ + NodeID: vdrNodeID, + Start: delStartTime, + End: delEndTime, + Wght: env.config.MinDelegatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{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 ff249f371f9..66a4799eaf1 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/txs" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) // This tests that the math performed during TransformSubnetTx execution can @@ -72,15 +73,18 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { env.config.BanffTime = test.banffTime tx, err := env.txBuilder.NewAddValidatorTx( // create the tx - env.config.MinValidatorStake, - uint64(startTime.Unix()), - uint64(defaultValidateEndTime.Unix()), - ids.EmptyNodeID, - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: ids.EmptyNodeID, + Start: uint64(startTime.Unix()), + End: uint64(defaultValidateEndTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -110,15 +114,18 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { // pending validator set with the minimum staking amount addMinStakeValidator := func(target *environment) { tx, err := target.txBuilder.NewAddValidatorTx( - target.config.MinValidatorStake, // stake amount - uint64(newValidatorStartTime.Unix()), // start time - uint64(newValidatorEndTime.Unix()), // end time - newValidatorID, // node ID - rewardAddress, // Reward Address - reward.PercentDenominator, // Shares + &txs.Validator{ + NodeID: newValidatorID, + Start: uint64(newValidatorStartTime.Unix()), + End: uint64(newValidatorEndTime.Unix()), + Wght: target.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, + }, + reward.PercentDenominator, // Shares []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(t, err) @@ -141,15 +148,18 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { // pending validator set with the maximum staking amount addMaxStakeValidator := func(target *environment) { tx, err := target.txBuilder.NewAddValidatorTx( - target.config.MaxValidatorStake, // stake amount - uint64(newValidatorStartTime.Unix()), // start time - uint64(newValidatorEndTime.Unix()), // end time - newValidatorID, // node ID - rewardAddress, // Reward Address - reward.PercentDenominator, // Shared + &txs.Validator{ + NodeID: newValidatorID, + Start: uint64(newValidatorStartTime.Unix()), + End: uint64(newValidatorEndTime.Unix()), + Wght: target.config.MaxValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, + }, + reward.PercentDenominator, // Shared []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(t, err) @@ -314,14 +324,17 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { freshTH.config.ApricotPhase3Time = tt.AP3Time tx, err := freshTH.txBuilder.NewAddDelegatorTx( - tt.stakeAmount, - uint64(tt.startTime.Unix()), - uint64(tt.endTime.Unix()), - tt.nodeID, - tt.rewardAddress, + &txs.Validator{ + NodeID: tt.nodeID, + Start: uint64(tt.startTime.Unix()), + End: uint64(tt.endTime.Unix()), + Wght: tt.stakeAmount, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{tt.rewardAddress}, + }, tt.feeKeys, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -359,14 +372,16 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // (note that keys[0] is a genesis validator) startTime := defaultValidateStartTime.Add(time.Second) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(startTime.Unix()), - uint64(defaultValidateEndTime.Unix())+1, - nodeID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(defaultValidateEndTime.Unix()) + 1, + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -388,14 +403,16 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // primary network validation period // (note that keys[0] is a genesis validator) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(defaultValidateStartTime.Unix()+1), - uint64(defaultValidateEndTime.Unix()), - nodeID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(defaultValidateStartTime.Unix() + 1), + End: uint64(defaultValidateEndTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -417,29 +434,34 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { dsEndTime := dsStartTime.Add(5 * defaultMinStakingDuration) addDSTx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, // stake amount - uint64(dsStartTime.Unix()), // start time - uint64(dsEndTime.Unix()), // end time - pendingDSValidatorID, // node ID - ids.GenerateTestShortID(), // reward address - reward.PercentDenominator, // shares + &txs.Validator{ + NodeID: pendingDSValidatorID, + Start: uint64(dsStartTime.Unix()), + End: uint64(dsEndTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + reward.PercentDenominator, // shares []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(err) { // Case: Proposed validator isn't in pending or current validator sets tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(dsStartTime.Unix()), // start validating subnet before primary network - uint64(dsEndTime.Unix()), - pendingDSValidatorID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: pendingDSValidatorID, + Start: uint64(dsStartTime.Unix()), // start validating subnet before primary network + End: uint64(dsEndTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -476,14 +498,16 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // Case: Proposed validator is pending validator of primary network // but starts validating subnet before primary network tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(dsStartTime.Unix())-1, // start validating subnet before primary network - uint64(dsEndTime.Unix()), - pendingDSValidatorID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: pendingDSValidatorID, + Start: uint64(dsStartTime.Unix()) - 1, // start validating subnet before primary network + End: uint64(dsEndTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -503,14 +527,16 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // Case: Proposed validator is pending validator of primary network // but stops validating subnet after primary network tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(dsStartTime.Unix()), - uint64(dsEndTime.Unix())+1, // stop validating subnet after stopping validating primary network - pendingDSValidatorID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: pendingDSValidatorID, + Start: uint64(dsStartTime.Unix()), + End: uint64(dsEndTime.Unix()) + 1, // stop validating subnet after stopping validating primary network + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -530,14 +556,16 @@ 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 tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(dsStartTime.Unix()), // same start time as for primary network - uint64(dsEndTime.Unix()), // same end time as for primary network - pendingDSValidatorID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: pendingDSValidatorID, + Start: uint64(dsStartTime.Unix()), // same start time as for primary network + End: uint64(dsEndTime.Unix()), // same end time as for primary network + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -558,14 +586,16 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { { tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(newTimestamp.Unix()), // start time - uint64(newTimestamp.Add(defaultMinStakingDuration).Unix()), // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(newTimestamp.Unix()), + End: uint64(newTimestamp.Add(defaultMinStakingDuration).Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -587,14 +617,16 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // Case: Proposed validator already validating the subnet // First, add validator as validator of subnet subnetTx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(defaultValidateStartTime.Unix()), // start time - uint64(defaultValidateEndTime.Unix()), // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(defaultValidateStartTime.Unix()), + End: uint64(defaultValidateEndTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -616,14 +648,16 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // Node with ID nodeIDKey.PublicKey().Address() now validating subnet with ID testSubnet1.ID startTime := defaultValidateStartTime.Add(time.Second) duplicateSubnetTx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(startTime.Unix()), // start time - uint64(defaultValidateEndTime.Unix()), // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(defaultValidateEndTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -647,14 +681,16 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // Case: Duplicate signatures startTime := defaultValidateStartTime.Add(time.Second) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(startTime.Unix()), // start time - uint64(startTime.Add(defaultMinStakingDuration).Unix())+1, // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(startTime.Add(defaultMinStakingDuration).Unix()) + 1, + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1], testSubnet1ControlKeys[2]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -681,14 +717,16 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // Case: Too few signatures startTime := defaultValidateStartTime.Add(time.Second) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(startTime.Unix()), // start time - uint64(startTime.Add(defaultMinStakingDuration).Unix()), // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(startTime.Add(defaultMinStakingDuration).Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[2]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -715,14 +753,16 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // Case: Control Signature from invalid key (keys[3] is not a control key) startTime := defaultValidateStartTime.Add(time.Second) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(startTime.Unix()), // start time - uint64(startTime.Add(defaultMinStakingDuration).Unix()), // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(startTime.Add(defaultMinStakingDuration).Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], preFundedKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -748,14 +788,16 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) { // First, add validator to pending validator set of subnet startTime := defaultValidateStartTime.Add(time.Second) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(startTime.Unix())+1, // start time - uint64(startTime.Add(defaultMinStakingDuration).Unix())+1, // end time - nodeID, // node ID - testSubnet1.ID(), // subnet ID + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()) + 1, + End: uint64(startTime.Add(defaultMinStakingDuration).Unix()) + 1, + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -797,15 +839,18 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { { // Case: Validator's start time too early tx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, - uint64(defaultValidateStartTime.Unix())-1, - uint64(defaultValidateEndTime.Unix()), - nodeID, - ids.ShortEmpty, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(defaultValidateStartTime.Unix()) - 1, + End: uint64(defaultValidateEndTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -825,15 +870,18 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { // Case: Validator in current validator set of primary network startTime := defaultValidateStartTime.Add(1 * time.Second) tx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, // stake amount - uint64(startTime.Unix()), // start time - uint64(startTime.Add(defaultMinStakingDuration).Unix()), // end time - nodeID, - ids.ShortEmpty, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(startTime.Add(defaultMinStakingDuration).Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, reward.PercentDenominator, // shares []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -865,15 +913,18 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { // Case: Validator in pending validator set of primary network startTime := defaultValidateStartTime.Add(1 * time.Second) tx, err := env.txBuilder.NewAddValidatorTx( - env.config.MinValidatorStake, // stake amount - uint64(startTime.Unix()), // start time - uint64(startTime.Add(defaultMinStakingDuration).Unix()), // end time - nodeID, - ids.ShortEmpty, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(startTime.Add(defaultMinStakingDuration).Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, reward.PercentDenominator, // shares []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -902,15 +953,18 @@ func TestBanffStandardTxExecutorAddValidator(t *testing.T) { // Case: Validator doesn't have enough tokens to cover stake amount startTime := defaultValidateStartTime.Add(1 * time.Second) tx, err := env.txBuilder.NewAddValidatorTx( // create the tx - env.config.MinValidatorStake, - uint64(startTime.Unix()), - uint64(startTime.Add(defaultMinStakingDuration).Unix()), - nodeID, - ids.ShortEmpty, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(startTime.Add(defaultMinStakingDuration).Unix()), + Wght: env.config.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -954,15 +1008,18 @@ func TestDurangoDisabledTransactions(t *testing.T) { ) tx, err := env.txBuilder.NewAddValidatorTx( - defaultMinValidatorStake, - 0, // startTime - uint64(endTime.Unix()), - nodeID, - ids.ShortEmpty, // reward address, + &txs.Validator{ + NodeID: nodeID, + Start: 0, + End: uint64(endTime.Unix()), + Wght: defaultMinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, reward.PercentDenominator, // shares preFundedKeys, - ids.ShortEmpty, // change address - nil, // memo ) require.NoError(t, err) @@ -987,14 +1044,17 @@ func TestDurangoDisabledTransactions(t *testing.T) { it.Release() tx, err := env.txBuilder.NewAddDelegatorTx( - defaultMinValidatorStake, - 0, // startTime - uint64(primaryValidator.EndTime.Unix()), - primaryValidator.NodeID, - ids.ShortEmpty, // reward address, + &txs.Validator{ + NodeID: primaryValidator.NodeID, + Start: 0, + End: uint64(primaryValidator.EndTime.Unix()), + Wght: defaultMinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, preFundedKeys, - ids.ShortEmpty, // change address - nil, // memo ) require.NoError(t, err) @@ -1052,14 +1112,17 @@ func TestDurangoMemoField(t *testing.T) { it.Release() tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultMinValidatorStake, - 0, // startTime - uint64(primaryValidator.EndTime.Unix()), - primaryValidator.NodeID, - testSubnet1.TxID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: primaryValidator.NodeID, + Start: 0, + End: uint64(primaryValidator.EndTime.Unix()), + Wght: defaultMinValidatorStake, + }, + Subnet: testSubnet1.TxID, + }, preFundedKeys, - ids.ShortEmpty, - memoField, + common.WithMemo(memoField), ) require.NoError(t, err) @@ -1078,8 +1141,7 @@ func TestDurangoMemoField(t *testing.T) { []ids.ID{}, // fxIDs "aaa", // chain name preFundedKeys, - ids.ShortEmpty, - memoField, + common.WithMemo(memoField), ) require.NoError(t, err) @@ -1093,11 +1155,12 @@ func TestDurangoMemoField(t *testing.T) { name: "CreateSubnetTx", setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { tx, err := env.txBuilder.NewCreateSubnetTx( - 1, - []ids.ShortID{ids.GenerateTestShortID()}, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, preFundedKeys, - ids.ShortEmpty, - memoField, + common.WithMemo(memoField), ) require.NoError(t, err) @@ -1132,10 +1195,13 @@ func TestDurangoMemoField(t *testing.T) { tx, err := env.txBuilder.NewImportTx( sourceChain, - sourceKey.PublicKey().Address(), + &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{sourceKey.PublicKey().Address()}, + }, preFundedKeys, - ids.ShortEmpty, // change address - memoField, + common.WithMemo(memoField), ) require.NoError(t, err) @@ -1149,12 +1215,20 @@ func TestDurangoMemoField(t *testing.T) { name: "ExportTx", 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 + 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, - ids.ShortEmpty, // change address - memoField, + common.WithMemo(memoField), ) require.NoError(t, err) @@ -1182,14 +1256,16 @@ func TestDurangoMemoField(t *testing.T) { endTime := primaryValidator.EndTime subnetValTx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - 0, - uint64(endTime.Unix()), - primaryValidator.NodeID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: primaryValidator.NodeID, + Start: 0, + End: uint64(endTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(t, err) @@ -1206,8 +1282,7 @@ func TestDurangoMemoField(t *testing.T) { primaryValidator.NodeID, testSubnet1.ID(), preFundedKeys, - ids.ShortEmpty, - memoField, + common.WithMemo(memoField), ) require.NoError(t, err) @@ -1233,8 +1308,7 @@ func TestDurangoMemoField(t *testing.T) { 1, // max validator weight factor 80, // uptime requirement preFundedKeys, - ids.ShortEmpty, // change address - memoField, + common.WithMemo(memoField), ) require.NoError(t, err) @@ -1256,16 +1330,28 @@ func TestDurangoMemoField(t *testing.T) { require.NoError(t, err) tx, err := env.txBuilder.NewAddPermissionlessValidatorTx( - env.config.MinValidatorStake, - 0, // start Time - uint64(endTime.Unix()), - nodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: 0, + End: uint64(endTime.Unix()), + Wght: env.config.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - ids.ShortEmpty, // reward address - reward.PercentDenominator, // shares + env.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, + reward.PercentDenominator, preFundedKeys, - ids.ShortEmpty, // change address - memoField, + common.WithMemo(memoField), ) require.NoError(t, err) @@ -1292,14 +1378,22 @@ func TestDurangoMemoField(t *testing.T) { it.Release() tx, err := env.txBuilder.NewAddPermissionlessDelegatorTx( - defaultMinValidatorStake, - 0, // start Time - uint64(primaryValidator.EndTime.Unix()), - primaryValidator.NodeID, - ids.ShortEmpty, // reward address + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: primaryValidator.NodeID, + Start: 0, + End: uint64(primaryValidator.EndTime.Unix()), + Wght: defaultMinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, + env.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, preFundedKeys, - ids.ShortEmpty, // change address - memoField, + common.WithMemo(memoField), ) require.NoError(t, err) @@ -1314,11 +1408,12 @@ func TestDurangoMemoField(t *testing.T) { setupTest: func(env *environment, memoField []byte) (*txs.Tx, state.Diff) { tx, err := env.txBuilder.NewTransferSubnetOwnershipTx( testSubnet1.TxID, - 1, - []ids.ShortID{ids.ShortEmpty}, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }, preFundedKeys, - ids.ShortEmpty, // change address - memoField, + common.WithMemo(memoField), ) require.NoError(t, err) @@ -1332,14 +1427,20 @@ func TestDurangoMemoField(t *testing.T) { name: "BaseTx", 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}, + []*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, - ids.ShortEmpty, - memoField, + common.WithMemo(memoField), ) require.NoError(t, err) diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 83b99578523..b47ce43958e 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -44,10 +44,12 @@ 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/secp256k1fx" 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" + walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) const ( @@ -264,14 +266,20 @@ func addSubnetValidator(vm *VM, data *validatorInputData, subnetID ids.ID) (*sta addr := keys[0].PublicKey().Address() signedTx, err := txBuilder.NewAddSubnetValidatorTx( - vm.Config.MinValidatorStake, - uint64(data.startTime.Unix()), - uint64(data.endTime.Unix()), - data.nodeID, - subnetID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: data.nodeID, + Start: uint64(data.startTime.Unix()), + End: uint64(data.endTime.Unix()), + Wght: vm.Config.MinValidatorStake, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - addr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) if err != nil { return nil, fmt.Errorf("could not create AddSubnetValidatorTx: %w", err) @@ -295,16 +303,31 @@ func addPrimaryValidatorWithBLSKey(vm *VM, data *validatorInputData) (*state.Sta ) signedTx, err := txBuilder.NewAddPermissionlessValidatorTx( - vm.Config.MinValidatorStake, - uint64(data.startTime.Unix()), - uint64(data.endTime.Unix()), - data.nodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: data.nodeID, + Start: uint64(data.startTime.Unix()), + End: uint64(data.endTime.Unix()), + Wght: vm.Config.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - addr, + vm.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, - addr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) if err != nil { return nil, fmt.Errorf("could not create AddPermissionlessValidatorTx: %w", err) @@ -703,11 +726,15 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { // Note: following Banff activation, block acceptance will move // chain time ahead testSubnet1, err = txBuilder.NewCreateSubnetTx( - 1, // threshold - []ids.ShortID{keys[0].PublicKey().Address()}, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{keys[len(keys)-1]}, // pays tx fee - keys[0].PublicKey().Address(), // change addr - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) 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 9d2afc070df..cabbf583dd2 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -48,6 +48,7 @@ import ( blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" + walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { @@ -64,15 +65,22 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { // create valid tx addValidatorTx, err := txBuilder.NewAddValidatorTx( - vm.MinValidatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, - changeAddr, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: vm.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -100,14 +108,21 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { // create valid tx addFirstDelegatorTx, err := txBuilder.NewAddDelegatorTx( - 4*vm.MinValidatorStake, // maximum amount of stake this delegator can provide - uint64(firstDelegatorStartTime.Unix()), - uint64(firstDelegatorEndTime.Unix()), - nodeID, - changeAddr, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(firstDelegatorStartTime.Unix()), + End: uint64(firstDelegatorEndTime.Unix()), + Wght: 4 * vm.MinValidatorStake, // maximum amount of stake this delegator can provide + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -137,14 +152,21 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { // create valid tx addSecondDelegatorTx, err := txBuilder.NewAddDelegatorTx( - vm.MinDelegatorStake, - uint64(secondDelegatorStartTime.Unix()), - uint64(secondDelegatorEndTime.Unix()), - nodeID, - changeAddr, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(secondDelegatorStartTime.Unix()), + End: uint64(secondDelegatorEndTime.Unix()), + Wght: vm.MinDelegatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }, []*secp256k1.PrivateKey{keys[0], keys[1], keys[3]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -164,14 +186,21 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { // create valid tx addThirdDelegatorTx, err := txBuilder.NewAddDelegatorTx( - vm.MinDelegatorStake, - uint64(thirdDelegatorStartTime.Unix()), - uint64(thirdDelegatorEndTime.Unix()), - nodeID, - changeAddr, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(thirdDelegatorStartTime.Unix()), + End: uint64(thirdDelegatorEndTime.Unix()), + Wght: vm.MinDelegatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }, []*secp256k1.PrivateKey{keys[0], keys[1], keys[4]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -236,15 +265,22 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { // create valid tx addValidatorTx, err := txBuilder.NewAddValidatorTx( - validatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, - id, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: validatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{id}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -262,14 +298,21 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { // create valid tx addFirstDelegatorTx, err := txBuilder.NewAddDelegatorTx( - delegator1Stake, - uint64(delegator1StartTime.Unix()), - uint64(delegator1EndTime.Unix()), - nodeID, - keys[0].PublicKey().Address(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(delegator1StartTime.Unix()), + End: uint64(delegator1EndTime.Unix()), + Wght: delegator1Stake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -287,14 +330,21 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { // create valid tx addSecondDelegatorTx, err := txBuilder.NewAddDelegatorTx( - delegator2Stake, - uint64(delegator2StartTime.Unix()), - uint64(delegator2EndTime.Unix()), - nodeID, - keys[0].PublicKey().Address(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(delegator2StartTime.Unix()), + End: uint64(delegator2EndTime.Unix()), + Wght: delegator2Stake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -312,14 +362,21 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { // create valid tx addThirdDelegatorTx, err := txBuilder.NewAddDelegatorTx( - delegator3Stake, - uint64(delegator3StartTime.Unix()), - uint64(delegator3EndTime.Unix()), - nodeID, - keys[0].PublicKey().Address(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(delegator3StartTime.Unix()), + End: uint64(delegator3EndTime.Unix()), + Wght: delegator3Stake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -337,14 +394,21 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { // create valid tx addFourthDelegatorTx, err := txBuilder.NewAddDelegatorTx( - delegator4Stake, - uint64(delegator4StartTime.Unix()), - uint64(delegator4EndTime.Unix()), - nodeID, - keys[0].PublicKey().Address(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(delegator4StartTime.Unix()), + End: uint64(delegator4EndTime.Unix()), + Wght: delegator4Stake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -426,29 +490,41 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { ) addSubnetTx0, err := txBuilder.NewCreateSubnetTx( - 1, - []ids.ShortID{addr0}, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr0}, + }, []*secp256k1.PrivateKey{key0}, - addr0, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr0}, + }), ) require.NoError(err) addSubnetTx1, err := txBuilder.NewCreateSubnetTx( - 1, - []ids.ShortID{addr1}, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr1}, + }, []*secp256k1.PrivateKey{key1}, - addr1, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr1}, + }), ) require.NoError(err) addSubnetTx2, err := txBuilder.NewCreateSubnetTx( - 1, - []ids.ShortID{addr1}, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr1}, + }, []*secp256k1.PrivateKey{key1}, - addr0, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr0}, + }), ) require.NoError(err) @@ -514,15 +590,18 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { // Create the tx to add a new validator addValidatorTx, err := txBuilder.NewAddValidatorTx( - vm.MinValidatorStake, - uint64(newValidatorStartTime.Unix()), - uint64(newValidatorEndTime.Unix()), - nodeID, - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(newValidatorStartTime.Unix()), + End: uint64(newValidatorEndTime.Unix()), + Wght: vm.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -723,15 +802,18 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { // Create the tx to add the first new validator addValidatorTx0, err := txBuilder.NewAddValidatorTx( - vm.MaxValidatorStake, - uint64(newValidatorStartTime0.Unix()), - uint64(newValidatorEndTime0.Unix()), - nodeID0, - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: nodeID0, + Start: uint64(newValidatorStartTime0.Unix()), + End: uint64(newValidatorEndTime0.Unix()), + Wght: vm.MaxValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -896,15 +978,18 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { // Create the tx to add the second new validator addValidatorTx1, err := txBuilder.NewAddValidatorTx( - vm.MaxValidatorStake, - uint64(newValidatorStartTime1.Unix()), - uint64(newValidatorEndTime1.Unix()), - nodeID1, - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: nodeID1, + Start: uint64(newValidatorStartTime1.Unix()), + End: uint64(newValidatorEndTime1.Unix()), + Wght: vm.MaxValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) @@ -1052,15 +1137,18 @@ func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { // Create the tx to add the first new validator addValidatorTx0, err := txBuilder.NewAddValidatorTx( - vm.MaxValidatorStake, - uint64(newValidatorStartTime0.Unix()), - uint64(newValidatorEndTime0.Unix()), - extraNodeID, - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: extraNodeID, + Start: uint64(newValidatorStartTime0.Unix()), + End: uint64(newValidatorEndTime0.Unix()), + Wght: vm.MaxValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - ids.GenerateTestShortID(), - nil, ) require.NoError(err) @@ -1174,15 +1262,22 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { // create valid tx addValidatorTx, err := txBuilder.NewAddValidatorTx( - validatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, - id, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: validatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{id}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -1200,14 +1295,21 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { // create valid tx addFirstDelegatorTx, err := txBuilder.NewAddDelegatorTx( - delegator1Stake, - uint64(delegator1StartTime.Unix()), - uint64(delegator1EndTime.Unix()), - nodeID, - keys[0].PublicKey().Address(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(delegator1StartTime.Unix()), + End: uint64(delegator1EndTime.Unix()), + Wght: delegator1Stake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -1225,14 +1327,21 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { // create valid tx addSecondDelegatorTx, err := txBuilder.NewAddDelegatorTx( - delegator2Stake, - uint64(delegator2StartTime.Unix()), - uint64(delegator2EndTime.Unix()), - nodeID, - keys[0].PublicKey().Address(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(delegator2StartTime.Unix()), + End: uint64(delegator2EndTime.Unix()), + Wght: delegator2Stake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -1262,15 +1371,22 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t changeAddr := keys[0].PublicKey().Address() addValidatorTx, err := txBuilder.NewAddValidatorTx( - defaultMaxValidatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, - id, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: defaultMaxValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{id}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -1286,11 +1402,15 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) createSubnetTx, err := txBuilder.NewCreateSubnetTx( - 1, - []ids.ShortID{changeAddr}, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -1306,14 +1426,20 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) addSubnetValidatorTx, err := txBuilder.NewAddSubnetValidatorTx( - defaultMaxValidatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, - createSubnetTx.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: defaultMaxValidatorStake, + }, + Subnet: createSubnetTx.ID(), + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -1340,8 +1466,10 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -1387,15 +1515,22 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t changeAddr := keys[0].PublicKey().Address() addValidatorTx, err := txBuilder.NewAddValidatorTx( - defaultMaxValidatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, - id, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: defaultMaxValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{id}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -1411,11 +1546,15 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) createSubnetTx, err := txBuilder.NewCreateSubnetTx( - 1, - []ids.ShortID{changeAddr}, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -1431,14 +1570,20 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) addSubnetValidatorTx, err := txBuilder.NewAddSubnetValidatorTx( - defaultMaxValidatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, - createSubnetTx.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: defaultMaxValidatorStake, + }, + Subnet: createSubnetTx.ID(), + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -1457,8 +1602,10 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -1514,16 +1661,31 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { // build primary network validator with BLS key primaryTx, err := txBuilder.NewAddPermissionlessValidatorTx( - vm.MinValidatorStake, - uint64(primaryStartTime.Unix()), - uint64(primaryEndTime.Unix()), - nodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(primaryStartTime.Unix()), + End: uint64(primaryEndTime.Unix()), + Wght: vm.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk1), - addr, // reward address + vm.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, reward.PercentDenominator, keys, - addr, // change address - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) require.NoError(err) uPrimaryTx := primaryTx.Unsigned.(*txs.AddPermissionlessValidatorTx) @@ -1547,14 +1709,20 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { // insert the subnet validator subnetTx, err := txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetStartTime.Unix()), // Start time - uint64(subnetEndTime.Unix()), // end time - nodeID, // Node ID - subnetID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(subnetStartTime.Unix()), + End: uint64(subnetEndTime.Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - addr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) require.NoError(err) @@ -1620,16 +1788,31 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NotEqual(sk1, sk2) primaryRestartTx, err := txBuilder.NewAddPermissionlessValidatorTx( - vm.MinValidatorStake, - uint64(primaryReStartTime.Unix()), - uint64(primaryReEndTime.Unix()), - nodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(primaryReStartTime.Unix()), + End: uint64(primaryReEndTime.Unix()), + Wght: vm.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk2), - addr, // reward address + vm.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, reward.PercentDenominator, keys, - addr, // change address - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) require.NoError(err) uPrimaryRestartTx := primaryRestartTx.Unsigned.(*txs.AddPermissionlessValidatorTx) @@ -1729,15 +1912,22 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { nodeID := ids.GenerateTestNodeID() addr := keys[0].PublicKey().Address() primaryTx1, err := txBuilder.NewAddValidatorTx( - vm.MinValidatorStake, - uint64(primaryStartTime1.Unix()), - uint64(primaryEndTime1.Unix()), - nodeID, - addr, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(primaryStartTime1.Unix()), + End: uint64(primaryEndTime1.Unix()), + Wght: vm.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - addr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) require.NoError(err) @@ -1790,16 +1980,31 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { require.NoError(err) primaryRestartTx, err := txBuilder.NewAddPermissionlessValidatorTx( - vm.MinValidatorStake, - uint64(primaryStartTime2.Unix()), - uint64(primaryEndTime2.Unix()), - nodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(primaryStartTime2.Unix()), + End: uint64(primaryEndTime2.Unix()), + Wght: vm.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk2), - addr, // reward address + vm.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, reward.PercentDenominator, keys, - addr, // change address - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) require.NoError(err) @@ -1862,15 +2067,22 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { nodeID := ids.GenerateTestNodeID() addr := keys[0].PublicKey().Address() primaryTx1, err := txBuilder.NewAddValidatorTx( - vm.MinValidatorStake, - uint64(primaryStartTime1.Unix()), - uint64(primaryEndTime1.Unix()), - nodeID, - addr, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(primaryStartTime1.Unix()), + End: uint64(primaryEndTime1.Unix()), + Wght: vm.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - addr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) require.NoError(err) @@ -1893,14 +2105,20 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { // insert the subnet validator subnetTx, err := txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetStartTime.Unix()), // Start time - uint64(subnetEndTime.Unix()), // end time - nodeID, // Node ID - subnetID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(subnetStartTime.Unix()), + End: uint64(subnetEndTime.Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - addr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) require.NoError(err) @@ -1965,16 +2183,31 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { require.NoError(err) primaryRestartTx, err := txBuilder.NewAddPermissionlessValidatorTx( - vm.MinValidatorStake, - uint64(primaryStartTime2.Unix()), - uint64(primaryEndTime2.Unix()), - nodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(primaryStartTime2.Unix()), + End: uint64(primaryEndTime2.Unix()), + Wght: vm.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk2), - addr, // reward address + vm.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, reward.PercentDenominator, keys, - addr, // change address - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) require.NoError(err) @@ -2044,15 +2277,22 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { nodeID := ids.GenerateTestNodeID() addr := keys[0].PublicKey().Address() primaryTx1, err := txBuilder.NewAddValidatorTx( - vm.MinValidatorStake, - uint64(primaryStartTime1.Unix()), - uint64(primaryEndTime1.Unix()), - nodeID, - addr, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(primaryStartTime1.Unix()), + End: uint64(primaryEndTime1.Unix()), + Wght: vm.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - addr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) require.NoError(err) @@ -2072,14 +2312,20 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { // insert the subnet validator subnetTx, err := txBuilder.NewAddSubnetValidatorTx( - 1, // Weight - uint64(subnetStartTime.Unix()), // Start time - uint64(subnetEndTime.Unix()), // end time - nodeID, // Node ID - subnetID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(subnetStartTime.Unix()), + End: uint64(subnetEndTime.Unix()), + Wght: 1, + }, + Subnet: subnetID, + }, []*secp256k1.PrivateKey{keys[0], keys[1]}, - addr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{addr}, + }), ) require.NoError(err) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index b55c543bb18..cbb1a44e8f4 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -69,6 +69,7 @@ import ( txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" + walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) const ( @@ -202,7 +203,7 @@ func defaultGenesis(t *testing.T, avaxAssetID ids.ID) (*api.BuildGenesisArgs, [] return &buildGenesisArgs, genesisBytes } -func defaultVM(t *testing.T, f fork) (*VM, txbuilder.Builder, database.Database, *mutableSharedMemory) { +func defaultVM(t *testing.T, f fork) (*VM, *txbuilder.Builder, database.Database, *mutableSharedMemory) { require := require.New(t) var ( apricotPhase3Time = mockable.MaxTime @@ -314,12 +315,19 @@ func defaultVM(t *testing.T, f fork) (*VM, txbuilder.Builder, database.Database, // chain time ahead var err error testSubnet1, err = builder.NewCreateSubnetTx( - 2, // threshold; 2 sigs from keys[0], keys[1], keys[2] needed to add validator to this subnet - // control keys are keys[0], keys[1], keys[2] - []ids.ShortID{keys[0].PublicKey().Address(), keys[1].PublicKey().Address(), keys[2].PublicKey().Address()}, + &secp256k1fx.OutputOwners{ + Threshold: 2, + Addrs: []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, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) require.NoError(err) vm.ctx.Lock.Unlock() @@ -413,16 +421,27 @@ func TestAddValidatorCommit(t *testing.T) { // create valid tx tx, err := txBuilder.NewAddPermissionlessValidatorTx( - vm.MinValidatorStake, - uint64(startTime.Unix()), - uint64(endTime.Unix()), - nodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: vm.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - rewardAddress, + vm.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -459,15 +478,18 @@ func TestInvalidAddValidatorCommit(t *testing.T) { // create invalid tx tx, err := txBuilder.NewAddValidatorTx( - vm.MinValidatorStake, - uint64(startTime.Unix()), - uint64(endTime.Unix()), - nodeID, - ids.GenerateTestShortID(), + &txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: vm.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -513,15 +535,18 @@ func TestAddValidatorReject(t *testing.T) { // create valid tx tx, err := txBuilder.NewAddValidatorTx( - vm.MinValidatorStake, - uint64(startTime.Unix()), - uint64(endTime.Unix()), - nodeID, - rewardAddress, + &txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: vm.MinValidatorStake, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardAddress}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -561,16 +586,27 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { // create valid tx tx, err := txBuilder.NewAddPermissionlessValidatorTx( - vm.MinValidatorStake, - uint64(startTime.Unix()), - uint64(endTime.Unix()), - repeatNodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: repeatNodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: vm.MinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - ids.GenerateTestShortID(), + vm.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.GenerateTestShortID()}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -598,14 +634,16 @@ func TestAddSubnetValidatorAccept(t *testing.T) { // note that [startTime, endTime] is a subset of time that keys[0] // validates primary network ([defaultValidateStartTime, defaultValidateEndTime]) tx, err := txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(startTime.Unix()), - uint64(endTime.Unix()), - nodeID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -646,14 +684,16 @@ func TestAddSubnetValidatorReject(t *testing.T) { // note that [startTime, endTime] is a subset of time that keys[0] // validates primary network ([defaultValidateStartTime, defaultValidateEndTime]) tx, err := txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(startTime.Unix()), - uint64(endTime.Unix()), - nodeID, - testSubnet1.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: defaultWeight, + }, + Subnet: testSubnet1.ID(), + }, []*secp256k1.PrivateKey{testSubnet1ControlKeys[1], testSubnet1ControlKeys[2]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -839,8 +879,6 @@ func TestCreateChain(t *testing.T) { nil, "name", []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -884,14 +922,18 @@ func TestCreateSubnet(t *testing.T) { nodeID := genesisNodeIDs[0] createSubnetTx, err := txBuilder.NewCreateSubnetTx( - 1, // threshold - []ids.ShortID{ // control keys - keys[0].PublicKey().Address(), - keys[1].PublicKey().Address(), + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keys[0].PublicKey().Address(), + keys[1].PublicKey().Address(), + }, }, []*secp256k1.PrivateKey{keys[0]}, // payer - keys[0].PublicKey().Address(), // change addr - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) require.NoError(err) @@ -928,14 +970,16 @@ func TestCreateSubnet(t *testing.T) { endTime := startTime.Add(defaultMinStakingDuration) // [startTime, endTime] is subset of time keys[0] validates default subnet so tx is valid addValidatorTx, err := txBuilder.NewAddSubnetValidatorTx( - defaultWeight, - uint64(startTime.Unix()), - uint64(endTime.Unix()), - nodeID, - createSubnetTx.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: defaultWeight, + }, + Subnet: createSubnetTx.ID(), + }, []*secp256k1.PrivateKey{keys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -996,10 +1040,12 @@ func TestAtomicImport(t *testing.T) { _, err := txBuilder.NewImportTx( vm.ctx.XChainID, - recipientKey.PublicKey().Address(), + &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{recipientKey.PublicKey().Address()}, + }, []*secp256k1.PrivateKey{keys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.ErrorIs(err, walletbuilder.ErrInsufficientFunds) @@ -1036,10 +1082,12 @@ func TestAtomicImport(t *testing.T) { tx, err := txBuilder.NewImportTx( vm.ctx.XChainID, - recipientKey.PublicKey().Address(), + &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{recipientKey.PublicKey().Address()}, + }, []*secp256k1.PrivateKey{recipientKey}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -2030,16 +2078,31 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { require.NoError(err) addValidatorTx, err := txBuilder.NewAddPermissionlessValidatorTx( - defaultMaxValidatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: defaultMaxValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - id, + vm.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{id}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{id}, + }, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, - keys[0].Address(), - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) require.NoError(err) @@ -2055,11 +2118,15 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) createSubnetTx, err := txBuilder.NewCreateSubnetTx( - 1, - []ids.ShortID{id}, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{id}, + }, []*secp256k1.PrivateKey{keys[0]}, - keys[0].Address(), - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) require.NoError(err) @@ -2075,14 +2142,20 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) addSubnetValidatorTx, err := txBuilder.NewAddSubnetValidatorTx( - defaultMaxValidatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - nodeID, - createSubnetTx.ID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(validatorStartTime.Unix()), + End: uint64(validatorEndTime.Unix()), + Wght: defaultMaxValidatorStake, + }, + Subnet: createSubnetTx.ID(), + }, []*secp256k1.PrivateKey{key, keys[1]}, - keys[1].Address(), - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[1].PublicKey().Address()}, + }), ) require.NoError(err) @@ -2090,8 +2163,10 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{key, keys[2]}, - keys[2].Address(), - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[2].PublicKey().Address()}, + }), ) require.NoError(err) @@ -2125,11 +2200,15 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { // Create a subnet createSubnetTx, err := txBuilder.NewCreateSubnetTx( - 1, - []ids.ShortID{keys[0].PublicKey().Address()}, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{keys[0]}, - keys[0].Address(), - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, + }), ) require.NoError(err) subnetID := createSubnetTx.ID() @@ -2164,11 +2243,11 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { transferSubnetOwnershipTx, err := txBuilder.NewTransferSubnetOwnershipTx( subnetID, - 1, - []ids.ShortID{keys[1].PublicKey().Address()}, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[1].PublicKey().Address()}, + }, []*secp256k1.PrivateKey{keys[0]}, - ids.ShortEmpty, // change addr - nil, ) require.NoError(err) @@ -2209,16 +2288,25 @@ func TestBaseTx(t *testing.T) { changeAddr := ids.ShortEmpty baseTx, err := txBuilder.NewBaseTx( - sendAmt, - secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keys[1].Address(), + []*avax.TransferableOutput{ + { + Asset: avax.Asset{ID: vm.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: sendAmt, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keys[1].Address(), + }, + }, + }, }, }, []*secp256k1.PrivateKey{keys[0]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -2285,16 +2373,25 @@ func TestPruneMempool(t *testing.T) { changeAddr := ids.ShortEmpty baseTx, err := txBuilder.NewBaseTx( - sendAmt, - secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keys[1].Address(), + []*avax.TransferableOutput{ + { + Asset: avax.Asset{ID: vm.ctx.AVAXAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: sendAmt, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keys[1].Address(), + }, + }, + }, }, }, []*secp256k1.PrivateKey{keys[0]}, - changeAddr, - nil, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{changeAddr}, + }), ) require.NoError(err) @@ -2317,16 +2414,27 @@ func TestPruneMempool(t *testing.T) { require.NoError(err) addValidatorTx, err := txBuilder.NewAddPermissionlessValidatorTx( - defaultMinValidatorStake, - uint64(startTime.Unix()), - uint64(endTime.Unix()), - ids.GenerateTestNodeID(), + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: defaultMinValidatorStake, + }, + Subnet: constants.PrimaryNetworkID, + }, signer.NewProofOfPossession(sk), - keys[2].Address(), + vm.ctx.AVAXAssetID, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[2].Address()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{keys[2].Address()}, + }, 20000, []*secp256k1.PrivateKey{keys[1]}, - ids.ShortEmpty, - nil, ) require.NoError(err) From fe8c795ca0b239d5ed7d21795fc9b40af4a1bf0d Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:58:45 -0400 Subject: [PATCH 37/51] remove config from backend --- vms/platformvm/txs/builder/backend.go | 4 ---- vms/platformvm/txs/builder/builder.go | 6 ++++-- vms/platformvm/txs/executor/create_chain_test.go | 2 +- vms/platformvm/txs/executor/create_subnet_test.go | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/vms/platformvm/txs/builder/backend.go b/vms/platformvm/txs/builder/backend.go index 4fb4d890444..d41cb7dc7a8 100644 --- a/vms/platformvm/txs/builder/backend.go +++ b/vms/platformvm/txs/builder/backend.go @@ -12,7 +12,6 @@ import ( "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/signer" @@ -26,19 +25,16 @@ var ( ) func NewBackend( - cfg *config.Config, state state.State, atomicUTXOsMan avax.AtomicUTXOManager, ) *Backend { return &Backend{ - cfg: cfg, state: state, atomicUTXOsMan: atomicUTXOsMan, } } type Backend struct { - cfg *config.Config addrs set.Set[ids.ShortID] state state.State atomicUTXOsMan avax.AtomicUTXOManager diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 5e645388274..292cae567f3 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -34,12 +34,14 @@ func New( ) *Builder { return &Builder{ ctx: ctx, - backend: NewBackend(cfg, state, atomicUTXOManager), + cfg: cfg, + backend: NewBackend(state, atomicUTXOManager), } } type Builder struct { ctx *snow.Context + cfg *config.Config backend *Backend } @@ -343,7 +345,7 @@ func (b *Builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, var ( kc = secp256k1fx.NewKeychain(keys...) addrs = kc.Addresses() - context = NewContext(b.ctx, b.backend.cfg, b.backend.state.GetTimestamp()) + context = NewContext(b.ctx, b.cfg, b.backend.state.GetTimestamp()) builder = walletbuilder.New(addrs, context, b.backend) signer = walletsigner.New(kc, b.backend) ) diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 176e6b80615..bb0cb85467c 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) { cfg := *env.config cfg.CreateBlockchainTxFee = test.fee builderContext := vmbuilder.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) - backend := vmbuilder.NewBackend(&cfg, env.state, env.atomicUTXOs) + backend := vmbuilder.NewBackend(env.state, env.atomicUTXOs) backend.ResetAddresses(addrs) pBuilder := walletbuilder.New(addrs, builderContext, backend) diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index bcf9a6b2e6d..46c1a285c33 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -68,7 +68,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateSubnetTxFee = test.fee builderContext := vmbuilder.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) - backend := vmbuilder.NewBackend(&cfg, env.state, env.atomicUTXOs) + backend := vmbuilder.NewBackend(env.state, env.atomicUTXOs) backend.ResetAddresses(addrs) pBuilder := walletbuilder.New(addrs, builderContext, backend) From 3f7291fbd9a2161b1183deb85671eff82d35ee42 Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:54:58 -0400 Subject: [PATCH 38/51] nit --- vms/platformvm/txs/executor/import_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index d70b7828d67..4ae35d80ae0 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -107,7 +107,6 @@ func TestNewImportTx(t *testing.T) { } to := &secp256k1fx.OutputOwners{ - Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{ids.GenerateTestShortID()}, } From 1cddffcba6574b5d4c979680a7c9c85b349b580e Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:56:59 -0400 Subject: [PATCH 39/51] nit --- vms/platformvm/txs/executor/reward_validator_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vms/platformvm/txs/executor/reward_validator_test.go b/vms/platformvm/txs/executor/reward_validator_test.go index 0e5a901e9a0..215e9a6f729 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -241,10 +241,10 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { vdrTx, err := env.txBuilder.NewAddValidatorTx( &txs.Validator{ - NodeID: vdrNodeID, // node ID + NodeID: vdrNodeID, Start: vdrStartTime, End: vdrEndTime, - Wght: env.config.MinValidatorStake, // stakeAmt + Wght: env.config.MinValidatorStake, }, &secp256k1fx.OutputOwners{ Threshold: 1, From af093c93cf27f216f096100916f6667a431f3d03 Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:57:43 -0400 Subject: [PATCH 40/51] nit --- vms/platformvm/block/builder/standard_block_test.go | 1 - vms/platformvm/service_test.go | 1 - vms/platformvm/vm_test.go | 2 -- 3 files changed, 4 deletions(-) diff --git a/vms/platformvm/block/builder/standard_block_test.go b/vms/platformvm/block/builder/standard_block_test.go index 55c76bd7c58..8606163990e 100644 --- a/vms/platformvm/block/builder/standard_block_test.go +++ b/vms/platformvm/block/builder/standard_block_test.go @@ -65,7 +65,6 @@ func TestAtomicTxImports(t *testing.T) { tx, err := env.txBuilder.NewImportTx( env.ctx.XChainID, &secp256k1fx.OutputOwners{ - Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{recipientKey.PublicKey().Address()}, }, diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index a14a0d47f70..9774ab55f50 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -170,7 +170,6 @@ func TestGetTxStatus(t *testing.T) { tx, err := txBuilder.NewImportTx( service.vm.ctx.XChainID, &secp256k1fx.OutputOwners{ - Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{ids.ShortEmpty}, }, diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index cbb1a44e8f4..a93ab355a73 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1041,7 +1041,6 @@ func TestAtomicImport(t *testing.T) { _, err := txBuilder.NewImportTx( vm.ctx.XChainID, &secp256k1fx.OutputOwners{ - Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{recipientKey.PublicKey().Address()}, }, @@ -1083,7 +1082,6 @@ func TestAtomicImport(t *testing.T) { tx, err := txBuilder.NewImportTx( vm.ctx.XChainID, &secp256k1fx.OutputOwners{ - Locktime: 0, Threshold: 1, Addrs: []ids.ShortID{recipientKey.PublicKey().Address()}, }, From b0ec09baabd926fef463645a2511eeceea43ce15 Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:07:16 -0400 Subject: [PATCH 41/51] nit --- vms/platformvm/txs/builder/backend.go | 6 ++---- vms/platformvm/txs/builder/builder.go | 5 +++-- vms/platformvm/txs/executor/create_chain_test.go | 3 +-- vms/platformvm/txs/executor/create_subnet_test.go | 3 +-- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/vms/platformvm/txs/builder/backend.go b/vms/platformvm/txs/builder/backend.go index d41cb7dc7a8..828c3f5918e 100644 --- a/vms/platformvm/txs/builder/backend.go +++ b/vms/platformvm/txs/builder/backend.go @@ -25,10 +25,12 @@ var ( ) func NewBackend( + addrs set.Set[ids.ShortID], state state.State, atomicUTXOsMan avax.AtomicUTXOManager, ) *Backend { return &Backend{ + addrs: addrs, state: state, atomicUTXOsMan: atomicUTXOsMan, } @@ -40,10 +42,6 @@ type Backend struct { atomicUTXOsMan avax.AtomicUTXOManager } -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) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 292cae567f3..7f44d0e4234 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -11,6 +11,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "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/state" @@ -35,7 +36,7 @@ func New( return &Builder{ ctx: ctx, cfg: cfg, - backend: NewBackend(state, atomicUTXOManager), + backend: NewBackend(set.Set[ids.ShortID]{}, state, atomicUTXOManager), } } @@ -349,7 +350,7 @@ func (b *Builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, builder = walletbuilder.New(addrs, context, b.backend) signer = walletsigner.New(kc, b.backend) ) - b.backend.ResetAddresses(addrs) + b.backend.addrs = addrs return builder, signer } diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index bb0cb85467c..6eb6f13bbcd 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -201,8 +201,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateBlockchainTxFee = test.fee builderContext := vmbuilder.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) - backend := vmbuilder.NewBackend(env.state, env.atomicUTXOs) - backend.ResetAddresses(addrs) + backend := vmbuilder.NewBackend(addrs, env.state, env.atomicUTXOs) pBuilder := walletbuilder.New(addrs, builderContext, 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 46c1a285c33..a24210de9d7 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -68,8 +68,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateSubnetTxFee = test.fee builderContext := vmbuilder.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) - backend := vmbuilder.NewBackend(env.state, env.atomicUTXOs) - backend.ResetAddresses(addrs) + backend := vmbuilder.NewBackend(addrs, env.state, env.atomicUTXOs) pBuilder := walletbuilder.New(addrs, builderContext, backend) utx, err := pBuilder.NewCreateSubnetTx( From f8af011d3befb56cea6466f27d9ffa11ba700527 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 28 Mar 2024 14:06:22 +0100 Subject: [PATCH 42/51] nit to restore stakers order in UT --- .../block/executor/proposal_block_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 11fb2f571ec..e4d17210452 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -28,6 +28,8 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + + walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) func TestApricotProposalBlockTimeVerification(t *testing.T) { @@ -547,6 +549,10 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }), ) require.NoError(err) @@ -573,6 +579,10 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { Subnet: subnetID, }, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }), ) require.NoError(err) @@ -606,6 +616,10 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }), ) require.NoError(err) @@ -774,6 +788,10 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { }, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, + walletcommon.WithChangeOwner(&secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ids.ShortEmpty}, + }), ) require.NoError(err) From 6fd25ec66f527d773ad5912adc58976867610e87 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 28 Mar 2024 14:23:13 +0100 Subject: [PATCH 43/51] nit --- vms/platformvm/block/executor/proposal_block_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index e4d17210452..0436251e999 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -368,7 +368,8 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { // The order in which they do it is asserted; the order may depend on the staker.TxID, // which in turns depend on every feature of the transaction creating the staker. // So in this test we avoid ids.GenerateTestNodeID, in favour of ids.BuildTestNodeID - // so that TxID does not depend on the order we run tests. + // so that TxID does not depend on the order we run tests. We also explicitly declare + // the change address, to avoid picking a random one in case multiple funding keys are set. staker0 := staker{ nodeID: ids.BuildTestNodeID([]byte{0xf0}), rewardAddress: ids.ShortID{0xf0}, From 42b556dc4606f7b1b86f0b69c934a0b6d1e4f839 Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 28 Mar 2024 15:06:36 -0400 Subject: [PATCH 44/51] nit --- vms/platformvm/txs/builder/builder.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 7f44d0e4234..71ac889d6e1 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -11,7 +11,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "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/state" @@ -34,16 +33,18 @@ func New( atomicUTXOManager avax.AtomicUTXOManager, ) *Builder { return &Builder{ - ctx: ctx, - cfg: cfg, - backend: NewBackend(set.Set[ids.ShortID]{}, state, atomicUTXOManager), + ctx: ctx, + cfg: cfg, + state: state, + atomicUTXOManager: atomicUTXOManager, } } type Builder struct { - ctx *snow.Context - cfg *config.Config - backend *Backend + ctx *snow.Context + cfg *config.Config + state state.State + atomicUTXOManager avax.AtomicUTXOManager } func (b *Builder) NewImportTx( @@ -346,11 +347,11 @@ func (b *Builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, var ( kc = secp256k1fx.NewKeychain(keys...) addrs = kc.Addresses() - context = NewContext(b.ctx, b.cfg, b.backend.state.GetTimestamp()) - builder = walletbuilder.New(addrs, context, b.backend) - signer = walletsigner.New(kc, b.backend) + backend = NewBackend(addrs, b.state, b.atomicUTXOManager) + context = NewContext(b.ctx, b.cfg, backend.state.GetTimestamp()) + builder = walletbuilder.New(addrs, context, backend) + signer = walletsigner.New(kc, backend) ) - b.backend.addrs = addrs return builder, signer } From 0d157f8130b82f8b79c8ed65cb977814da379dc5 Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 28 Mar 2024 15:32:29 -0400 Subject: [PATCH 45/51] nits --- vms/platformvm/service.go | 8 +++++--- vms/platformvm/txs/builder/backend.go | 5 +++-- vms/platformvm/txs/builder/builder.go | 3 --- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index 8ef46eef265..6c0004404b3 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -36,7 +36,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/builder" "github.com/ava-labs/avalanchego/vms/secp256k1fx" avajson "github.com/ava-labs/avalanchego/utils/json" @@ -51,6 +50,9 @@ const ( // Max number of addresses that can be passed in as argument to GetStake maxGetStakeAddrs = 256 + // Max number of items allowed in a page + maxPageSize = 1024 + // Note: Staker attributes cache should be large enough so that no evictions // happen when the API loops through all stakers. stakerAttributesCacheSize = 100_000 @@ -366,8 +368,8 @@ func (s *Service) GetUTXOs(_ *http.Request, args *api.GetUTXOsArgs, response *ap endUTXOID ids.ID ) limit := int(args.Limit) - if limit <= 0 || builder.MaxPageSize < limit { - limit = builder.MaxPageSize + if limit <= 0 || maxPageSize < limit { + limit = maxPageSize } s.vm.ctx.Lock.Lock() diff --git a/vms/platformvm/txs/builder/backend.go b/vms/platformvm/txs/builder/backend.go index 828c3f5918e..00d882583e1 100644 --- a/vms/platformvm/txs/builder/backend.go +++ b/vms/platformvm/txs/builder/backend.go @@ -6,6 +6,7 @@ package builder import ( "context" "fmt" + "math" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" @@ -47,7 +48,7 @@ func (b *Backend) UTXOs(_ context.Context, sourceChainID ids.ID) ([]*avax.UTXO, return avax.GetAllUTXOs(b.state, b.addrs) } - atomicUTXOs, _, _, err := b.atomicUTXOsMan.GetAtomicUTXOs(sourceChainID, b.addrs, ids.ShortEmpty, ids.Empty, MaxPageSize) + atomicUTXOs, _, _, err := b.atomicUTXOsMan.GetAtomicUTXOs(sourceChainID, b.addrs, ids.ShortEmpty, ids.Empty, math.MaxInt) return atomicUTXOs, err } @@ -56,7 +57,7 @@ func (b *Backend) GetUTXO(_ context.Context, chainID, utxoID ids.ID) (*avax.UTXO return b.state.GetUTXO(utxoID) } - atomicUTXOs, _, _, err := b.atomicUTXOsMan.GetAtomicUTXOs(chainID, b.addrs, ids.ShortEmpty, ids.Empty, MaxPageSize) + atomicUTXOs, _, _, err := b.atomicUTXOsMan.GetAtomicUTXOs(chainID, b.addrs, ids.ShortEmpty, utxoID, 2) if err != nil { return nil, fmt.Errorf("problem retrieving atomic UTXOs: %w", err) } diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 71ac889d6e1..3cc34603f5e 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -23,9 +23,6 @@ import ( walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) -// Max number of items allowed in a page -const MaxPageSize = 1024 - func New( ctx *snow.Context, cfg *config.Config, From cd97be6cb6d00f551bfd28d46a7381713556310d Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 28 Mar 2024 16:00:08 -0400 Subject: [PATCH 46/51] nit --- vms/platformvm/block/builder/helpers_test.go | 1 - vms/platformvm/block/executor/helpers_test.go | 2 - vms/platformvm/txs/builder/backend.go | 61 +++++++++++++------ vms/platformvm/txs/builder/builder.go | 17 +++--- .../txs/executor/create_chain_test.go | 2 +- .../txs/executor/create_subnet_test.go | 2 +- vms/platformvm/txs/executor/helpers_test.go | 1 - vms/platformvm/validator_set_property_test.go | 4 -- vms/platformvm/vm_regression_test.go | 1 - vms/platformvm/vm_test.go | 1 - 10 files changed, 53 insertions(+), 39 deletions(-) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 0e32af73d31..73b552e0962 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -158,7 +158,6 @@ func newEnvironment(t *testing.T, f fork) *environment { //nolint:unparam res.ctx, res.config, res.state, - res.atomicUTXOs, ) genesisID := res.state.GetLastAccepted() diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 167611e3c57..454824288ec 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -163,7 +163,6 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment res.ctx, res.config, res.state, - res.atomicUTXOs, ) } else { genesisBlkID = ids.GenerateTestID() @@ -175,7 +174,6 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment res.ctx, res.config, res.mockedState, - res.atomicUTXOs, ) // setup expectations strictly needed for environment creation diff --git a/vms/platformvm/txs/builder/backend.go b/vms/platformvm/txs/builder/backend.go index 00d882583e1..7f5b444ab2c 100644 --- a/vms/platformvm/txs/builder/backend.go +++ b/vms/platformvm/txs/builder/backend.go @@ -8,13 +8,14 @@ import ( "fmt" "math" - "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/chains/atomic" "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/vms/platformvm/txs" "github.com/ava-labs/avalanchego/wallet/chain/p/signer" walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" @@ -28,19 +29,19 @@ var ( func NewBackend( addrs set.Set[ids.ShortID], state state.State, - atomicUTXOsMan avax.AtomicUTXOManager, + sharedMemory atomic.SharedMemory, ) *Backend { return &Backend{ - addrs: addrs, - state: state, - atomicUTXOsMan: atomicUTXOsMan, + addrs: addrs, + state: state, + sharedMemory: sharedMemory, } } type Backend struct { - addrs set.Set[ids.ShortID] - state state.State - atomicUTXOsMan avax.AtomicUTXOManager + addrs set.Set[ids.ShortID] + state state.State + sharedMemory atomic.SharedMemory } func (b *Backend) UTXOs(_ context.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) { @@ -48,8 +49,34 @@ func (b *Backend) UTXOs(_ context.Context, sourceChainID ids.ID) ([]*avax.UTXO, return avax.GetAllUTXOs(b.state, b.addrs) } - atomicUTXOs, _, _, err := b.atomicUTXOsMan.GetAtomicUTXOs(sourceChainID, b.addrs, ids.ShortEmpty, ids.Empty, math.MaxInt) - return atomicUTXOs, err + addrsList := make([][]byte, b.addrs.Len()) + i := 0 + for addr := range b.addrs { + copied := addr + addrsList[i] = copied[:] + i++ + } + + allUTXOBytes, _, _, err := b.sharedMemory.Indexed( + sourceChainID, + addrsList, + ids.ShortEmpty[:], + ids.Empty[:], + math.MaxInt, + ) + if err != nil { + return nil, fmt.Errorf("error fetching atomic UTXOs: %w", err) + } + + utxos := make([]*avax.UTXO, len(allUTXOBytes)) + for i, utxoBytes := range allUTXOBytes { + utxo := &avax.UTXO{} + if _, err := txs.Codec.Unmarshal(utxoBytes, utxo); err != nil { + return nil, fmt.Errorf("error parsing UTXO: %w", err) + } + utxos[i] = utxo + } + return utxos, nil } func (b *Backend) GetUTXO(_ context.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) { @@ -57,16 +84,16 @@ func (b *Backend) GetUTXO(_ context.Context, chainID, utxoID ids.ID) (*avax.UTXO return b.state.GetUTXO(utxoID) } - atomicUTXOs, _, _, err := b.atomicUTXOsMan.GetAtomicUTXOs(chainID, b.addrs, ids.ShortEmpty, utxoID, 2) + utxoBytes, err := b.sharedMemory.Get(chainID, [][]byte{utxoID[:]}) if err != nil { - return nil, fmt.Errorf("problem retrieving atomic UTXOs: %w", err) + return nil, err } - for _, utxo := range atomicUTXOs { - if utxo.InputID() == utxoID { - return utxo, nil - } + + utxo := avax.UTXO{} + if _, err := txs.Codec.Unmarshal(utxoBytes[0], &utxo); err != nil { + return nil, err } - return nil, database.ErrNotFound + return &utxo, nil } func (b *Backend) GetSubnetOwner(_ context.Context, subnetID ids.ID) (fx.Owner, error) { diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 3cc34603f5e..3afecfe0e50 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -27,21 +27,18 @@ func New( ctx *snow.Context, cfg *config.Config, state state.State, - atomicUTXOManager avax.AtomicUTXOManager, ) *Builder { return &Builder{ - ctx: ctx, - cfg: cfg, - state: state, - atomicUTXOManager: atomicUTXOManager, + ctx: ctx, + cfg: cfg, + state: state, } } type Builder struct { - ctx *snow.Context - cfg *config.Config - state state.State - atomicUTXOManager avax.AtomicUTXOManager + ctx *snow.Context + cfg *config.Config + state state.State } func (b *Builder) NewImportTx( @@ -344,7 +341,7 @@ func (b *Builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, var ( kc = secp256k1fx.NewKeychain(keys...) addrs = kc.Addresses() - backend = NewBackend(addrs, b.state, b.atomicUTXOManager) + backend = NewBackend(addrs, b.state, b.ctx.SharedMemory) context = NewContext(b.ctx, b.cfg, backend.state.GetTimestamp()) builder = walletbuilder.New(addrs, context, backend) signer = walletsigner.New(kc, backend) diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 6eb6f13bbcd..cd65a7098bd 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) { cfg := *env.config cfg.CreateBlockchainTxFee = test.fee builderContext := vmbuilder.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) - backend := vmbuilder.NewBackend(addrs, env.state, env.atomicUTXOs) + backend := vmbuilder.NewBackend(addrs, env.state, env.msm) pBuilder := walletbuilder.New(addrs, builderContext, 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 a24210de9d7..54c9cde5294 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -68,7 +68,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateSubnetTxFee = test.fee builderContext := vmbuilder.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) - backend := vmbuilder.NewBackend(addrs, env.state, env.atomicUTXOs) + backend := vmbuilder.NewBackend(addrs, env.state, env.msm) pBuilder := walletbuilder.New(addrs, builderContext, backend) utx, err := pBuilder.NewCreateSubnetTx( diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index e6b522fd539..aabb8df5d53 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -149,7 +149,6 @@ func newEnvironment(t *testing.T, f fork) *environment { ctx, config, baseState, - atomicUTXOs, ) backend := Backend{ diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index b47ce43958e..0bb3a751e9d 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -36,7 +36,6 @@ import ( "github.com/ava-labs/avalanchego/utils/json" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/config" @@ -261,7 +260,6 @@ func addSubnetValidator(vm *VM, data *validatorInputData, subnetID ids.ID) (*sta vm.ctx, &vm.Config, vm.state, - avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), ) addr := keys[0].PublicKey().Address() @@ -299,7 +297,6 @@ func addPrimaryValidatorWithBLSKey(vm *VM, data *validatorInputData) (*state.Sta vm.ctx, &vm.Config, vm.state, - avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), ) signedTx, err := txBuilder.NewAddPermissionlessValidatorTx( @@ -719,7 +716,6 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { vm.ctx, &vm.Config, vm.state, - avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), ) // Create a subnet and store it in testSubnet1 diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index cabbf583dd2..919ccad13ee 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -486,7 +486,6 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { vm.ctx, &vm.Config, vm.state, - avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), ) addSubnetTx0, err := txBuilder.NewCreateSubnetTx( diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index a93ab355a73..62630883ddf 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -307,7 +307,6 @@ func defaultVM(t *testing.T, f fork) (*VM, *txbuilder.Builder, database.Database ctx, &vm.Config, vm.state, - avax.NewAtomicUTXOManager(vm.ctx.SharedMemory, txs.Codec), ) // Create a subnet and store it in testSubnet1 From cd105df17a6e884d08f5d1ea5465d65acaa0c36f Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 28 Mar 2024 16:08:57 -0400 Subject: [PATCH 47/51] `txstest` --- vms/platformvm/block/builder/helpers_test.go | 6 +++--- vms/platformvm/block/executor/helpers_test.go | 8 ++++---- vms/platformvm/service_test.go | 12 ++++++------ vms/platformvm/txs/executor/create_chain_test.go | 6 +++--- vms/platformvm/txs/executor/create_subnet_test.go | 6 +++--- vms/platformvm/txs/executor/helpers_test.go | 8 ++++---- vms/platformvm/txs/{builder => txstest}/backend.go | 2 +- vms/platformvm/txs/{builder => txstest}/builder.go | 4 ++-- vms/platformvm/txs/{builder => txstest}/context.go | 2 +- vms/platformvm/validator_set_property_test.go | 8 ++++---- vms/platformvm/vm_regression_test.go | 4 ++-- vms/platformvm/vm_test.go | 6 +++--- 12 files changed, 36 insertions(+), 36 deletions(-) rename vms/platformvm/txs/{builder => txstest}/backend.go (99%) rename vms/platformvm/txs/{builder => txstest}/builder.go (99%) rename vms/platformvm/txs/{builder => txstest}/context.go (98%) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 73b552e0962..bdb23bdfef1 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -45,11 +45,11 @@ 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/mempool" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "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" - txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" pvalidators "github.com/ava-labs/avalanchego/vms/platformvm/validators" walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -118,7 +118,7 @@ type environment struct { atomicUTXOs avax.AtomicUTXOManager uptimes uptime.Manager utxosVerifier utxo.Verifier - txBuilder *txbuilder.Builder + txBuilder *txstest.Builder backend txexecutor.Backend } @@ -154,7 +154,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.txBuilder = txbuilder.New( + res.txBuilder = txstest.NewBuilder( res.ctx, res.config, res.state, diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 454824288ec..0a8b902ffc4 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -46,10 +46,10 @@ 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/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - p_tx_builder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" pvalidators "github.com/ava-labs/avalanchego/vms/platformvm/validators" walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -130,7 +130,7 @@ type environment struct { atomicUTXOs avax.AtomicUTXOManager uptimes uptime.Manager utxosVerifier utxo.Verifier - txBuilder *p_tx_builder.Builder + txBuilder *txstest.Builder backend *executor.Backend } @@ -159,7 +159,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment res.state = defaultState(res.config, res.ctx, res.baseDB, rewardsCalc) res.uptimes = uptime.NewManager(res.state, res.clk) res.utxosVerifier = utxo.NewVerifier(res.ctx, res.clk, res.fx) - res.txBuilder = p_tx_builder.New( + res.txBuilder = txstest.NewBuilder( res.ctx, res.config, res.state, @@ -170,7 +170,7 @@ 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.txBuilder = p_tx_builder.New( + res.txBuilder = txstest.NewBuilder( res.ctx, res.config, res.mockedState, diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 9774ab55f50..29fb83cfca9 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -46,8 +46,8 @@ import ( 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" - 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/txstest" ) var ( @@ -74,7 +74,7 @@ var ( } ) -func defaultService(t *testing.T) (*Service, *mutableSharedMemory, *txbuilder.Builder) { +func defaultService(t *testing.T) (*Service, *mutableSharedMemory, *txstest.Builder) { vm, txBuilder, _, mutableSharedMemory := defaultVM(t, latestFork) return &Service{ @@ -211,13 +211,13 @@ func TestGetTxStatus(t *testing.T) { func TestGetTx(t *testing.T) { type test struct { description string - createTx func(service *Service, builder *txbuilder.Builder) (*txs.Tx, error) + createTx func(service *Service, builder *txstest.Builder) (*txs.Tx, error) } tests := []test{ { "standard block", - func(_ *Service, builder *txbuilder.Builder) (*txs.Tx, error) { + func(_ *Service, builder *txstest.Builder) (*txs.Tx, error) { return builder.NewCreateChainTx( // Test GetTx works for standard blocks testSubnet1.ID(), []byte{}, @@ -234,7 +234,7 @@ func TestGetTx(t *testing.T) { }, { "proposal block", - func(service *Service, builder *txbuilder.Builder) (*txs.Tx, error) { + func(service *Service, builder *txstest.Builder) (*txs.Tx, error) { sk, err := bls.NewSecretKey() require.NoError(t, err) @@ -268,7 +268,7 @@ func TestGetTx(t *testing.T) { }, { "atomic block", - func(service *Service, builder *txbuilder.Builder) (*txs.Tx, error) { + func(service *Service, builder *txstest.Builder) (*txs.Tx, error) { return builder.NewExportTx( // Test GetTx works for proposal blocks service.vm.ctx.XChainID, []*avax.TransferableOutput{{ diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index cd65a7098bd..dc08248f239 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -19,11 +19,11 @@ 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/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "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" ) @@ -200,8 +200,8 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateBlockchainTxFee = test.fee - builderContext := vmbuilder.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) - backend := vmbuilder.NewBackend(addrs, env.state, env.msm) + builderContext := txstest.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) + backend := txstest.NewBackend(addrs, env.state, env.msm) pBuilder := walletbuilder.New(addrs, builderContext, 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 54c9cde5294..6f58853d7d9 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -14,11 +14,11 @@ 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/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "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" ) @@ -67,8 +67,8 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { cfg := *env.config cfg.CreateSubnetTxFee = test.fee - builderContext := vmbuilder.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) - backend := vmbuilder.NewBackend(addrs, env.state, env.msm) + builderContext := txstest.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) + backend := txstest.NewBackend(addrs, env.state, env.msm) pBuilder := walletbuilder.New(addrs, builderContext, backend) utx, err := pBuilder.NewCreateSubnetTx( diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index aabb8df5d53..4d58a9aebf4 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -42,7 +42,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/builder" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -105,7 +105,7 @@ type environment struct { atomicUTXOs avax.AtomicUTXOManager uptimes uptime.Manager utxosHandler utxo.Verifier - txBuilder *builder.Builder + txBuilder *txstest.Builder backend Backend } @@ -145,7 +145,7 @@ func newEnvironment(t *testing.T, f fork) *environment { uptimes := uptime.NewManager(baseState, clk) utxosVerifier := utxo.NewVerifier(ctx, clk, fx) - txBuilder := builder.New( + txBuilder := txstest.NewBuilder( ctx, config, baseState, @@ -211,7 +211,7 @@ func newEnvironment(t *testing.T, f fork) *environment { func addSubnet( t *testing.T, env *environment, - txBuilder *builder.Builder, + txBuilder *txstest.Builder, ) { require := require.New(t) diff --git a/vms/platformvm/txs/builder/backend.go b/vms/platformvm/txs/txstest/backend.go similarity index 99% rename from vms/platformvm/txs/builder/backend.go rename to vms/platformvm/txs/txstest/backend.go index 7f5b444ab2c..da3d29794c3 100644 --- a/vms/platformvm/txs/builder/backend.go +++ b/vms/platformvm/txs/txstest/backend.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package builder +package txstest import ( "context" diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/txstest/builder.go similarity index 99% rename from vms/platformvm/txs/builder/builder.go rename to vms/platformvm/txs/txstest/builder.go index 3afecfe0e50..d361c024a80 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/txstest/builder.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package builder +package txstest import ( "context" @@ -23,7 +23,7 @@ import ( walletsigner "github.com/ava-labs/avalanchego/wallet/chain/p/signer" ) -func New( +func NewBuilder( ctx *snow.Context, cfg *config.Config, state state.State, diff --git a/vms/platformvm/txs/builder/context.go b/vms/platformvm/txs/txstest/context.go similarity index 98% rename from vms/platformvm/txs/builder/context.go rename to vms/platformvm/txs/txstest/context.go index 78fcf87def4..1ed2b81d013 100644 --- a/vms/platformvm/txs/builder/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package builder +package txstest import ( "time" diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 0bb3a751e9d..9effc6fbeeb 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -43,10 +43,10 @@ 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/txstest" "github.com/ava-labs/avalanchego/vms/secp256k1fx" 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" walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -256,7 +256,7 @@ func takeValidatorsSnapshotAtCurrentHeight(vm *VM, validatorsSetByHeightAndSubne } func addSubnetValidator(vm *VM, data *validatorInputData, subnetID ids.ID) (*state.Staker, error) { - txBuilder := txbuilder.New( + txBuilder := txstest.NewBuilder( vm.ctx, &vm.Config, vm.state, @@ -293,7 +293,7 @@ func addPrimaryValidatorWithBLSKey(vm *VM, data *validatorInputData) (*state.Sta return nil, fmt.Errorf("failed to generate BLS key: %w", err) } - txBuilder := txbuilder.New( + txBuilder := txstest.NewBuilder( vm.ctx, &vm.Config, vm.state, @@ -712,7 +712,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { return nil, ids.Empty, err } - txBuilder := txbuilder.New( + txBuilder := txstest.NewBuilder( vm.ctx, &vm.Config, vm.state, diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 919ccad13ee..0218e115521 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -44,10 +44,10 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/secp256k1fx" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" - txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -482,7 +482,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { addr0 := key0.PublicKey().Address() addr1 := key1.PublicKey().Address() - txBuilder := txbuilder.New( + txBuilder := txstest.NewBuilder( vm.ctx, &vm.Config, vm.state, diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 62630883ddf..fb7ddc1c912 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -58,6 +58,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/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/txstest" "github.com/ava-labs/avalanchego/vms/secp256k1fx" smcon "github.com/ava-labs/avalanchego/snow/consensus/snowman" @@ -66,7 +67,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" walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" walletcommon "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -203,7 +203,7 @@ func defaultGenesis(t *testing.T, avaxAssetID ids.ID) (*api.BuildGenesisArgs, [] return &buildGenesisArgs, genesisBytes } -func defaultVM(t *testing.T, f fork) (*VM, *txbuilder.Builder, database.Database, *mutableSharedMemory) { +func defaultVM(t *testing.T, f fork) (*VM, *txstest.Builder, database.Database, *mutableSharedMemory) { require := require.New(t) var ( apricotPhase3Time = mockable.MaxTime @@ -303,7 +303,7 @@ func defaultVM(t *testing.T, f fork) (*VM, *txbuilder.Builder, database.Database require.NoError(vm.SetState(context.Background(), snow.NormalOp)) - builder := txbuilder.New( + builder := txstest.NewBuilder( ctx, &vm.Config, vm.state, From daeb16a59449966df5234236509ce8fbcfcf6864 Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 28 Mar 2024 16:17:19 -0400 Subject: [PATCH 48/51] nit --- vms/platformvm/service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 29fb83cfca9..9d28576dc03 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -39,6 +39,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -47,7 +48,6 @@ 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/txstest" ) var ( From 5e2e78893aa308171de34f23a225dde2eb2a6eff Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 28 Mar 2024 16:40:43 -0400 Subject: [PATCH 49/51] reduce diff --- vms/platformvm/txs/txstest/backend.go | 32 +++------------------------ 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/vms/platformvm/txs/txstest/backend.go b/vms/platformvm/txs/txstest/backend.go index da3d29794c3..21f00e8181f 100644 --- a/vms/platformvm/txs/txstest/backend.go +++ b/vms/platformvm/txs/txstest/backend.go @@ -5,7 +5,6 @@ package txstest import ( "context" - "fmt" "math" "github.com/ava-labs/avalanchego/chains/atomic" @@ -49,34 +48,9 @@ func (b *Backend) UTXOs(_ context.Context, sourceChainID ids.ID) ([]*avax.UTXO, return avax.GetAllUTXOs(b.state, b.addrs) } - addrsList := make([][]byte, b.addrs.Len()) - i := 0 - for addr := range b.addrs { - copied := addr - addrsList[i] = copied[:] - i++ - } - - allUTXOBytes, _, _, err := b.sharedMemory.Indexed( - sourceChainID, - addrsList, - ids.ShortEmpty[:], - ids.Empty[:], - math.MaxInt, - ) - if err != nil { - return nil, fmt.Errorf("error fetching atomic UTXOs: %w", err) - } - - utxos := make([]*avax.UTXO, len(allUTXOBytes)) - for i, utxoBytes := range allUTXOBytes { - utxo := &avax.UTXO{} - if _, err := txs.Codec.Unmarshal(utxoBytes, utxo); err != nil { - return nil, fmt.Errorf("error parsing UTXO: %w", err) - } - utxos[i] = utxo - } - return utxos, nil + atomicUTXOManager := avax.NewAtomicUTXOManager(b.sharedMemory, txs.Codec) + utxos, _, _, err := atomicUTXOManager.GetAtomicUTXOs(sourceChainID, b.addrs, ids.ShortEmpty, ids.Empty, math.MaxInt) + return utxos, err } func (b *Backend) GetUTXO(_ context.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) { From a0cc76bfe17bc3ffbabe5904627a807dcd90248f Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 28 Mar 2024 18:27:36 -0400 Subject: [PATCH 50/51] nits --- vms/platformvm/txs/executor/create_chain_test.go | 5 ++--- vms/platformvm/txs/executor/create_subnet_test.go | 5 ++--- vms/platformvm/txs/txstest/backend.go | 7 +++---- vms/platformvm/txs/txstest/context.go | 7 +++---- vms/platformvm/vm_test.go | 2 +- wallet/chain/p/builder/builder.go | 6 +++--- 6 files changed, 14 insertions(+), 18 deletions(-) diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index dc08248f239..97f543ab6f0 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -22,9 +22,8 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "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" - - walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) // Ensure Execute fails when there are not enough control sigs @@ -202,7 +201,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { cfg.CreateBlockchainTxFee = test.fee builderContext := txstest.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) backend := txstest.NewBackend(addrs, env.state, env.msm) - pBuilder := walletbuilder.New(addrs, builderContext, backend) + pBuilder := builder.New(addrs, builderContext, backend) utx, err := pBuilder.NewCreateChainTx( testSubnet1.ID(), diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 6f58853d7d9..8f5fecbe5bc 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -17,9 +17,8 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "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" - - walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) func TestCreateSubnetTxAP3FeeChange(t *testing.T) { @@ -69,7 +68,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { cfg.CreateSubnetTxFee = test.fee builderContext := txstest.NewContext(env.ctx, &cfg, env.state.GetTimestamp()) backend := txstest.NewBackend(addrs, env.state, env.msm) - pBuilder := walletbuilder.New(addrs, builderContext, backend) + pBuilder := builder.New(addrs, builderContext, backend) utx, err := pBuilder.NewCreateSubnetTx( &secp256k1fx.OutputOwners{}, // owner diff --git a/vms/platformvm/txs/txstest/backend.go b/vms/platformvm/txs/txstest/backend.go index 21f00e8181f..6dd1e4ff6cf 100644 --- a/vms/platformvm/txs/txstest/backend.go +++ b/vms/platformvm/txs/txstest/backend.go @@ -15,14 +15,13 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/wallet/chain/p/builder" "github.com/ava-labs/avalanchego/wallet/chain/p/signer" - - walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" ) var ( - _ walletbuilder.Backend = (*Backend)(nil) - _ signer.Backend = (*Backend)(nil) + _ builder.Backend = (*Backend)(nil) + _ signer.Backend = (*Backend)(nil) ) func NewBackend( diff --git a/vms/platformvm/txs/txstest/context.go b/vms/platformvm/txs/txstest/context.go index 1ed2b81d013..c4379ddf115 100644 --- a/vms/platformvm/txs/txstest/context.go +++ b/vms/platformvm/txs/txstest/context.go @@ -8,16 +8,15 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/vms/platformvm/config" - - walletbuilder "github.com/ava-labs/avalanchego/wallet/chain/p/builder" + "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{ +) *builder.Context { + return &builder.Context{ NetworkID: ctx.NetworkID, AVAXAssetID: ctx.AVAXAssetID, BaseTxFee: cfg.TxFee, diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index fb7ddc1c912..1eb98a115da 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -2341,7 +2341,7 @@ func TestBaseTx(t *testing.T) { } require.Equal(totalOutputAmt, key0OutputAmt+key1OutputAmt+changeAddrOutputAmt) - require.Equal(vm.Config.TxFee, totalInputAmt-totalOutputAmt) // wallet inflates baseTx fee + require.Equal(vm.TxFee, totalInputAmt-totalOutputAmt) require.Equal(sendAmt, key1OutputAmt) vm.ctx.Lock.Unlock() diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index b411efae8dd..745ebe4d584 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -962,9 +962,9 @@ 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 + // Initialize the return values with empty slices to preserve backward + // compatibility of the json representation of transactions with no + // inputs or outputs. inputs = make([]*avax.TransferableInput, 0) changeOutputs = make([]*avax.TransferableOutput, 0) stakeOutputs = make([]*avax.TransferableOutput, 0) From 8c91bb3ca7ca2427037d5ea1ae276fa264b878bb Mon Sep 17 00:00:00 2001 From: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 28 Mar 2024 18:28:40 -0400 Subject: [PATCH 51/51] nit --- vms/platformvm/txs/txstest/builder.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vms/platformvm/txs/txstest/builder.go b/vms/platformvm/txs/txstest/builder.go index d361c024a80..f310616bb19 100644 --- a/vms/platformvm/txs/txstest/builder.go +++ b/vms/platformvm/txs/txstest/builder.go @@ -16,10 +16,10 @@ 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/builder" "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" ) @@ -337,13 +337,13 @@ func (b *Builder) NewBaseTx( return walletsigner.SignUnsigned(context.Background(), pSigner, utx) } -func (b *Builder) builders(keys []*secp256k1.PrivateKey) (walletbuilder.Builder, walletsigner.Signer) { +func (b *Builder) builders(keys []*secp256k1.PrivateKey) (builder.Builder, walletsigner.Signer) { var ( kc = secp256k1fx.NewKeychain(keys...) addrs = kc.Addresses() backend = NewBackend(addrs, b.state, b.ctx.SharedMemory) context = NewContext(b.ctx, b.cfg, backend.state.GetTimestamp()) - builder = walletbuilder.New(addrs, context, backend) + builder = builder.New(addrs, context, backend) signer = walletsigner.New(kc, backend) )