github.com/ava-labs/avalanchego@v1.11.11/wallet/chain/p/builder/builder_test.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package builder 5 6 import ( 7 "math/rand" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/require" 12 13 "github.com/ava-labs/avalanchego/ids" 14 "github.com/ava-labs/avalanchego/utils" 15 "github.com/ava-labs/avalanchego/vms/components/avax" 16 "github.com/ava-labs/avalanchego/vms/components/verify" 17 "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" 18 "github.com/ava-labs/avalanchego/vms/secp256k1fx" 19 ) 20 21 func generateUTXOs(random *rand.Rand, assetID ids.ID, locktime uint64) []*avax.UTXO { 22 utxos := make([]*avax.UTXO, random.Intn(10)) 23 for i := range utxos { 24 var output avax.TransferableOut = &secp256k1fx.TransferOutput{ 25 Amt: random.Uint64(), 26 OutputOwners: secp256k1fx.OutputOwners{ 27 Locktime: random.Uint64(), 28 Threshold: 1, 29 Addrs: []ids.ShortID{ids.GenerateTestShortID()}, 30 }, 31 } 32 if locktime != 0 { 33 output = &stakeable.LockOut{ 34 Locktime: locktime, 35 TransferableOut: output, 36 } 37 } 38 utxos[i] = &avax.UTXO{ 39 UTXOID: avax.UTXOID{ 40 TxID: ids.GenerateTestID(), 41 OutputIndex: random.Uint32(), 42 }, 43 Asset: avax.Asset{ 44 ID: assetID, 45 }, 46 Out: output, 47 } 48 } 49 return utxos 50 } 51 52 func TestSplitByLocktime(t *testing.T) { 53 seed := time.Now().UnixNano() 54 t.Logf("Seed: %d", seed) 55 random := rand.New(rand.NewSource(seed)) // #nosec G404 56 57 var ( 58 require = require.New(t) 59 60 unlockedTime uint64 = 100 61 expectedUnlocked = utils.Join( 62 generateUTXOs(random, ids.GenerateTestID(), 0), 63 generateUTXOs(random, ids.GenerateTestID(), unlockedTime-1), 64 generateUTXOs(random, ids.GenerateTestID(), unlockedTime), 65 ) 66 expectedLocked = utils.Join( 67 generateUTXOs(random, ids.GenerateTestID(), unlockedTime+100), 68 generateUTXOs(random, ids.GenerateTestID(), unlockedTime+1), 69 ) 70 utxos = utils.Join( 71 expectedUnlocked, 72 expectedLocked, 73 ) 74 ) 75 random.Shuffle(len(utxos), func(i, j int) { 76 utxos[i], utxos[j] = utxos[j], utxos[i] 77 }) 78 79 utxosByLocktime := splitByLocktime(utxos, unlockedTime) 80 require.ElementsMatch(expectedUnlocked, utxosByLocktime.unlocked) 81 require.ElementsMatch(expectedLocked, utxosByLocktime.locked) 82 } 83 84 func TestByAssetID(t *testing.T) { 85 seed := time.Now().UnixNano() 86 t.Logf("Seed: %d", seed) 87 random := rand.New(rand.NewSource(seed)) // #nosec G404 88 89 var ( 90 require = require.New(t) 91 92 assetID = ids.GenerateTestID() 93 expectedRequested = generateUTXOs(random, assetID, random.Uint64()) 94 expectedOther = generateUTXOs(random, ids.GenerateTestID(), random.Uint64()) 95 utxos = utils.Join( 96 expectedRequested, 97 expectedOther, 98 ) 99 ) 100 random.Shuffle(len(utxos), func(i, j int) { 101 utxos[i], utxos[j] = utxos[j], utxos[i] 102 }) 103 104 utxosByAssetID := splitByAssetID(utxos, assetID) 105 require.ElementsMatch(expectedRequested, utxosByAssetID.requested) 106 require.ElementsMatch(expectedOther, utxosByAssetID.other) 107 } 108 109 func TestUnwrapOutput(t *testing.T) { 110 normalOutput := &secp256k1fx.TransferOutput{ 111 Amt: 123, 112 OutputOwners: secp256k1fx.OutputOwners{ 113 Locktime: 456, 114 Threshold: 1, 115 Addrs: []ids.ShortID{ids.ShortEmpty}, 116 }, 117 } 118 119 tests := []struct { 120 name string 121 output verify.State 122 expectedOutput *secp256k1fx.TransferOutput 123 expectedLocktime uint64 124 expectedErr error 125 }{ 126 { 127 name: "normal output", 128 output: normalOutput, 129 expectedOutput: normalOutput, 130 expectedLocktime: 0, 131 expectedErr: nil, 132 }, 133 { 134 name: "locked output", 135 output: &stakeable.LockOut{ 136 Locktime: 789, 137 TransferableOut: normalOutput, 138 }, 139 expectedOutput: normalOutput, 140 expectedLocktime: 789, 141 expectedErr: nil, 142 }, 143 { 144 name: "locked output with no locktime", 145 output: &stakeable.LockOut{ 146 Locktime: 0, 147 TransferableOut: normalOutput, 148 }, 149 expectedOutput: normalOutput, 150 expectedLocktime: 0, 151 expectedErr: nil, 152 }, 153 { 154 name: "invalid output", 155 output: nil, 156 expectedOutput: nil, 157 expectedLocktime: 0, 158 expectedErr: ErrUnknownOutputType, 159 }, 160 } 161 162 for _, test := range tests { 163 t.Run(test.name, func(t *testing.T) { 164 require := require.New(t) 165 166 output, locktime, err := unwrapOutput(test.output) 167 require.ErrorIs(err, test.expectedErr) 168 require.Equal(test.expectedOutput, output) 169 require.Equal(test.expectedLocktime, locktime) 170 }) 171 } 172 }