Skip to content

Commit 113294a

Browse files
committed
Squashed commit of the following:
commit cb0a693 Author: Alberto Benegiamo <alberto.benegiamo@gmail.com> Date: Thu Feb 15 12:16:10 2024 +0100 replaced Spend with NewSpend commit 03c0a9f Author: Alberto Benegiamo <alberto.benegiamo@gmail.com> Date: Thu Feb 15 11:50:01 2024 +0100 wip: refactoring importTx builder commit 40e480a Author: Alberto Benegiamo <alberto.benegiamo@gmail.com> Date: Thu Feb 15 11:02:53 2024 +0100 refactored exportTx builder commit 7c04d76 Author: Alberto Benegiamo <alberto.benegiamo@gmail.com> Date: Wed Feb 14 18:46:20 2024 +0100 refactored operationTx builder commit 39cae3c Author: Alberto Benegiamo <alberto.benegiamo@gmail.com> Date: Wed Feb 14 17:48:17 2024 +0100 refactored baseTx builder commit 1feae9a Author: Alberto Benegiamo <alberto.benegiamo@gmail.com> Date: Wed Feb 14 15:55:07 2024 +0100 refactored createAssetTx builder commit a759c24 Author: Stephen Buttolph <stephen@avalabs.org> Date: Tue Feb 13 15:21:03 2024 -0500 Remove duplicate IP length constant (#2733)
1 parent 044bd52 commit 113294a

File tree

8 files changed

+334
-418
lines changed

8 files changed

+334
-418
lines changed

network/peer/ip.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func (ip *UnsignedIP) Sign(signer crypto.Signer) (*SignedIP, error) {
4444

4545
func (ip *UnsignedIP) bytes() []byte {
4646
p := wrappers.Packer{
47-
Bytes: make([]byte, wrappers.IPLen+wrappers.LongLen),
47+
Bytes: make([]byte, ips.IPPortLen+wrappers.LongLen),
4848
}
4949
ips.PackIP(&p, ip.IPPort)
5050
p.PackLong(ip.Timestamp)

utils/ips/ip_port.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
)
1414

1515
const (
16-
IPPortLen = 16 + wrappers.ShortLen
16+
IPPortLen = net.IPv6len + wrappers.ShortLen
1717
nullStr = "null"
1818
)
1919

utils/wrappers/packing.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ const (
2222
LongLen = 8
2323
// BoolLen is the number of bytes per bool
2424
BoolLen = 1
25-
// IPLen is the number of bytes per IP
26-
IPLen = 16 + ShortLen
2725
)
2826

2927
func StringLen(str string) int {

vms/avm/service.go

Lines changed: 33 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -968,45 +968,10 @@ func (s *Service) buildCreateNFTAsset(args *CreateNFTAssetArgs) (*txs.Tx, ids.Sh
968968

969969
codec := s.vm.parser.Codec()
970970
initialState.Sort(codec)
971-
972-
return buildCreateNFTAsset(s.vm, args.Name, args.Symbol, args.MinterSets, utxos, kc, changeAddr)
973-
}
974-
975-
func buildCreateNFTAsset(
976-
vm *VM,
977-
name, symbol string,
978-
minterSets []Owners,
979-
utxos []*avax.UTXO,
980-
kc *secp256k1fx.Keychain,
981-
changeAddr ids.ShortID,
982-
) (*txs.Tx, ids.ShortID, error) {
983-
initialState := &txs.InitialState{
984-
FxIndex: 1, // TODO: Should lookup nftfx FxID
985-
Outs: make([]verify.State, 0, len(minterSets)),
986-
}
987-
for i, owner := range minterSets {
988-
minter := &nftfx.MintOutput{
989-
GroupID: uint32(i),
990-
OutputOwners: secp256k1fx.OutputOwners{
991-
Threshold: uint32(owner.Threshold),
992-
},
993-
}
994-
minterAddrsSet, err := avax.ParseServiceAddresses(vm, owner.Minters)
995-
if err != nil {
996-
return nil, ids.ShortEmpty, err
997-
}
998-
minter.Addrs = minterAddrsSet.List()
999-
utils.Sort(minter.Addrs)
1000-
initialState.Outs = append(initialState.Outs, minter)
1001-
}
1002-
1003-
codec := vm.parser.Codec()
1004-
initialState.Sort(codec)
1005-
1006971
return buildCreateAssetTx(
1007-
vm,
1008-
name,
1009-
symbol,
972+
s.vm,
973+
args.Name,
974+
args.Symbol,
1010975
0, // NFTs are non-fungible
1011976
[]*txs.InitialState{initialState},
1012977
utxos,
@@ -1774,45 +1739,59 @@ func (s *Service) buildImport(args *ImportArgs) (*txs.Tx, error) {
17741739
return nil, fmt.Errorf("problem retrieving user's atomic UTXOs: %w", err)
17751740
}
17761741

1777-
amountsSpent, importInputs, importKeys, err := s.vm.SpendAll(atomicUTXOs, kc)
1742+
return buildImportTx(s.vm, chainID, atomicUTXOs, to, utxos, kc)
1743+
}
1744+
1745+
func buildImportTx(
1746+
vm *VM,
1747+
sourceChain ids.ID,
1748+
atomicUTXOs []*avax.UTXO,
1749+
to ids.ShortID,
1750+
utxos []*avax.UTXO,
1751+
kc *secp256k1fx.Keychain,
1752+
) (*txs.Tx, error) {
1753+
toBurn, importInputs, importKeys, err := vm.SpendAll(atomicUTXOs, kc)
17781754
if err != nil {
17791755
return nil, err
17801756
}
17811757

17821758
var (
1783-
chainTime = s.vm.state.GetTimestamp()
1784-
feeCfg = s.vm.GetDynamicFeesConfig(chainTime)
1759+
chainTime = vm.state.GetTimestamp()
1760+
feeCfg = vm.GetDynamicFeesConfig(chainTime)
17851761
feeMan = commonfees.NewManager(feeCfg.UnitFees)
17861762
feeCalc = &fees.Calculator{
1787-
IsEUpgradeActive: s.vm.IsEUpgradeActivated(chainTime),
1788-
Config: &s.vm.Config,
1763+
IsEUpgradeActive: vm.IsEUpgradeActivated(chainTime),
1764+
Config: &vm.Config,
17891765
FeeManager: feeMan,
17901766
ConsumedUnitsCap: feeCfg.BlockUnitsCap,
1791-
Codec: s.vm.parser.Codec(),
1767+
Codec: vm.parser.Codec(),
17921768
}
17931769
)
17941770

17951771
uTx := &txs.ImportTx{
17961772
BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{
1797-
NetworkID: s.vm.ctx.NetworkID,
1798-
BlockchainID: s.vm.ctx.ChainID,
1773+
NetworkID: vm.ctx.NetworkID,
1774+
BlockchainID: vm.ctx.ChainID,
17991775
}},
1800-
SourceChain: chainID,
1776+
SourceChain: sourceChain,
18011777
ImportedIns: importInputs,
18021778
}
18031779
if err := uTx.Visit(feeCalc); err != nil {
18041780
return nil, err
18051781
}
18061782

1807-
if amountSpent := amountsSpent[s.vm.feeAssetID]; amountSpent < feeCalc.Fee {
1808-
feeCalc.Fee -= amountSpent
1783+
if importedAmt := toBurn[vm.feeAssetID]; importedAmt < feeCalc.Fee {
1784+
feeCalc.Fee -= importedAmt
1785+
toBurn[vm.feeAssetID] = 0
1786+
} else {
1787+
feeCalc.Fee = 0
1788+
toBurn[vm.feeAssetID] -= feeCalc.Fee
18091789
}
1810-
toSpend := make(map[ids.ID]uint64)
1811-
ins, outs, keys, err := s.vm.FinanceTx(
1790+
ins, outs, keys, err := vm.FinanceTx(
18121791
utxos,
1813-
s.vm.feeAssetID,
1792+
vm.feeAssetID,
18141793
kc,
1815-
toSpend,
1794+
toBurn,
18161795
feeCalc,
18171796
to,
18181797
)
@@ -1824,7 +1803,7 @@ func (s *Service) buildImport(args *ImportArgs) (*txs.Tx, error) {
18241803
uTx.Ins = ins
18251804
uTx.Outs = outs
18261805
tx := &txs.Tx{Unsigned: uTx}
1827-
return tx, tx.SignSECP256K1Fx(s.vm.parser.Codec(), keys)
1806+
return tx, tx.SignSECP256K1Fx(vm.parser.Codec(), keys)
18281807
}
18291808

18301809
// ExportArgs are arguments for passing into ExportAVA requests

vms/avm/service_test.go

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,37 +1747,6 @@ func buildTestExportTx(t *testing.T, env *environment, chainID ids.ID) *txs.Tx {
17471747
)
17481748
require.NoError(t, err)
17491749
return tx
1750-
1751-
// return &txs.Tx{Unsigned: &txs.ExportTx{
1752-
// BaseTx: txs.BaseTx{
1753-
// BaseTx: avax.BaseTx{
1754-
// NetworkID: constants.UnitTestID,
1755-
// BlockchainID: chainID,
1756-
// Ins: []*avax.TransferableInput{{
1757-
// UTXOID: avax.UTXOID{
1758-
// TxID: avaxTx.ID(),
1759-
// OutputIndex: 2,
1760-
// },
1761-
// Asset: avax.Asset{ID: avaxTx.ID()},
1762-
// In: &secp256k1fx.TransferInput{
1763-
// Amt: startBalance,
1764-
// Input: secp256k1fx.Input{SigIndices: []uint32{0}},
1765-
// },
1766-
// }},
1767-
// },
1768-
// },
1769-
// DestinationChain: constants.PlatformChainID,
1770-
// ExportedOuts: []*avax.TransferableOutput{{
1771-
// Asset: avax.Asset{ID: avaxTx.ID()},
1772-
// Out: &secp256k1fx.TransferOutput{
1773-
// Amt: startBalance / 2, // TODO ABENEGIA: find a way to pay the exact amount of fees
1774-
// OutputOwners: secp256k1fx.OutputOwners{
1775-
// Threshold: 1,
1776-
// Addrs: []ids.ShortID{key.PublicKey().Address()},
1777-
// },
1778-
// },
1779-
// }},
1780-
// }}
17811750
}
17821751

17831752
func buildNFTxMintOp(createAssetTx *txs.Tx, key *secp256k1.PrivateKey, outputIndex, groupID uint32) *txs.Operation {

vms/avm/utxo/spender.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,16 @@ type Spender interface {
3030
// Arguments:
3131
// - [utxos] contains assets ID and amount to be spend for each assestID
3232
// - [kc] are the owners of the funds
33-
// - [amounts] is the amount of funds that are available to be spent for each assetID
33+
// - [toSpend] is the amount of funds that are available to be spent for each assetID
3434
// Returns:
35-
// - [amountsSpent] the amount of funds that are spent
3635
// - [inputs] the inputs that should be consumed to fund the outputs
37-
// - [outputs] the outputs that should be generated
36+
// - [outputs] the outputs produced
3837
// - [signers] the proof of ownership of the funds being moved
3938
FinanceTx(
4039
utxos []*avax.UTXO,
4140
feeAssetID ids.ID,
4241
kc *secp256k1fx.Keychain,
43-
amounts map[ids.ID]uint64,
42+
toSpend map[ids.ID]uint64,
4443
feeCalc *fees.Calculator,
4544
changeAddr ids.ShortID,
4645
) (
@@ -132,22 +131,25 @@ func (s *spender) FinanceTx(
132131
toSpend[feeAssetID] = amountWithFee
133132

134133
var (
135-
time = s.clock.Unix()
134+
minIssuanceTime = s.clock.Unix()
136135

137136
ins = []*avax.TransferableInput{}
138137
outs = []*avax.TransferableOutput{}
139138
keys = [][]*secp256k1.PrivateKey{}
140139
)
141140

141+
// Iterate over the UTXOs
142142
for _, utxo := range utxos {
143143
assetID := utxo.AssetID()
144+
remainingAmountToBurn := toSpend[assetID]
144145

145-
if toSpend[assetID] == 0 {
146-
// we have enough inputs allocated to this asset
146+
// If we have consumed enough of the asset, then we have no need burn
147+
// more.
148+
if remainingAmountToBurn == 0 {
147149
continue
148150
}
149151

150-
inputIntf, signers, err := kc.Spend(utxo.Out, time)
152+
inputIntf, signers, err := kc.Spend(utxo.Out, minIssuanceTime)
151153
if err != nil {
152154
// this utxo can't be spent with the current keys right now
153155
continue

vms/avm/vm_regression_test.go

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import (
1111
"github.com/stretchr/testify/require"
1212

1313
"github.com/ava-labs/avalanchego/ids"
14-
"github.com/ava-labs/avalanchego/utils/constants"
15-
"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
1614
"github.com/ava-labs/avalanchego/utils/timer/mockable"
1715
"github.com/ava-labs/avalanchego/vms/avm/config"
1816
"github.com/ava-labs/avalanchego/vms/avm/txs"
@@ -46,6 +44,7 @@ func TestVerifyFxUsage(t *testing.T) {
4644
utxos, err := avax.GetAllUTXOs(env.vm.state, kc.Addresses())
4745
require.NoError(err)
4846

47+
// Create the asset
4948
createAssetTx, _, err := buildCreateAssetTx(
5049
env.vm,
5150
"Team Rocket", // name
@@ -84,47 +83,52 @@ func TestVerifyFxUsage(t *testing.T) {
8483
require.NoError(err)
8584
issueAndAccept(require, env.vm, env.issuer, createAssetTx)
8685

87-
mintNFTTx := &txs.Tx{Unsigned: &txs.OperationTx{
88-
BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{
89-
NetworkID: constants.UnitTestID,
90-
BlockchainID: env.vm.ctx.XChainID,
91-
}},
92-
Ops: []*txs.Operation{{
93-
Asset: avax.Asset{ID: createAssetTx.ID()},
94-
UTXOIDs: []*avax.UTXOID{{
95-
TxID: createAssetTx.ID(),
96-
OutputIndex: 1,
97-
}},
98-
Op: &nftfx.MintOperation{
99-
MintInput: secp256k1fx.Input{
100-
SigIndices: []uint32{0},
101-
},
102-
GroupID: 1,
103-
Payload: []byte{'h', 'e', 'l', 'l', 'o'},
104-
Outputs: []*secp256k1fx.OutputOwners{{}},
105-
},
106-
}},
107-
}}
108-
require.NoError(mintNFTTx.SignNFTFx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{keys[0]}}))
86+
// Mint the NFT
87+
utxos, err = avax.GetAllUTXOs(env.vm.state, kc.Addresses())
88+
require.NoError(err)
89+
mintOp, nftKeys, err := env.vm.MintNFT(
90+
utxos,
91+
kc,
92+
createAssetTx.ID(),
93+
[]byte{'h', 'e', 'l', 'l', 'o'}, // payload
94+
key.Address(),
95+
)
96+
require.NoError(err)
97+
98+
mintNFTTx, _, err := buildOperation(
99+
env.vm,
100+
mintOp,
101+
nil,
102+
utxos,
103+
kc,
104+
key.Address(),
105+
)
106+
require.NoError(err)
107+
require.NoError(mintNFTTx.SignNFTFx(env.vm.parser.Codec(), nftKeys))
109108
issueAndAccept(require, env.vm, env.issuer, mintNFTTx)
110109

111-
spendTx := &txs.Tx{Unsigned: &txs.BaseTx{BaseTx: avax.BaseTx{
112-
NetworkID: constants.UnitTestID,
113-
BlockchainID: env.vm.ctx.XChainID,
114-
Ins: []*avax.TransferableInput{{
115-
UTXOID: avax.UTXOID{
116-
TxID: createAssetTx.ID(),
117-
OutputIndex: 0,
118-
},
110+
// move the NFT
111+
utxos, err = avax.GetAllUTXOs(env.vm.state, kc.Addresses())
112+
require.NoError(err)
113+
114+
to := keys[2].PublicKey().Address()
115+
spendTx, _, err := buildBaseTx(
116+
env.vm,
117+
[]*avax.TransferableOutput{{
119118
Asset: avax.Asset{ID: createAssetTx.ID()},
120-
In: &secp256k1fx.TransferInput{
119+
Out: &secp256k1fx.TransferOutput{
121120
Amt: 1,
122-
Input: secp256k1fx.Input{
123-
SigIndices: []uint32{0},
121+
OutputOwners: secp256k1fx.OutputOwners{
122+
Threshold: 1,
123+
Addrs: []ids.ShortID{to},
124124
},
125125
},
126126
}},
127-
}}}
128-
require.NoError(spendTx.SignSECP256K1Fx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{keys[0]}}))
127+
nil, // memo
128+
utxos,
129+
kc,
130+
key.Address(),
131+
)
132+
require.NoError(err)
129133
issueAndAccept(require, env.vm, env.issuer, spendTx)
130134
}

0 commit comments

Comments
 (0)