github.com/trezor/blockbook@v0.4.1-0.20240328132726-e9a08582ee2c/bchain/coins/dcr/decredparser_test.go (about)

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