github.com/MetalBlockchain/metalgo@v1.11.9/vms/platformvm/txs/add_delegator_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 txs 5 6 import ( 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/require" 11 12 "github.com/MetalBlockchain/metalgo/ids" 13 "github.com/MetalBlockchain/metalgo/snow/snowtest" 14 "github.com/MetalBlockchain/metalgo/utils/crypto/secp256k1" 15 "github.com/MetalBlockchain/metalgo/utils/timer/mockable" 16 "github.com/MetalBlockchain/metalgo/vms/components/avax" 17 "github.com/MetalBlockchain/metalgo/vms/platformvm/stakeable" 18 "github.com/MetalBlockchain/metalgo/vms/secp256k1fx" 19 ) 20 21 var preFundedKeys = secp256k1.TestKeys() 22 23 func TestAddDelegatorTxSyntacticVerify(t *testing.T) { 24 require := require.New(t) 25 clk := mockable.Clock{} 26 ctx := snowtest.Context(t, snowtest.PChainID) 27 signers := [][]*secp256k1.PrivateKey{preFundedKeys} 28 29 var ( 30 stx *Tx 31 addDelegatorTx *AddDelegatorTx 32 err error 33 ) 34 35 // Case : signed tx is nil 36 err = stx.SyntacticVerify(ctx) 37 require.ErrorIs(err, ErrNilSignedTx) 38 39 // Case : unsigned tx is nil 40 err = addDelegatorTx.SyntacticVerify(ctx) 41 require.ErrorIs(err, ErrNilTx) 42 43 validatorWeight := uint64(2022) 44 inputs := []*avax.TransferableInput{{ 45 UTXOID: avax.UTXOID{ 46 TxID: ids.ID{'t', 'x', 'I', 'D'}, 47 OutputIndex: 2, 48 }, 49 Asset: avax.Asset{ID: ctx.AVAXAssetID}, 50 In: &secp256k1fx.TransferInput{ 51 Amt: uint64(5678), 52 Input: secp256k1fx.Input{SigIndices: []uint32{0}}, 53 }, 54 }} 55 outputs := []*avax.TransferableOutput{{ 56 Asset: avax.Asset{ID: ctx.AVAXAssetID}, 57 Out: &secp256k1fx.TransferOutput{ 58 Amt: uint64(1234), 59 OutputOwners: secp256k1fx.OutputOwners{ 60 Threshold: 1, 61 Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, 62 }, 63 }, 64 }} 65 stakes := []*avax.TransferableOutput{{ 66 Asset: avax.Asset{ID: ctx.AVAXAssetID}, 67 Out: &stakeable.LockOut{ 68 Locktime: uint64(clk.Time().Add(time.Second).Unix()), 69 TransferableOut: &secp256k1fx.TransferOutput{ 70 Amt: validatorWeight, 71 OutputOwners: secp256k1fx.OutputOwners{ 72 Threshold: 1, 73 Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, 74 }, 75 }, 76 }, 77 }} 78 addDelegatorTx = &AddDelegatorTx{ 79 BaseTx: BaseTx{BaseTx: avax.BaseTx{ 80 NetworkID: ctx.NetworkID, 81 BlockchainID: ctx.ChainID, 82 Outs: outputs, 83 Ins: inputs, 84 Memo: []byte{1, 2, 3, 4, 5, 6, 7, 8}, 85 }}, 86 Validator: Validator{ 87 NodeID: ctx.NodeID, 88 Start: uint64(clk.Time().Unix()), 89 End: uint64(clk.Time().Add(time.Hour).Unix()), 90 Wght: validatorWeight, 91 }, 92 StakeOuts: stakes, 93 DelegationRewardsOwner: &secp256k1fx.OutputOwners{ 94 Locktime: 0, 95 Threshold: 1, 96 Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, 97 }, 98 } 99 100 // Case: signed tx not initialized 101 stx = &Tx{Unsigned: addDelegatorTx} 102 err = stx.SyntacticVerify(ctx) 103 require.ErrorIs(err, errSignedTxNotInitialized) 104 105 // Case: valid tx 106 stx, err = NewSigned(addDelegatorTx, Codec, signers) 107 require.NoError(err) 108 require.NoError(stx.SyntacticVerify(ctx)) 109 110 // Case: Wrong network ID 111 addDelegatorTx.SyntacticallyVerified = false 112 addDelegatorTx.NetworkID++ 113 stx, err = NewSigned(addDelegatorTx, Codec, signers) 114 require.NoError(err) 115 err = stx.SyntacticVerify(ctx) 116 require.ErrorIs(err, avax.ErrWrongNetworkID) 117 addDelegatorTx.NetworkID-- 118 119 // Case: delegator weight is not equal to total stake weight 120 addDelegatorTx.SyntacticallyVerified = false 121 addDelegatorTx.Wght = 2 * validatorWeight 122 stx, err = NewSigned(addDelegatorTx, Codec, signers) 123 require.NoError(err) 124 err = stx.SyntacticVerify(ctx) 125 require.ErrorIs(err, errDelegatorWeightMismatch) 126 addDelegatorTx.Wght = validatorWeight 127 } 128 129 func TestAddDelegatorTxSyntacticVerifyNotAVAX(t *testing.T) { 130 require := require.New(t) 131 clk := mockable.Clock{} 132 ctx := snowtest.Context(t, snowtest.PChainID) 133 signers := [][]*secp256k1.PrivateKey{preFundedKeys} 134 135 var ( 136 stx *Tx 137 addDelegatorTx *AddDelegatorTx 138 err error 139 ) 140 141 assetID := ids.GenerateTestID() 142 validatorWeight := uint64(2022) 143 inputs := []*avax.TransferableInput{{ 144 UTXOID: avax.UTXOID{ 145 TxID: ids.ID{'t', 'x', 'I', 'D'}, 146 OutputIndex: 2, 147 }, 148 Asset: avax.Asset{ID: assetID}, 149 In: &secp256k1fx.TransferInput{ 150 Amt: uint64(5678), 151 Input: secp256k1fx.Input{SigIndices: []uint32{0}}, 152 }, 153 }} 154 outputs := []*avax.TransferableOutput{{ 155 Asset: avax.Asset{ID: assetID}, 156 Out: &secp256k1fx.TransferOutput{ 157 Amt: uint64(1234), 158 OutputOwners: secp256k1fx.OutputOwners{ 159 Threshold: 1, 160 Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, 161 }, 162 }, 163 }} 164 stakes := []*avax.TransferableOutput{{ 165 Asset: avax.Asset{ID: assetID}, 166 Out: &stakeable.LockOut{ 167 Locktime: uint64(clk.Time().Add(time.Second).Unix()), 168 TransferableOut: &secp256k1fx.TransferOutput{ 169 Amt: validatorWeight, 170 OutputOwners: secp256k1fx.OutputOwners{ 171 Threshold: 1, 172 Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, 173 }, 174 }, 175 }, 176 }} 177 addDelegatorTx = &AddDelegatorTx{ 178 BaseTx: BaseTx{BaseTx: avax.BaseTx{ 179 NetworkID: ctx.NetworkID, 180 BlockchainID: ctx.ChainID, 181 Outs: outputs, 182 Ins: inputs, 183 Memo: []byte{1, 2, 3, 4, 5, 6, 7, 8}, 184 }}, 185 Validator: Validator{ 186 NodeID: ctx.NodeID, 187 Start: uint64(clk.Time().Unix()), 188 End: uint64(clk.Time().Add(time.Hour).Unix()), 189 Wght: validatorWeight, 190 }, 191 StakeOuts: stakes, 192 DelegationRewardsOwner: &secp256k1fx.OutputOwners{ 193 Locktime: 0, 194 Threshold: 1, 195 Addrs: []ids.ShortID{preFundedKeys[0].PublicKey().Address()}, 196 }, 197 } 198 199 stx, err = NewSigned(addDelegatorTx, Codec, signers) 200 require.NoError(err) 201 202 err = stx.SyntacticVerify(ctx) 203 require.ErrorIs(err, errStakeMustBeAVAX) 204 } 205 206 func TestAddDelegatorTxNotValidatorTx(t *testing.T) { 207 txIntf := any((*AddDelegatorTx)(nil)) 208 _, ok := txIntf.(ValidatorTx) 209 require.False(t, ok) 210 }