github.com/MetalBlockchain/metalgo@v1.11.9/vms/platformvm/api/static_service_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 api 5 6 import ( 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/MetalBlockchain/metalgo/ids" 12 "github.com/MetalBlockchain/metalgo/utils/constants" 13 "github.com/MetalBlockchain/metalgo/utils/formatting" 14 "github.com/MetalBlockchain/metalgo/utils/formatting/address" 15 "github.com/MetalBlockchain/metalgo/utils/json" 16 "github.com/MetalBlockchain/metalgo/vms/platformvm/genesis" 17 ) 18 19 func TestBuildGenesisInvalidUTXOBalance(t *testing.T) { 20 require := require.New(t) 21 nodeID := ids.BuildTestNodeID([]byte{1, 2, 3}) 22 addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) 23 require.NoError(err) 24 25 utxo := UTXO{ 26 Address: addr, 27 Amount: 0, 28 } 29 weight := json.Uint64(987654321) 30 validator := GenesisPermissionlessValidator{ 31 GenesisValidator: GenesisValidator{ 32 EndTime: 15, 33 Weight: weight, 34 NodeID: nodeID, 35 }, 36 RewardOwner: &Owner{ 37 Threshold: 1, 38 Addresses: []string{addr}, 39 }, 40 Staked: []UTXO{{ 41 Amount: weight, 42 Address: addr, 43 }}, 44 } 45 46 args := BuildGenesisArgs{ 47 UTXOs: []UTXO{ 48 utxo, 49 }, 50 Validators: []GenesisPermissionlessValidator{ 51 validator, 52 }, 53 Time: 5, 54 Encoding: formatting.Hex, 55 } 56 reply := BuildGenesisReply{} 57 58 ss := StaticService{} 59 err = ss.BuildGenesis(nil, &args, &reply) 60 require.ErrorIs(err, errUTXOHasNoValue) 61 } 62 63 func TestBuildGenesisInvalidStakeWeight(t *testing.T) { 64 require := require.New(t) 65 nodeID := ids.BuildTestNodeID([]byte{1, 2, 3}) 66 addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) 67 require.NoError(err) 68 69 utxo := UTXO{ 70 Address: addr, 71 Amount: 123456789, 72 } 73 weight := json.Uint64(0) 74 validator := GenesisPermissionlessValidator{ 75 GenesisValidator: GenesisValidator{ 76 StartTime: 0, 77 EndTime: 15, 78 NodeID: nodeID, 79 }, 80 RewardOwner: &Owner{ 81 Threshold: 1, 82 Addresses: []string{addr}, 83 }, 84 Staked: []UTXO{{ 85 Amount: weight, 86 Address: addr, 87 }}, 88 } 89 90 args := BuildGenesisArgs{ 91 UTXOs: []UTXO{ 92 utxo, 93 }, 94 Validators: []GenesisPermissionlessValidator{ 95 validator, 96 }, 97 Time: 5, 98 Encoding: formatting.Hex, 99 } 100 reply := BuildGenesisReply{} 101 102 ss := StaticService{} 103 err = ss.BuildGenesis(nil, &args, &reply) 104 require.ErrorIs(err, errValidatorHasNoWeight) 105 } 106 107 func TestBuildGenesisInvalidEndtime(t *testing.T) { 108 require := require.New(t) 109 nodeID := ids.BuildTestNodeID([]byte{1, 2, 3}) 110 addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) 111 require.NoError(err) 112 113 utxo := UTXO{ 114 Address: addr, 115 Amount: 123456789, 116 } 117 118 weight := json.Uint64(987654321) 119 validator := GenesisPermissionlessValidator{ 120 GenesisValidator: GenesisValidator{ 121 StartTime: 0, 122 EndTime: 5, 123 NodeID: nodeID, 124 }, 125 RewardOwner: &Owner{ 126 Threshold: 1, 127 Addresses: []string{addr}, 128 }, 129 Staked: []UTXO{{ 130 Amount: weight, 131 Address: addr, 132 }}, 133 } 134 135 args := BuildGenesisArgs{ 136 UTXOs: []UTXO{ 137 utxo, 138 }, 139 Validators: []GenesisPermissionlessValidator{ 140 validator, 141 }, 142 Time: 5, 143 Encoding: formatting.Hex, 144 } 145 reply := BuildGenesisReply{} 146 147 ss := StaticService{} 148 err = ss.BuildGenesis(nil, &args, &reply) 149 require.ErrorIs(err, errValidatorAlreadyExited) 150 } 151 152 func TestBuildGenesisReturnsSortedValidators(t *testing.T) { 153 require := require.New(t) 154 nodeID := ids.BuildTestNodeID([]byte{1}) 155 addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) 156 require.NoError(err) 157 158 utxo := UTXO{ 159 Address: addr, 160 Amount: 123456789, 161 } 162 163 weight := json.Uint64(987654321) 164 validator1 := GenesisPermissionlessValidator{ 165 GenesisValidator: GenesisValidator{ 166 StartTime: 0, 167 EndTime: 20, 168 NodeID: nodeID, 169 }, 170 RewardOwner: &Owner{ 171 Threshold: 1, 172 Addresses: []string{addr}, 173 }, 174 Staked: []UTXO{{ 175 Amount: weight, 176 Address: addr, 177 }}, 178 } 179 180 validator2 := GenesisPermissionlessValidator{ 181 GenesisValidator: GenesisValidator{ 182 StartTime: 3, 183 EndTime: 15, 184 NodeID: nodeID, 185 }, 186 RewardOwner: &Owner{ 187 Threshold: 1, 188 Addresses: []string{addr}, 189 }, 190 Staked: []UTXO{{ 191 Amount: weight, 192 Address: addr, 193 }}, 194 } 195 196 validator3 := GenesisPermissionlessValidator{ 197 GenesisValidator: GenesisValidator{ 198 StartTime: 1, 199 EndTime: 10, 200 NodeID: nodeID, 201 }, 202 RewardOwner: &Owner{ 203 Threshold: 1, 204 Addresses: []string{addr}, 205 }, 206 Staked: []UTXO{{ 207 Amount: weight, 208 Address: addr, 209 }}, 210 } 211 212 args := BuildGenesisArgs{ 213 AvaxAssetID: ids.ID{'d', 'u', 'm', 'm', 'y', ' ', 'I', 'D'}, 214 UTXOs: []UTXO{ 215 utxo, 216 }, 217 Validators: []GenesisPermissionlessValidator{ 218 validator1, 219 validator2, 220 validator3, 221 }, 222 Time: 5, 223 Encoding: formatting.Hex, 224 } 225 reply := BuildGenesisReply{} 226 227 ss := StaticService{} 228 require.NoError(ss.BuildGenesis(nil, &args, &reply)) 229 230 genesisBytes, err := formatting.Decode(reply.Encoding, reply.Bytes) 231 require.NoError(err) 232 233 genesis, err := genesis.Parse(genesisBytes) 234 require.NoError(err) 235 236 validators := genesis.Validators 237 require.Len(validators, 3) 238 } 239 240 func TestUTXOCompare(t *testing.T) { 241 var ( 242 smallerAddr = ids.ShortID{} 243 largerAddr = ids.ShortID{1} 244 ) 245 smallerAddrStr, err := address.FormatBech32("avax", smallerAddr[:]) 246 require.NoError(t, err) 247 largerAddrStr, err := address.FormatBech32("avax", largerAddr[:]) 248 require.NoError(t, err) 249 250 type test struct { 251 name string 252 utxo1 UTXO 253 utxo2 UTXO 254 expected int 255 } 256 tests := []test{ 257 { 258 name: "both empty", 259 utxo1: UTXO{}, 260 utxo2: UTXO{}, 261 expected: 0, 262 }, 263 { 264 name: "locktime smaller", 265 utxo1: UTXO{}, 266 utxo2: UTXO{ 267 Locktime: 1, 268 }, 269 expected: -1, 270 }, 271 { 272 name: "amount smaller", 273 utxo1: UTXO{}, 274 utxo2: UTXO{ 275 Amount: 1, 276 }, 277 expected: -1, 278 }, 279 { 280 name: "address smaller", 281 utxo1: UTXO{ 282 Address: smallerAddrStr, 283 }, 284 utxo2: UTXO{ 285 Address: largerAddrStr, 286 }, 287 expected: -1, 288 }, 289 } 290 291 for _, tt := range tests { 292 t.Run(tt.name, func(t *testing.T) { 293 require := require.New(t) 294 295 require.Equal(tt.expected, tt.utxo1.Compare(tt.utxo2)) 296 require.Equal(-tt.expected, tt.utxo2.Compare(tt.utxo1)) 297 }) 298 } 299 }