OSDN Git Service

90abf410b202383466dd724f7f518ec3f8fa8c0b
[bytom/vapor.git] / common / address_test.go
1 package common
2
3 import (
4         "bytes"
5         "fmt"
6         "reflect"
7         "strings"
8         "testing"
9
10         "github.com/vapor/common/bech32"
11         "github.com/vapor/consensus"
12 )
13
14 func TestAddresses(t *testing.T) {
15         tests := []struct {
16                 name    string
17                 addr    string
18                 encoded string
19                 valid   bool
20                 result  Address
21                 f       func() (Address, error)
22                 net     *consensus.Params
23         }{
24                 // Segwit address tests.
25                 {
26                         name:    "segwit mainnet p2wpkh v0",
27                         addr:    "VBM1QZAPS6230EM2WVR4STEMF46DX2GK9V0LXZ9WEEL",
28                         encoded: "vbm1qzaps6230em2wvr4stemf46dx2gk9v0lxz9weel",
29                         valid:   true,
30                         result: tstAddressWitnessPubKeyHash(
31                                 0,
32                                 [20]byte{
33                                         0x17, 0x43, 0x0d, 0x2a, 0x2f, 0xce, 0xd4, 0xe6, 0x0e, 0xb0,
34                                         0x5e, 0x76, 0x9a, 0xe9, 0xa6, 0x52, 0x2c, 0x56, 0x3f, 0xe6},
35                                 consensus.MainNetParams.Bech32HRPSegwit),
36                         f: func() (Address, error) {
37                                 pkHash := []byte{
38                                         0x17, 0x43, 0x0d, 0x2a, 0x2f, 0xce, 0xd4, 0xe6, 0x0e, 0xb0,
39                                         0x5e, 0x76, 0x9a, 0xe9, 0xa6, 0x52, 0x2c, 0x56, 0x3f, 0xe6}
40                                 return NewAddressWitnessPubKeyHash(pkHash, &consensus.MainNetParams)
41                         },
42                         net: &consensus.MainNetParams,
43                 },
44                 {
45                         name:    "segwit mainnet p2wsh v0",
46                         addr:    "VBM1QSG9QUUNLD2SY752QZ3G8V6NCGHAKZ7GUWSL5HE8PM3CUZXKQQ2AQ3767CL",
47                         encoded: "vbm1qsg9quunld2sy752qz3g8v6ncghakz7guwsl5he8pm3cuzxkqq2aq3767cl",
48                         valid:   true,
49                         result: tstAddressWitnessScriptHash(
50                                 0,
51                                 [32]byte{
52                                         0x82, 0x0a, 0x0e, 0x72, 0x7f, 0x6a, 0xa0, 0x4f,
53                                         0x51, 0x40, 0x14, 0x50, 0x76, 0x6a, 0x78, 0x45,
54                                         0xfb, 0x61, 0x79, 0x1c, 0x74, 0x3f, 0x4b, 0xe4,
55                                         0xe1, 0xdc, 0x71, 0xc1, 0x1a, 0xc0, 0x02, 0xba},
56                                 consensus.MainNetParams.Bech32HRPSegwit),
57                         f: func() (Address, error) {
58                                 scriptHash := []byte{
59                                         0x82, 0x0a, 0x0e, 0x72, 0x7f, 0x6a, 0xa0, 0x4f,
60                                         0x51, 0x40, 0x14, 0x50, 0x76, 0x6a, 0x78, 0x45,
61                                         0xfb, 0x61, 0x79, 0x1c, 0x74, 0x3f, 0x4b, 0xe4,
62                                         0xe1, 0xdc, 0x71, 0xc1, 0x1a, 0xc0, 0x02, 0xba}
63                                 return NewAddressWitnessScriptHash(scriptHash, &consensus.MainNetParams)
64                         },
65                         net: &consensus.MainNetParams,
66                 },
67                 {
68                         name:    "segwit testnet p2wpkh v0",
69                         addr:    "vtm1qpzap59m2kadjwumj8nv4qevfjqwraytjnxap6u",
70                         encoded: "vtm1qpzap59m2kadjwumj8nv4qevfjqwraytjnxap6u",
71                         valid:   true,
72                         result: tstAddressWitnessPubKeyHash(
73                                 0,
74                                 [20]byte{
75                                         0x08, 0xba, 0x1a, 0x17, 0x6a, 0xb7, 0x5b, 0x27, 0x73, 0x72,
76                                         0x3c, 0xd9, 0x50, 0x65, 0x89, 0x90, 0x1c, 0x3e, 0x91, 0x72},
77                                 consensus.TestNetParams.Bech32HRPSegwit),
78                         f: func() (Address, error) {
79                                 pkHash := []byte{
80                                         0x08, 0xba, 0x1a, 0x17, 0x6a, 0xb7, 0x5b, 0x27, 0x73, 0x72,
81                                         0x3c, 0xd9, 0x50, 0x65, 0x89, 0x90, 0x1c, 0x3e, 0x91, 0x72}
82                                 return NewAddressWitnessPubKeyHash(pkHash, &consensus.TestNetParams)
83                         },
84                         net: &consensus.TestNetParams,
85                 },
86                 {
87                         name:    "segwit testnet p2wsh v0",
88                         addr:    "vtm1qf5cwj7fydpgdqgcf5lmwp55zdvykwy5qnrtk08w3uefurkwqztcqgkzap0",
89                         encoded: "vtm1qf5cwj7fydpgdqgcf5lmwp55zdvykwy5qnrtk08w3uefurkwqztcqgkzap0",
90                         valid:   true,
91                         result: tstAddressWitnessScriptHash(
92                                 0,
93                                 [32]byte{
94                                         0x4d, 0x30, 0xe9, 0x79, 0x24, 0x68, 0x50, 0xd0,
95                                         0x23, 0x09, 0xa7, 0xf6, 0xe0, 0xd2, 0x82, 0x6b,
96                                         0x09, 0x67, 0x12, 0x80, 0x98, 0xd7, 0x67, 0x9d,
97                                         0xd1, 0xe6, 0x53, 0xc1, 0xd9, 0xc0, 0x12, 0xf0},
98                                 consensus.TestNetParams.Bech32HRPSegwit),
99                         f: func() (Address, error) {
100                                 scriptHash := []byte{
101                                         0x4d, 0x30, 0xe9, 0x79, 0x24, 0x68, 0x50, 0xd0,
102                                         0x23, 0x09, 0xa7, 0xf6, 0xe0, 0xd2, 0x82, 0x6b,
103                                         0x09, 0x67, 0x12, 0x80, 0x98, 0xd7, 0x67, 0x9d,
104                                         0xd1, 0xe6, 0x53, 0xc1, 0xd9, 0xc0, 0x12, 0xf0}
105                                 return NewAddressWitnessScriptHash(scriptHash, &consensus.TestNetParams)
106                         },
107                         net: &consensus.TestNetParams,
108                 },
109                 /*
110                         {
111                                 name:    "segwit testnet p2wsh witness v0",
112                                 addr:    "tm1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesvkesyk",
113                                 encoded: "tm1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesvkesyk",
114                                 valid:   true,
115                                 result: tstAddressWitnessScriptHash(
116                                         0,
117                                         [32]byte{
118                                                 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62,
119                                                 0x21, 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66,
120                                                 0x36, 0x2b, 0x99, 0xd5, 0xe9, 0x1c, 0x6c, 0xe2,
121                                                 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, 0x33},
122                                         consensus.TestNetParams.Bech32HRPSegwit),
123                                 f: func() (Address, error) {
124                                         scriptHash := []byte{
125                                                 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62,
126                                                 0x21, 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66,
127                                                 0x36, 0x2b, 0x99, 0xd5, 0xe9, 0x1c, 0x6c, 0xe2,
128                                                 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, 0x33}
129                                         return NewAddressWitnessScriptHash(scriptHash, &consensus.TestNetParams)
130                                 },
131                                 net: &consensus.TestNetParams,
132                         },
133                         // Unsupported witness versions (version 0 only supported at this point)
134                         {
135                                 name:  "segwit mainnet witness v1",
136                                 addr:  "bm1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx",
137                                 valid: false,
138                                 net:   &consensus.MainNetParams,
139                         },
140                         {
141                                 name:  "segwit mainnet witness v16",
142                                 addr:  "BM1SW50QA3JX3S",
143                                 valid: false,
144                                 net:   &consensus.MainNetParams,
145                         },
146                         {
147                                 name:  "segwit mainnet witness v2",
148                                 addr:  "bm1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
149                                 valid: false,
150                                 net:   &consensus.MainNetParams,
151                         },
152                         // Invalid segwit addresses
153                         {
154                                 name:  "segwit invalid hrp",
155                                 addr:  "tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty",
156                                 valid: false,
157                                 net:   &consensus.TestNetParams,
158                         },
159                         {
160                                 name:  "segwit invalid checksum",
161                                 addr:  "bm1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5",
162                                 valid: false,
163                                 net:   &consensus.MainNetParams,
164                         },
165                         {
166                                 name:  "segwit invalid witness version",
167                                 addr:  "BM13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2",
168                                 valid: false,
169                                 net:   &consensus.MainNetParams,
170                         },
171                         {
172                                 name:  "segwit invalid program length",
173                                 addr:  "bm1rw5uspcuh",
174                                 valid: false,
175                                 net:   &consensus.MainNetParams,
176                         },
177                         {
178                                 name:  "segwit invalid program length",
179                                 addr:  "bm10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90",
180                                 valid: false,
181                                 net:   &consensus.MainNetParams,
182                         },
183                         {
184                                 name:  "segwit invalid program length for witness version 0 (per BIP141)",
185                                 addr:  "BM1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P",
186                                 valid: false,
187                                 net:   &consensus.MainNetParams,
188                         },
189                         {
190                                 name:  "segwit mixed case",
191                                 addr:  "tm1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7",
192                                 valid: false,
193                                 net:   &consensus.TestNetParams,
194                         },
195                         {
196                                 name:  "segwit zero padding of more than 4 bits",
197                                 addr:  "tm1pw508d6qejxtdg4y5r3zarqfsj6c3",
198                                 valid: false,
199                                 net:   &consensus.TestNetParams,
200                         },
201                         {
202                                 name:  "segwit non-zero padding in 8-to-5 conversion",
203                                 addr:  "tm1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv",
204                                 valid: false,
205                                 net:   &consensus.TestNetParams,
206                         },
207                 */
208         }
209
210         for _, test := range tests {
211                 // Decode addr and compare error against valid.
212                 decoded, err := DecodeAddress(test.addr, test.net)
213                 if (err == nil) != test.valid {
214                         t.Errorf("%v: decoding test failed: %v", test.name, err)
215                         return
216                 }
217
218                 if err == nil {
219                         // Ensure the stringer returns the same address as the
220                         // original.
221
222                         if decodedStringer, ok := decoded.(fmt.Stringer); ok {
223                                 addr := test.addr
224
225                                 // For Segwit addresses the string representation
226                                 // will always be lower case, so in that case we
227                                 // convert the original to lower case first.
228                                 if strings.Contains(test.name, "segwit") {
229                                         addr = strings.ToLower(addr)
230                                 }
231
232                                 if addr != decodedStringer.String() {
233                                         t.Errorf("%v: String on decoded value does not match expected value: %v != %v",
234                                                 test.name, test.addr, decodedStringer.String())
235                                         return
236                                 }
237
238                         }
239
240                         // Encode again and compare against the original.
241                         encoded := decoded.EncodeAddress()
242                         if test.encoded != encoded {
243                                 t.Errorf("%v: decoding and encoding produced different addressess: %v != %v",
244                                         test.name, test.encoded, encoded)
245                                 return
246                         }
247
248                         // Perform type-specific calculations.
249                         var saddr []byte
250                         switch decoded.(type) {
251
252                         case *AddressWitnessPubKeyHash:
253                                 saddr = tstAddressSegwitSAddr(encoded)
254                         case *AddressWitnessScriptHash:
255                                 saddr = tstAddressSegwitSAddr(encoded)
256                         }
257
258                         // Check script address, as well as the Hash160 method for P2PKH and
259                         // P2SH addresses.
260                         if !bytes.Equal(saddr, decoded.ScriptAddress()) {
261                                 t.Errorf("%v: script addresses do not match:\n%x != \n%x",
262                                         test.name, saddr, decoded.ScriptAddress())
263                                 return
264                         }
265                         switch a := decoded.(type) {
266
267                         case *AddressWitnessPubKeyHash:
268                                 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp {
269                                         t.Errorf("%v: hrps do not match:\n%x != \n%x",
270                                                 test.name, test.net.Bech32HRPSegwit, hrp)
271                                         return
272                                 }
273
274                                 expVer := test.result.(*AddressWitnessPubKeyHash).WitnessVersion()
275                                 if v := a.WitnessVersion(); v != expVer {
276                                         t.Errorf("%v: witness versions do not match:\n%x != \n%x",
277                                                 test.name, expVer, v)
278                                         return
279                                 }
280
281                                 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) {
282                                         t.Errorf("%v: witness programs do not match:\n%x != \n%x",
283                                                 test.name, saddr, p)
284                                         return
285                                 }
286
287                         case *AddressWitnessScriptHash:
288                                 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp {
289                                         t.Errorf("%v: hrps do not match:\n%x != \n%x",
290                                                 test.name, test.net.Bech32HRPSegwit, hrp)
291                                         return
292                                 }
293
294                                 expVer := test.result.(*AddressWitnessScriptHash).WitnessVersion()
295                                 if v := a.WitnessVersion(); v != expVer {
296                                         t.Errorf("%v: witness versions do not match:\n%x != \n%x",
297                                                 test.name, expVer, v)
298                                         return
299                                 }
300
301                                 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) {
302                                         t.Errorf("%v: witness programs do not match:\n%x != \n%x",
303                                                 test.name, saddr, p)
304                                         return
305                                 }
306                         }
307
308                         // Ensure the address is for the expected network.
309                         if !decoded.IsForNet(test.net) {
310                                 t.Errorf("%v: calculated network does not match expected",
311                                         test.name)
312                                 return
313                         }
314                 }
315
316                 if !test.valid {
317                         // If address is invalid, but a creation function exists,
318                         // verify that it returns a nil addr and non-nil error.
319                         if test.f != nil {
320                                 _, err := test.f()
321                                 if err == nil {
322                                         t.Errorf("%v: address is invalid but creating new address succeeded",
323                                                 test.name)
324                                         return
325                                 }
326                         }
327                         continue
328                 }
329
330                 // Valid test, compare address created with f against expected result.
331                 addr, err := test.f()
332                 if err != nil {
333                         t.Errorf("%v: address is valid but creating new address failed with error %v",
334                                 test.name, err)
335                         return
336                 }
337
338                 if !reflect.DeepEqual(addr, test.result) {
339                         t.Errorf("%v: created address does not match expected result",
340                                 test.name)
341                         return
342                 }
343         }
344 }
345
346 // TstAddressWitnessPubKeyHash creates an AddressWitnessPubKeyHash, initiating
347 // the fields as given.
348 func tstAddressWitnessPubKeyHash(version byte, program [20]byte,
349         hrp string) *AddressWitnessPubKeyHash {
350
351         return &AddressWitnessPubKeyHash{
352                 hrp:            hrp,
353                 witnessVersion: version,
354                 witnessProgram: program,
355         }
356 }
357
358 // TstAddressWitnessScriptHash creates an AddressWitnessScriptHash, initiating
359 // the fields as given.
360 func tstAddressWitnessScriptHash(version byte, program [32]byte,
361         hrp string) *AddressWitnessScriptHash {
362
363         return &AddressWitnessScriptHash{
364                 hrp:            hrp,
365                 witnessVersion: version,
366                 witnessProgram: program,
367         }
368 }
369
370 // TstAddressSegwitSAddr returns the expected witness program bytes for
371 // bech32 encoded P2WPKH and P2WSH bitcoin addresses.
372 func tstAddressSegwitSAddr(addr string) []byte {
373         _, data, err := bech32.Bech32Decode(addr)
374         if err != nil {
375                 return []byte{}
376         }
377
378         // First byte is version, rest is base 32 encoded data.
379         data, err = bech32.ConvertBits(data[1:], 5, 8, false)
380         if err != nil {
381                 return []byte{}
382         }
383         return data
384 }