github.com/cerberus-wallet/blockbook@v0.3.2/bchain/coins/dcr/decredparser_test.go (about) 1 // +build unittest 2 3 package dcr 4 5 import ( 6 "blockbook/bchain" 7 "blockbook/bchain/coins/btc" 8 "encoding/hex" 9 "math/big" 10 "os" 11 "reflect" 12 "testing" 13 ) 14 15 var ( 16 testnetParser, mainnetParser *DecredParser 17 18 testTx1 = bchain.Tx{ 19 Hex: "01000000012372568fe80d2f9b2ab17226158dd5732d9926dc705371eaf40ab748c9e3d9720200000001ffffffff02644b252d0000000000001976a914a862f83733cc368f386a651e03d844a5bd6116d588acacdf63090000000000001976a91491dc5d18370939b3414603a0729bcb3a38e4ef7688ac000000000000000001e48d893600000000bb3d0000020000006a4730440220378e1442cc17fa7e49184518713eedd30e13e42147e077859557da6ffbbd40c702205f85563c28b6287f9c9110e6864dd18acfd92d85509ea846913c28b6e8a7f940012102bbbd7aadef33f2d2bdd9b0c5ba278815f5d66a6a01d2c019fb73f697662038b5", 20 Blocktime: 1535632670, 21 Time: 1535632670, 22 Txid: "132acb5b474b45b830f7961c91c87e53cce3a37a6c6f0b0933ccdf0395c81a6a", 23 LockTime: 0, 24 Version: 1, 25 Vin: []bchain.Vin{ 26 { 27 Txid: "72d9e3c948b70af4ea715370dc26992d73d58d152672b12a9b2f0de88f567223", 28 Vout: 2, 29 Sequence: 4294967295, 30 }, 31 }, 32 Vout: []bchain.Vout{ 33 { 34 ValueSat: *big.NewInt(757418852), 35 N: 0, 36 ScriptPubKey: bchain.ScriptPubKey{ 37 Hex: "76a914a862f83733cc368f386a651e03d844a5bd6116d588ac", 38 Addresses: []string{ 39 "TsgNUZKEnUhFASLESj7fVRTkgue3QR9TAeZ", 40 }, 41 }, 42 }, 43 { 44 ValueSat: *big.NewInt(157540268), 45 N: 1, 46 ScriptPubKey: bchain.ScriptPubKey{ 47 Hex: "76a91491dc5d18370939b3414603a0729bcb3a38e4ef7688ac", 48 Addresses: []string{ 49 "TseKNSWYbAzaGogpnNn25teTz53PTk3sgPu", 50 }, 51 }, 52 }, 53 }, 54 } 55 56 testTx2 = bchain.Tx{ 57 Hex: "0100000001193c189c71dff482b70ccb10ec9cf0ea3421a7fc51e4c7b0cf59c98a293a2f960200000000ffffffff027c87f00b0000000000001976a91418f10131a859912119c4a8510199f87f0a4cec2488ac9889495f0000000000001976a914631fb783b1e06c3f6e71777e16da6de13450465e88ac0000000000000000015ced3d6b0000000030740000000000006a47304402204e6afc21f6d065b9c082dad81a5f29136320e2b54c6cdf6b8722e4507e1a8d8902203933c5e592df3b0bbb0568f121f48ef6cbfae9cf479a57229742b5780dedc57a012103b89bb443b6ab17724458285b302291b082c59e5a022f273af0f61d47a414a537", 58 Txid: "7058766ffef2e9cee61ee4b7604a39bc91c3000cb951c4f93f3307f6e0bf4def", 59 Blocktime: 1463843967, 60 Time: 1463843967, 61 LockTime: 0, 62 Version: 1, 63 Vin: []bchain.Vin{ 64 { 65 Txid: "962f3a298ac959cfb0c7e451fca72134eaf09cec10cb0cb782f4df719c183c19", 66 Vout: 2, 67 Sequence: 4294967295, 68 ScriptSig: bchain.ScriptSig{ 69 Hex: "47304402204e6afc21f6d065b9c082dad81a5f29136320e2b54c6cdf6b8722e4507e1a8d8902203933c5e592df3b0bbb0568f121f48ef6cbfae9cf479a57229742b5780dedc57a012103b89bb443b6ab17724458285b302291b082c59e5a022f273af0f61d47a414a537", 70 }, 71 }, 72 }, 73 Vout: []bchain.Vout{ 74 { 75 ValueSat: *big.NewInt(200312700), 76 N: 0, 77 ScriptPubKey: bchain.ScriptPubKey{ 78 Hex: "76a91418f10131a859912119c4a8510199f87f0a4cec2488ac", 79 Addresses: []string{ 80 "DsTEnRLDEjQNeQ4A47fdS2pqtaFrGNzkqNa", 81 }, 82 }, 83 }, 84 { 85 ValueSat: *big.NewInt(1598654872), 86 N: 1, 87 ScriptPubKey: bchain.ScriptPubKey{ 88 Hex: "76a914631fb783b1e06c3f6e71777e16da6de13450465e88ac", 89 Addresses: []string{ 90 "Dsa12P9VnCd55hTnUXpvGgFKSeGkFkzRvYb", 91 }, 92 }, 93 }, 94 }, 95 } 96 97 testTx3 = bchain.Tx{ 98 Hex: "0100000001c56d80756eaa7fc6e3542b29f596c60a9bcc959cf04d5f6e6b12749e241ece290200000001ffffffff02cf20b42d0000000000001976a9140799daa3cd36b44def220886802eb99e10c4a7c488ac0c25c7070000000000001976a9140b102deb3314213164cb6322211225365658407e88ac000000000000000001afa87b3500000000e33d0000000000006a47304402201ff342e5aa55b6030171f85729221ca0b81938826cc09449b77752e6e3b615be0220281e160b618e57326b95a0e0c3ac7a513bd041aba63cbace2f71919e111cfdba01210290a8de6665c8caac2bb8ca1aabd3dc09a334f997f97bd894772b1e51cab003d9", 99 Blocktime: 1535638326, 100 Time: 1535638326, 101 Txid: "caf34c934d4c36b410c0265222b069f52e2df459ebb09d6797a635ceee0edd60", 102 LockTime: 0, 103 Version: 1, 104 Vin: []bchain.Vin{ 105 { 106 Txid: "29ce1e249e74126b6e5f4df09c95cc9b0ac696f5292b54e3c67faa6e75806dc5", 107 Vout: 2, 108 Sequence: 4294967295, 109 }, 110 }, 111 Vout: []bchain.Vout{ 112 { 113 ValueSat: *big.NewInt(766779599), 114 N: 0, 115 ScriptPubKey: bchain.ScriptPubKey{ 116 Hex: "76a9140799daa3cd36b44def220886802eb99e10c4a7c488ac", 117 Addresses: []string{ 118 "TsRiKWsS9ucaqYDw9qhg6NukTthS5LwTRnv", 119 }, 120 }, 121 }, 122 { 123 ValueSat: *big.NewInt(13049166), 124 N: 1, 125 ScriptPubKey: bchain.ScriptPubKey{ 126 Hex: "76a9140b102deb3314213164cb6322211225365658407e88ac", 127 Addresses: []string{ 128 "TsS2dHqESY1vffjddpo1VMTbwLnDspfEj5W", 129 }, 130 }, 131 }, 132 }, 133 } 134 ) 135 136 func TestMain(m *testing.M) { 137 testnetParser = NewDecredParser(GetChainParams("testnet3"), &btc.Configuration{Slip44: 1}) 138 mainnetParser = NewDecredParser(GetChainParams("mainnet"), &btc.Configuration{Slip44: 42}) 139 exitCode := m.Run() 140 os.Exit(exitCode) 141 } 142 143 func TestGetAddrDescFromAddress(t *testing.T) { 144 type args struct { 145 address string 146 } 147 tests := []struct { 148 name string 149 args args 150 want string 151 wantErr bool 152 }{ 153 { 154 name: "P2PKH", 155 args: args{address: "TcrypGAcGCRVXrES7hWqVZb5oLJKCZEtoL1"}, 156 want: "5463727970474163474352565872455337685771565a62356f4c4a4b435a45746f4c31", 157 wantErr: false, 158 }, 159 { 160 name: "P2PKH", 161 args: args{address: "TsfDLrRkk9ciUuwfp2b8PawwnukYD7yAjGd"}, 162 want: "547366444c72526b6b3963695575776670326238506177776e756b59443779416a4764", 163 wantErr: false, 164 }, 165 { 166 name: "P2PKH", 167 args: args{address: "TsTevp3WYTiV3X1qjvZqa7nutuTqt5VNeoU"}, 168 want: "547354657670335759546956335831716a765a7161376e75747554717435564e656f55", 169 wantErr: false, 170 }, 171 } 172 173 for _, tt := range tests { 174 t.Run(tt.name, func(t *testing.T) { 175 got, err := testnetParser.GetAddrDescFromAddress(tt.args.address) 176 if (err != nil) != tt.wantErr { 177 t.Fatalf("GetAddrDescFromAddress() error = %v, wantErr %v", err, tt.wantErr) 178 } 179 h := hex.EncodeToString(got) 180 if !reflect.DeepEqual(h, tt.want) { 181 t.Errorf("GetAddrDescFromAddress() = %v, want %v", h, tt.want) 182 } 183 }) 184 } 185 } 186 187 func TestGetAddrDescFromVout(t *testing.T) { 188 type args struct { 189 vout bchain.Vout 190 } 191 tests := []struct { 192 name string 193 args args 194 want string 195 wantErr bool 196 }{ 197 { 198 name: "P2PK", 199 args: args{vout: bchain.Vout{ScriptPubKey: bchain.ScriptPubKey{Hex: "76a914936f3a56a2dd0fb3bfde6bc820d4643e1701542a88ac"}}}, 200 want: "54736554683431516f356b594c3337614c474d535167346e67636f71396a7a44583659", 201 wantErr: false, 202 }, 203 { 204 name: "P2PK", 205 args: args{vout: bchain.Vout{ScriptPubKey: bchain.ScriptPubKey{Hex: "76a9144b31f712b03837b1303cddcb1ae9abd98da44f1088ac"}}}, 206 want: "547358736a3161747744736455746e354455576b666f6d5a586e4a6151467862395139", 207 wantErr: false, 208 }, 209 { 210 name: "P2PK", 211 args: args{vout: bchain.Vout{ScriptPubKey: bchain.ScriptPubKey{Hex: "76a9140d85a1d3f77383eb3dacfd83c46e2c7915aba91d88ac"}}}, 212 want: "54735346644c79657942776e68486978737367784b34546f4664763876525931793871", 213 wantErr: false, 214 }, 215 } 216 217 for _, tt := range tests { 218 t.Run(tt.name, func(t *testing.T) { 219 got, err := testnetParser.GetAddrDescFromVout(&tt.args.vout) 220 if (err != nil) != tt.wantErr { 221 t.Fatalf("GetAddrDescFromVout() error = %v, wantErr %v", err, tt.wantErr) 222 } 223 h := hex.EncodeToString(got) 224 if !reflect.DeepEqual(h, tt.want) { 225 t.Errorf("GetAddrDescFromVout() = %v, want %v", h, tt.want) 226 } 227 }) 228 } 229 } 230 231 func TestGetAddressesFromAddrDesc(t *testing.T) { 232 type args struct { 233 script string 234 } 235 tests := []struct { 236 name string 237 args args 238 want []string 239 want2 bool 240 wantErr bool 241 }{ 242 { 243 name: "P2PKH", 244 args: args{script: "5463727970474163474352565872455337685771565a62356f4c4a4b435a45746f4c31"}, 245 want: []string{"TcrypGAcGCRVXrES7hWqVZb5oLJKCZEtoL1"}, 246 want2: true, 247 wantErr: false, 248 }, 249 { 250 name: "P2PKH", 251 args: args{script: "547366444c72526b6b3963695575776670326238506177776e756b59443779416a4764"}, 252 want: []string{"TsfDLrRkk9ciUuwfp2b8PawwnukYD7yAjGd"}, 253 want2: true, 254 wantErr: false, 255 }, 256 { 257 name: "P2PKH", 258 args: args{script: "547354657670335759546956335831716a765a7161376e75747554717435564e656f55"}, 259 want: []string{"TsTevp3WYTiV3X1qjvZqa7nutuTqt5VNeoU"}, 260 want2: true, 261 wantErr: false, 262 }, 263 } 264 265 for _, tt := range tests { 266 t.Run(tt.name, func(t *testing.T) { 267 b, _ := hex.DecodeString(tt.args.script) 268 got, got2, err := testnetParser.GetAddressesFromAddrDesc(b) 269 if (err != nil) != tt.wantErr { 270 t.Fatalf("GetAddressesFromAddrDesc() error = %v, wantErr %v", err, tt.wantErr) 271 } 272 if !reflect.DeepEqual(got, tt.want) { 273 t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got, tt.want) 274 } 275 if !reflect.DeepEqual(got2, tt.want2) { 276 t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got2, tt.want2) 277 } 278 }) 279 } 280 } 281 282 func TestDeriveAddressDescriptors(t *testing.T) { 283 type args struct { 284 xpub string 285 change uint32 286 indexes []uint32 287 parser *DecredParser 288 } 289 tests := []struct { 290 name string 291 args args 292 want []string 293 wantErr bool 294 }{ 295 { 296 name: "m/44'/42'/0'", 297 args: args{ 298 xpub: "dpubZFYFpu8cZxwrApmtot59LZLChk5JcdB8xCxVQ4pcsTig4fscH3EfAkhxcKKhXBQH6SGyYs2VDidoomA5qukTWMaHDkBsAtnpodAHm61ozbD", 299 change: 0, 300 indexes: []uint32{0, 5}, 301 parser: mainnetParser, 302 }, 303 want: []string{"DsUPx4NgAJzUQFRXnn2XZnWwEeQkQpwhqFD", "DsaT4kaGCeJU1Fef721J2DNt8UgcrmE2UsD"}, 304 }, 305 { 306 name: "m/44'/42'/1'", 307 args: args{ 308 xpub: "dpubZFYFpu8cZxwrESo75eazNjVHtC4nWJqL5aXxExZHKnyvZxKirkpypbgeJhVzhTdfnK2986DLjich4JQqcSaSyxu5KSoZ25KJ67j4mQJ9iqx", 309 change: 0, 310 indexes: []uint32{0, 5}, 311 parser: mainnetParser, 312 }, 313 want: []string{"DsX5px9k9XZKFNP2Z9kyZBbfHgecm1ftNz6", "Dshjbo35CSWwNo7xMgG7UM8AWykwEjJ5DCP"}, 314 }, 315 { 316 name: "m/44'/1'/0'", 317 args: args{ 318 xpub: "tpubVossdTiJthe9xZZ5rz47szxN6ncpLJ4XmtJS26hKciDUPtboikdwHKZPWfo4FWYuLRZ6MNkLjyPRKhxqjStBTV2BE1LCULznpqsFakkPfPr", 319 change: 0, 320 indexes: []uint32{0, 2}, 321 parser: testnetParser, 322 }, 323 want: []string{"TsboBwzpaH831s9J63XDcDx5GbKLcwv9ujo", "TsXrNt9nP3kBUM2Wr3rQGoPrpL7RMMSJyJH"}, 324 }, 325 { 326 name: "m/44'/1'/1'", 327 args: args{ 328 xpub: "tpubVossdTiJtheA1fQniKn9EN1JE1Eq1kBofaq2KwywrvuNhAk1KsEM7J2r8anhMJUmmcn9Wmoh73EctpW7Vxs3gS8cbF7N3m4zVjzuyvBj3qC", 329 change: 0, 330 indexes: []uint32{0, 3}, 331 parser: testnetParser, 332 }, 333 want: []string{"TsndBjzcwZVjoZEuqYKwiMbCJH9QpkEekg4", "TsbrkVdFciW3Lfh1W8qjwRY9uSbdiBmY4VP"}, 334 }, 335 } 336 for _, tt := range tests { 337 t.Run(tt.name, func(t *testing.T) { 338 got, err := tt.args.parser.DeriveAddressDescriptors(tt.args.xpub, tt.args.change, tt.args.indexes) 339 if (err != nil) != tt.wantErr { 340 t.Errorf("DeriveAddressDescriptorsFromTo() error = %v, wantErr %v", err, tt.wantErr) 341 return 342 } 343 gotAddresses := make([]string, len(got)) 344 for i, ad := range got { 345 aa, _, err := tt.args.parser.GetAddressesFromAddrDesc(ad) 346 if err != nil || len(aa) != 1 { 347 t.Errorf("DeriveAddressDescriptorsFromTo() got incorrect address descriptor %v, error %v", ad, err) 348 return 349 } 350 gotAddresses[i] = aa[0] 351 } 352 if !reflect.DeepEqual(gotAddresses, tt.want) { 353 t.Errorf("DeriveAddressDescriptorsFromTo() = %v, want %v", gotAddresses, tt.want) 354 } 355 }) 356 } 357 } 358 359 func TestDeriveAddressDescriptorsFromTo(t *testing.T) { 360 type args struct { 361 xpub string 362 change uint32 363 fromIndex uint32 364 toIndex uint32 365 parser *DecredParser 366 } 367 tests := []struct { 368 name string 369 args args 370 want []string 371 wantErr bool 372 }{ 373 { 374 name: "m/44'/42'/2'", 375 args: args{ 376 xpub: "dpubZFYFpu8cZxwrGnWbdHmvsAcTaMve4W9EAUiSHzXp1c5hQvfeWgk7LxsE5LqopwfxV62CoB51fxw97YaNpdA3tdo4GHbLxtUzRmYcUtVPYUi", 377 change: 0, 378 fromIndex: 0, 379 toIndex: 1, 380 parser: mainnetParser, 381 }, 382 want: []string{"Dshtd1N7pKw814wgWXUq5qFVC5ENQ9oSGK7"}, 383 }, 384 { 385 name: "m/44'/42'/1'", 386 args: args{ 387 xpub: "dpubZFYFpu8cZxwrESo75eazNjVHtC4nWJqL5aXxExZHKnyvZxKirkpypbgeJhVzhTdfnK2986DLjich4JQqcSaSyxu5KSoZ25KJ67j4mQJ9iqx", 388 change: 0, 389 fromIndex: 0, 390 toIndex: 1, 391 parser: mainnetParser, 392 }, 393 want: []string{"DsX5px9k9XZKFNP2Z9kyZBbfHgecm1ftNz6"}, 394 }, 395 { 396 name: "m/44'/1'/2'", 397 args: args{ 398 xpub: "tpubVossdTiJtheA51AuNQZtqvKUbhM867Von8XBadxX3tRkDm71kyyi6U966jDPEw9RnQjNcQLwxYSnQ9kBjZxrxfmSbByRbz7D1PLjgAPmL42", 399 change: 0, 400 fromIndex: 0, 401 toIndex: 1, 402 parser: testnetParser, 403 }, 404 want: []string{"TsSpo87rBG21PLvvbzFk2Ust2Dbyvjfn8pQ"}, 405 }, 406 { 407 name: "m/44'/1'/1'", 408 args: args{ 409 xpub: "tpubVossdTiJtheA1fQniKn9EN1JE1Eq1kBofaq2KwywrvuNhAk1KsEM7J2r8anhMJUmmcn9Wmoh73EctpW7Vxs3gS8cbF7N3m4zVjzuyvBj3qC", 410 change: 0, 411 fromIndex: 0, 412 toIndex: 5, 413 parser: testnetParser, 414 }, 415 want: []string{"TsndBjzcwZVjoZEuqYKwiMbCJH9QpkEekg4", "TshWHbnPAVCDARTcCfTEQyL9SzeHxxexX4J", "TspE6pMdC937UHHyfYJpTiKi6vPj5rVnWiG", 416 "TsbrkVdFciW3Lfh1W8qjwRY9uSbdiBmY4VP", "TsagMXjC4Xj6ckPEJh8f1RKHU4cEzTtdVW6"}, 417 }, 418 } 419 for _, tt := range tests { 420 t.Run(tt.name, func(t *testing.T) { 421 got, err := tt.args.parser.DeriveAddressDescriptorsFromTo(tt.args.xpub, tt.args.change, tt.args.fromIndex, tt.args.toIndex) 422 if (err != nil) != tt.wantErr { 423 t.Errorf("DeriveAddressDescriptorsFromTo() error = %v, wantErr %v", err, tt.wantErr) 424 return 425 } 426 gotAddresses := make([]string, len(got)) 427 for i, ad := range got { 428 aa, _, err := tt.args.parser.GetAddressesFromAddrDesc(ad) 429 if err != nil || len(aa) != 1 { 430 t.Errorf("DeriveAddressDescriptorsFromTo() got incorrect address descriptor %v, error %v", ad, err) 431 return 432 } 433 gotAddresses[i] = aa[0] 434 } 435 if !reflect.DeepEqual(gotAddresses, tt.want) { 436 t.Errorf("DeriveAddressDescriptorsFromTo() = %v, want %v", gotAddresses, tt.want) 437 } 438 }) 439 } 440 } 441 442 func TestDerivationBasePath(t *testing.T) { 443 tests := []struct { 444 name string 445 xpub string 446 parser *DecredParser 447 }{ 448 { 449 name: "m/44'/42'/2'", 450 xpub: "dpubZFYFpu8cZxwrGnWbdHmvsAcTaMve4W9EAUiSHzXp1c5hQvfeWgk7LxsE5LqopwfxV62CoB51fxw97YaNpdA3tdo4GHbLxtUzRmYcUtVPYUi", 451 parser: mainnetParser, 452 }, 453 { 454 name: "m/44'/42'/1'", 455 xpub: "dpubZFYFpu8cZxwrESo75eazNjVHtC4nWJqL5aXxExZHKnyvZxKirkpypbgeJhVzhTdfnK2986DLjich4JQqcSaSyxu5KSoZ25KJ67j4mQJ9iqx", 456 parser: mainnetParser, 457 }, 458 { 459 name: "m/44'/1'/2'", 460 xpub: "tpubVossdTiJtheA51AuNQZtqvKUbhM867Von8XBadxX3tRkDm71kyyi6U966jDPEw9RnQjNcQLwxYSnQ9kBjZxrxfmSbByRbz7D1PLjgAPmL42", 461 parser: testnetParser, 462 }, 463 { 464 name: "m/44'/1'/1'", 465 xpub: "tpubVossdTiJtheA1fQniKn9EN1JE1Eq1kBofaq2KwywrvuNhAk1KsEM7J2r8anhMJUmmcn9Wmoh73EctpW7Vxs3gS8cbF7N3m4zVjzuyvBj3qC", 466 parser: testnetParser, 467 }, 468 } 469 470 for _, tt := range tests { 471 t.Run(tt.name, func(t *testing.T) { 472 got, err := tt.parser.DerivationBasePath(tt.xpub) 473 if err != nil { 474 t.Errorf("DerivationBasePath() expected no error but got %v", err) 475 return 476 } 477 478 if got != tt.name { 479 t.Errorf("DerivationBasePath() = %v, want %v", got, tt.name) 480 } 481 }) 482 } 483 } 484 485 func TestPackAndUnpack(t *testing.T) { 486 tests := []struct { 487 name string 488 txInfo *bchain.Tx 489 height uint32 490 parser *DecredParser 491 }{ 492 { 493 name: "Test_1", 494 txInfo: &testTx1, 495 height: 15819, 496 parser: testnetParser, 497 }, 498 { 499 name: "Test_2", 500 txInfo: &testTx2, 501 height: 300000, 502 parser: mainnetParser, 503 }, 504 { 505 name: "Test_3", 506 txInfo: &testTx3, 507 height: 15859, 508 parser: testnetParser, 509 }, 510 } 511 512 for _, tt := range tests { 513 t.Run(tt.name, func(t *testing.T) { 514 packedTx, err := tt.parser.PackTx(tt.txInfo, tt.height, tt.txInfo.Blocktime) 515 if err != nil { 516 t.Errorf("PackTx() expected no error but got %v", err) 517 return 518 } 519 520 unpackedtx, gotHeight, err := tt.parser.UnpackTx(packedTx) 521 if err != nil { 522 t.Errorf("PackTx() expected no error but got %v", err) 523 return 524 } 525 526 if !reflect.DeepEqual(tt.txInfo, unpackedtx) { 527 t.Errorf("TestPackAndUnpack() expected the raw tx and the unpacked tx to match but they didn't") 528 } 529 530 if gotHeight != tt.height { 531 t.Errorf("TestPackAndUnpack() = got height %v, but want %v", gotHeight, tt.height) 532 } 533 }) 534 } 535 536 }