OSDN Git Service

add log (#373)
[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:    "VP1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KPSCEPL",
28                         encoded: "vp1qw508d6qejxtdg4y5r3zarvary0c5xw7kpscepl",
29                         valid:   true,
30                         result: tstAddressWitnessPubKeyHash(
31                                 0,
32                                 [20]byte{
33                                         0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94,
34                                         0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6},
35                                 consensus.MainNetParams.Bech32HRPSegwit),
36                         f: func() (Address, error) {
37                                 pkHash := []byte{
38                                         0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94,
39                                         0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6}
40                                 return NewAddressWitnessPubKeyHash(pkHash, &consensus.MainNetParams)
41                         },
42                         net: &consensus.MainNetParams,
43                 },
44                 {
45                         name:    "segwit mainnet p2wsh v0",
46                         addr:    "vp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3ql5u263",
47                         encoded: "vp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3ql5u263",
48                         valid:   true,
49                         result: tstAddressWitnessScriptHash(
50                                 0,
51                                 [32]byte{
52                                         0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68,
53                                         0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13,
54                                         0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1,
55                                         0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62},
56                                 consensus.MainNetParams.Bech32HRPSegwit),
57                         f: func() (Address, error) {
58                                 scriptHash := []byte{
59                                         0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68,
60                                         0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13,
61                                         0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1,
62                                         0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62}
63                                 return NewAddressWitnessScriptHash(scriptHash, &consensus.MainNetParams)
64                         },
65                         net: &consensus.MainNetParams,
66                 },
67                 {
68                         name:    "segwit testnet p2wpkh v0",
69                         addr:    "tp1qw508d6qejxtdg4y5r3zarvary0c5xw7kvj35pt",
70                         encoded: "tp1qw508d6qejxtdg4y5r3zarvary0c5xw7kvj35pt",
71                         valid:   true,
72                         result: tstAddressWitnessPubKeyHash(
73                                 0,
74                                 [20]byte{
75                                         0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94,
76                                         0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6},
77                                 consensus.TestNetParams.Bech32HRPSegwit),
78                         f: func() (Address, error) {
79                                 pkHash := []byte{
80                                         0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94,
81                                         0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6}
82                                 return NewAddressWitnessPubKeyHash(pkHash, &consensus.TestNetParams)
83                         },
84                         net: &consensus.TestNetParams,
85                 },
86                 {
87                         name:    "segwit testnet p2wsh v0",
88                         addr:    "tp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qayxglu",
89                         encoded: "tp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qayxglu",
90                         valid:   true,
91                         result: tstAddressWitnessScriptHash(
92                                 0,
93                                 [32]byte{
94                                         0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68,
95                                         0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13,
96                                         0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1,
97                                         0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62},
98                                 consensus.TestNetParams.Bech32HRPSegwit),
99                         f: func() (Address, error) {
100                                 scriptHash := []byte{
101                                         0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68,
102                                         0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13,
103                                         0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1,
104                                         0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62}
105                                 return NewAddressWitnessScriptHash(scriptHash, &consensus.TestNetParams)
106                         },
107                         net: &consensus.TestNetParams,
108                 },
109                 {
110                         name:    "segwit testnet p2wsh witness v0",
111                         addr:    "tp1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses3jwx7x",
112                         encoded: "tp1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses3jwx7x",
113                         valid:   true,
114                         result: tstAddressWitnessScriptHash(
115                                 0,
116                                 [32]byte{
117                                         0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62,
118                                         0x21, 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66,
119                                         0x36, 0x2b, 0x99, 0xd5, 0xe9, 0x1c, 0x6c, 0xe2,
120                                         0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, 0x33},
121                                 consensus.TestNetParams.Bech32HRPSegwit),
122                         f: func() (Address, error) {
123                                 scriptHash := []byte{
124                                         0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62,
125                                         0x21, 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66,
126                                         0x36, 0x2b, 0x99, 0xd5, 0xe9, 0x1c, 0x6c, 0xe2,
127                                         0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, 0x33}
128                                 return NewAddressWitnessScriptHash(scriptHash, &consensus.TestNetParams)
129                         },
130                         net: &consensus.TestNetParams,
131                 },
132                 // Unsupported witness versions (version 0 only supported at this point)
133                 {
134                         name:  "segwit mainnet witness v1",
135                         addr:  "vp1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx",
136                         valid: false,
137                         net:   &consensus.MainNetParams,
138                 },
139                 {
140                         name:  "segwit mainnet witness v16",
141                         addr:  "VP1SW50QA3JX3S",
142                         valid: false,
143                         net:   &consensus.MainNetParams,
144                 },
145                 {
146                         name:  "segwit mainnet witness v2",
147                         addr:  "vp1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
148                         valid: false,
149                         net:   &consensus.MainNetParams,
150                 },
151                 // Invalid segwit addresses
152                 {
153                         name:  "segwit invalid hrp",
154                         addr:  "tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty",
155                         valid: false,
156                         net:   &consensus.TestNetParams,
157                 },
158                 {
159                         name:  "segwit invalid checksum",
160                         addr:  "vp1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5",
161                         valid: false,
162                         net:   &consensus.MainNetParams,
163                 },
164                 {
165                         name:  "segwit invalid witness version",
166                         addr:  "VP13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2",
167                         valid: false,
168                         net:   &consensus.MainNetParams,
169                 },
170                 {
171                         name:  "segwit invalid program length",
172                         addr:  "vp1rw5uspcuh",
173                         valid: false,
174                         net:   &consensus.MainNetParams,
175                 },
176                 {
177                         name:  "segwit invalid program length",
178                         addr:  "vp10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90",
179                         valid: false,
180                         net:   &consensus.MainNetParams,
181                 },
182                 {
183                         name:  "segwit invalid program length for witness version 0 (per BIP141)",
184                         addr:  "VP1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P",
185                         valid: false,
186                         net:   &consensus.MainNetParams,
187                 },
188                 {
189                         name:  "segwit mixed case",
190                         addr:  "tp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7",
191                         valid: false,
192                         net:   &consensus.TestNetParams,
193                 },
194                 {
195                         name:  "segwit zero padding of more than 4 bits",
196                         addr:  "tp1pw508d6qejxtdg4y5r3zarqfsj6c3",
197                         valid: false,
198                         net:   &consensus.TestNetParams,
199                 },
200                 {
201                         name:  "segwit non-zero padding in 8-to-5 conversion",
202                         addr:  "tp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv",
203                         valid: false,
204                         net:   &consensus.TestNetParams,
205                 },
206         }
207
208         for _, test := range tests {
209                 // Decode addr and compare error against valid.
210                 decoded, err := DecodeAddress(test.addr, test.net)
211                 if (err == nil) != test.valid {
212                         t.Errorf("%v: decoding test failed: %v", test.name, err)
213                         return
214                 }
215
216                 if err == nil {
217                         // Ensure the stringer returns the same address as the
218                         // original.
219
220                         if decodedStringer, ok := decoded.(fmt.Stringer); ok {
221                                 addr := test.addr
222
223                                 // For Segwit addresses the string representation
224                                 // will always be lower case, so in that case we
225                                 // convert the original to lower case first.
226                                 if strings.Contains(test.name, "segwit") {
227                                         addr = strings.ToLower(addr)
228                                 }
229
230                                 if addr != decodedStringer.String() {
231                                         t.Errorf("%v: String on decoded value does not match expected value: %v != %v",
232                                                 test.name, test.addr, decodedStringer.String())
233                                         return
234                                 }
235
236                         }
237
238                         // Encode again and compare against the original.
239                         encoded := decoded.EncodeAddress()
240                         if test.encoded != encoded {
241                                 t.Errorf("%v: decoding and encoding produced different addressess: %v != %v",
242                                         test.name, test.encoded, encoded)
243                                 return
244                         }
245
246                         // Perform type-specific calculations.
247                         var saddr []byte
248                         switch decoded.(type) {
249
250                         case *AddressWitnessPubKeyHash:
251                                 saddr = tstAddressSegwitSAddr(encoded)
252                         case *AddressWitnessScriptHash:
253                                 saddr = tstAddressSegwitSAddr(encoded)
254                         }
255
256                         // Check script address, as well as the Hash160 method for P2PKH and
257                         // P2SH addresses.
258                         if !bytes.Equal(saddr, decoded.ScriptAddress()) {
259                                 t.Errorf("%v: script addresses do not match:\n%x != \n%x",
260                                         test.name, saddr, decoded.ScriptAddress())
261                                 return
262                         }
263                         switch a := decoded.(type) {
264
265                         case *AddressWitnessPubKeyHash:
266                                 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp {
267                                         t.Errorf("%v: hrps do not match:\n%x != \n%x",
268                                                 test.name, test.net.Bech32HRPSegwit, hrp)
269                                         return
270                                 }
271
272                                 expVer := test.result.(*AddressWitnessPubKeyHash).WitnessVersion()
273                                 if v := a.WitnessVersion(); v != expVer {
274                                         t.Errorf("%v: witness versions do not match:\n%x != \n%x",
275                                                 test.name, expVer, v)
276                                         return
277                                 }
278
279                                 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) {
280                                         t.Errorf("%v: witness programs do not match:\n%x != \n%x",
281                                                 test.name, saddr, p)
282                                         return
283                                 }
284
285                         case *AddressWitnessScriptHash:
286                                 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp {
287                                         t.Errorf("%v: hrps do not match:\n%x != \n%x",
288                                                 test.name, test.net.Bech32HRPSegwit, hrp)
289                                         return
290                                 }
291
292                                 expVer := test.result.(*AddressWitnessScriptHash).WitnessVersion()
293                                 if v := a.WitnessVersion(); v != expVer {
294                                         t.Errorf("%v: witness versions do not match:\n%x != \n%x",
295                                                 test.name, expVer, v)
296                                         return
297                                 }
298
299                                 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) {
300                                         t.Errorf("%v: witness programs do not match:\n%x != \n%x",
301                                                 test.name, saddr, p)
302                                         return
303                                 }
304                         }
305
306                         // Ensure the address is for the expected network.
307                         if !decoded.IsForNet(test.net) {
308                                 t.Errorf("%v: calculated network does not match expected",
309                                         test.name)
310                                 return
311                         }
312                 }
313
314                 if !test.valid {
315                         // If address is invalid, but a creation function exists,
316                         // verify that it returns a nil addr and non-nil error.
317                         if test.f != nil {
318                                 _, err := test.f()
319                                 if err == nil {
320                                         t.Errorf("%v: address is invalid but creating new address succeeded",
321                                                 test.name)
322                                         return
323                                 }
324                         }
325                         continue
326                 }
327
328                 // Valid test, compare address created with f against expected result.
329                 addr, err := test.f()
330                 if err != nil {
331                         t.Errorf("%v: address is valid but creating new address failed with error %v",
332                                 test.name, err)
333                         return
334                 }
335
336                 if !reflect.DeepEqual(addr, test.result) {
337                         t.Errorf("%v: created address does not match expected result",
338                                 test.name)
339                         return
340                 }
341         }
342 }
343
344 // TstAddressWitnessPubKeyHash creates an AddressWitnessPubKeyHash, initiating
345 // the fields as given.
346 func tstAddressWitnessPubKeyHash(version byte, program [20]byte,
347         hrp string) *AddressWitnessPubKeyHash {
348
349         return &AddressWitnessPubKeyHash{
350                 hrp:            hrp,
351                 witnessVersion: version,
352                 witnessProgram: program,
353         }
354 }
355
356 // TstAddressWitnessScriptHash creates an AddressWitnessScriptHash, initiating
357 // the fields as given.
358 func tstAddressWitnessScriptHash(version byte, program [32]byte,
359         hrp string) *AddressWitnessScriptHash {
360
361         return &AddressWitnessScriptHash{
362                 hrp:            hrp,
363                 witnessVersion: version,
364                 witnessProgram: program,
365         }
366 }
367
368 // TstAddressSegwitSAddr returns the expected witness program bytes for
369 // bech32 encoded P2WPKH and P2WSH bitcoin addresses.
370 func tstAddressSegwitSAddr(addr string) []byte {
371         _, data, err := bech32.Bech32Decode(addr)
372         if err != nil {
373                 return []byte{}
374         }
375
376         // First byte is version, rest is base 32 encoded data.
377         data, err = bech32.ConvertBits(data[1:], 5, 8, false)
378         if err != nil {
379                 return []byte{}
380         }
381         return data
382 }