OSDN Git Service

Merge pull request #1137 from Bytom/v1.0.3_fix
[bytom/bytom.git] / account / builder_test.go
1 package account
2
3 import (
4         "encoding/hex"
5         "encoding/json"
6         "testing"
7
8         "github.com/bytom/blockchain/txbuilder"
9         "github.com/bytom/crypto/ed25519/chainkd"
10         chainjson "github.com/bytom/encoding/json"
11         "github.com/bytom/protocol/bc"
12         "github.com/bytom/testutil"
13 )
14
15 func TestMergeSpendAction(t *testing.T) {
16         testBTM := &bc.AssetID{}
17         if err := testBTM.UnmarshalText([]byte("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); err != nil {
18                 t.Fatal(err)
19         }
20
21         testAssetID1 := &bc.AssetID{}
22         if err := testAssetID1.UnmarshalText([]byte("50ec80b6bc48073f6aa8fa045131a71213c33f3681203b15ddc2e4b81f1f4730")); err != nil {
23                 t.Fatal(err)
24         }
25
26         testAssetID2 := &bc.AssetID{}
27         if err := testAssetID2.UnmarshalText([]byte("43c6946d092b2959c1a82e90b282c68fca63e66de289048f6acd6cea9383c79c")); err != nil {
28                 t.Fatal(err)
29         }
30
31         cases := []struct {
32                 testActions     []txbuilder.Action
33                 wantActions     []txbuilder.Action
34                 testActionCount int
35                 wantActionCount int
36         }{
37                 {
38                         testActions: []txbuilder.Action{
39                                 txbuilder.Action(&spendAction{
40                                         AssetAmount: bc.AssetAmount{
41                                                 AssetId: testBTM,
42                                                 Amount:  100,
43                                         },
44                                         AccountID: "test_account",
45                                 }),
46                                 txbuilder.Action(&spendAction{
47                                         AssetAmount: bc.AssetAmount{
48                                                 AssetId: testBTM,
49                                                 Amount:  200,
50                                         },
51                                         AccountID: "test_account",
52                                 }),
53                                 txbuilder.Action(&spendAction{
54                                         AssetAmount: bc.AssetAmount{
55                                                 AssetId: testBTM,
56                                                 Amount:  300,
57                                         },
58                                         AccountID: "test_account",
59                                 }),
60                                 txbuilder.Action(&spendAction{
61                                         AssetAmount: bc.AssetAmount{
62                                                 AssetId: testAssetID1,
63                                                 Amount:  300,
64                                         },
65                                         AccountID: "test_account",
66                                 }),
67                         },
68                         wantActions: []txbuilder.Action{
69                                 txbuilder.Action(&spendAction{
70                                         AssetAmount: bc.AssetAmount{
71                                                 AssetId: testBTM,
72                                                 Amount:  600,
73                                         },
74                                         AccountID: "test_account",
75                                 }),
76                                 txbuilder.Action(&spendAction{
77                                         AssetAmount: bc.AssetAmount{
78                                                 AssetId: testAssetID1,
79                                                 Amount:  300,
80                                         },
81                                         AccountID: "test_account",
82                                 }),
83                         },
84                         testActionCount: 4,
85                         wantActionCount: 2,
86                 },
87                 {
88                         testActions: []txbuilder.Action{
89                                 txbuilder.Action(&spendAction{
90                                         AssetAmount: bc.AssetAmount{
91                                                 AssetId: testBTM,
92                                                 Amount:  100,
93                                         },
94                                         AccountID: "test_account",
95                                 }),
96                                 txbuilder.Action(&spendAction{
97                                         AssetAmount: bc.AssetAmount{
98                                                 AssetId: testAssetID1,
99                                                 Amount:  200,
100                                         },
101                                         AccountID: "test_account",
102                                 }),
103                                 txbuilder.Action(&spendAction{
104                                         AssetAmount: bc.AssetAmount{
105                                                 AssetId: testBTM,
106                                                 Amount:  500,
107                                         },
108                                         AccountID: "test_account",
109                                 }),
110                                 txbuilder.Action(&spendAction{
111                                         AssetAmount: bc.AssetAmount{
112                                                 AssetId: testAssetID1,
113                                                 Amount:  300,
114                                         },
115                                         AccountID: "test_account",
116                                 }),
117                         },
118                         wantActions: []txbuilder.Action{
119                                 txbuilder.Action(&spendAction{
120                                         AssetAmount: bc.AssetAmount{
121                                                 AssetId: testBTM,
122                                                 Amount:  600,
123                                         },
124                                         AccountID: "test_account",
125                                 }),
126                                 txbuilder.Action(&spendAction{
127                                         AssetAmount: bc.AssetAmount{
128                                                 AssetId: testAssetID1,
129                                                 Amount:  500,
130                                         },
131                                         AccountID: "test_account",
132                                 }),
133                         },
134                         testActionCount: 4,
135                         wantActionCount: 2,
136                 },
137                 {
138                         testActions: []txbuilder.Action{
139                                 txbuilder.Action(&spendAction{
140                                         AssetAmount: bc.AssetAmount{
141                                                 AssetId: testBTM,
142                                                 Amount:  100,
143                                         },
144                                         AccountID: "test_account",
145                                 }),
146                                 txbuilder.Action(&spendAction{
147                                         AssetAmount: bc.AssetAmount{
148                                                 AssetId: testAssetID1,
149                                                 Amount:  200,
150                                         },
151                                         AccountID: "test_account",
152                                 }),
153                                 txbuilder.Action(&spendAction{
154                                         AssetAmount: bc.AssetAmount{
155                                                 AssetId: testAssetID2,
156                                                 Amount:  300,
157                                         },
158                                         AccountID: "test_account",
159                                 }),
160                                 txbuilder.Action(&spendAction{
161                                         AssetAmount: bc.AssetAmount{
162                                                 AssetId: testAssetID1,
163                                                 Amount:  300,
164                                         },
165                                         AccountID: "test_account",
166                                 }),
167                                 txbuilder.Action(&spendAction{
168                                         AssetAmount: bc.AssetAmount{
169                                                 AssetId: testAssetID2,
170                                                 Amount:  500,
171                                         },
172                                         AccountID: "test_account",
173                                 }),
174                         },
175                         wantActions: []txbuilder.Action{
176                                 txbuilder.Action(&spendAction{
177                                         AssetAmount: bc.AssetAmount{
178                                                 AssetId: testBTM,
179                                                 Amount:  100,
180                                         },
181                                         AccountID: "test_account",
182                                 }),
183                                 txbuilder.Action(&spendAction{
184                                         AssetAmount: bc.AssetAmount{
185                                                 AssetId: testAssetID1,
186                                                 Amount:  500,
187                                         },
188                                         AccountID: "test_account",
189                                 }),
190                                 txbuilder.Action(&spendAction{
191                                         AssetAmount: bc.AssetAmount{
192                                                 AssetId: testAssetID2,
193                                                 Amount:  800,
194                                         },
195                                         AccountID: "test_account",
196                                 }),
197                         },
198                         testActionCount: 5,
199                         wantActionCount: 3,
200                 },
201                 {
202                         testActions: []txbuilder.Action{
203                                 txbuilder.Action(&spendAction{
204                                         AssetAmount: bc.AssetAmount{
205                                                 AssetId: testBTM,
206                                                 Amount:  100,
207                                         },
208                                         AccountID: "test_account",
209                                 }),
210                                 txbuilder.Action(&spendAction{
211                                         AssetAmount: bc.AssetAmount{
212                                                 AssetId: testBTM,
213                                                 Amount:  200,
214                                         },
215                                         AccountID: "test_account1",
216                                 }),
217                                 txbuilder.Action(&spendAction{
218                                         AssetAmount: bc.AssetAmount{
219                                                 AssetId: testBTM,
220                                                 Amount:  500,
221                                         },
222                                         AccountID: "test_account",
223                                 }),
224                                 txbuilder.Action(&spendAction{
225                                         AssetAmount: bc.AssetAmount{
226                                                 AssetId: testAssetID1,
227                                                 Amount:  300,
228                                         },
229                                         AccountID: "test_account1",
230                                 }),
231                         },
232                         wantActions: []txbuilder.Action{
233                                 txbuilder.Action(&spendAction{
234                                         AssetAmount: bc.AssetAmount{
235                                                 AssetId: testBTM,
236                                                 Amount:  600,
237                                         },
238                                         AccountID: "test_account",
239                                 }),
240                                 txbuilder.Action(&spendAction{
241                                         AssetAmount: bc.AssetAmount{
242                                                 AssetId: testBTM,
243                                                 Amount:  200,
244                                         },
245                                         AccountID: "test_account1",
246                                 }),
247                                 txbuilder.Action(&spendAction{
248                                         AssetAmount: bc.AssetAmount{
249                                                 AssetId: testAssetID1,
250                                                 Amount:  300,
251                                         },
252                                         AccountID: "test_account1",
253                                 }),
254                         },
255                         testActionCount: 4,
256                         wantActionCount: 3,
257                 },
258                 {
259                         testActions: []txbuilder.Action{
260                                 txbuilder.Action(&spendUTXOAction{
261                                         OutputID: &bc.Hash{V0: 128},
262                                 }),
263                                 txbuilder.Action(&spendAction{
264                                         AssetAmount: bc.AssetAmount{
265                                                 AssetId: testBTM,
266                                                 Amount:  100,
267                                         },
268                                         AccountID: "test_account",
269                                 }),
270                                 txbuilder.Action(&spendAction{
271                                         AssetAmount: bc.AssetAmount{
272                                                 AssetId: testAssetID1,
273                                                 Amount:  200,
274                                         },
275                                         AccountID: "test_account1",
276                                 }),
277                                 txbuilder.Action(&spendUTXOAction{
278                                         OutputID: &bc.Hash{V0: 256},
279                                 }),
280                                 txbuilder.Action(&spendAction{
281                                         AssetAmount: bc.AssetAmount{
282                                                 AssetId: testAssetID2,
283                                                 Amount:  300,
284                                         },
285                                         AccountID: "test_account2",
286                                 }),
287                         },
288                         wantActions: []txbuilder.Action{
289                                 txbuilder.Action(&spendUTXOAction{
290                                         OutputID: &bc.Hash{V0: 128},
291                                 }),
292                                 txbuilder.Action(&spendAction{
293                                         AssetAmount: bc.AssetAmount{
294                                                 AssetId: testBTM,
295                                                 Amount:  100,
296                                         },
297                                         AccountID: "test_account",
298                                 }),
299                                 txbuilder.Action(&spendAction{
300                                         AssetAmount: bc.AssetAmount{
301                                                 AssetId: testAssetID1,
302                                                 Amount:  200,
303                                         },
304                                         AccountID: "test_account1",
305                                 }),
306                                 txbuilder.Action(&spendUTXOAction{
307                                         OutputID: &bc.Hash{V0: 256},
308                                 }),
309                                 txbuilder.Action(&spendAction{
310                                         AssetAmount: bc.AssetAmount{
311                                                 AssetId: testAssetID2,
312                                                 Amount:  300,
313                                         },
314                                         AccountID: "test_account2",
315                                 }),
316                         },
317                         testActionCount: 5,
318                         wantActionCount: 5,
319                 },
320         }
321
322         for _, c := range cases {
323                 gotActions := MergeSpendAction(c.testActions)
324
325                 gotMap := make(map[string]uint64)
326                 wantMap := make(map[string]uint64)
327                 for _, got := range gotActions {
328                         switch got := got.(type) {
329                         case *spendAction:
330                                 gotKey := got.AssetId.String() + got.AccountID
331                                 gotMap[gotKey] = got.Amount
332                         default:
333                                 continue
334                         }
335                 }
336
337                 for _, want := range c.wantActions {
338                         switch want := want.(type) {
339                         case *spendAction:
340                                 wantKey := want.AssetId.String() + want.AccountID
341                                 wantMap[wantKey] = want.Amount
342                         default:
343                                 continue
344                         }
345                 }
346
347                 for key := range gotMap {
348                         if gotMap[key] != wantMap[key] {
349                                 t.Fatalf("gotMap[%s]=%v, wantMap[%s]=%v", key, gotMap[key], key, wantMap[key])
350                         }
351                 }
352
353                 if len(gotActions) != c.wantActionCount {
354                         t.Fatalf("number of gotActions=%d, wantActions=%d", len(gotActions), c.wantActionCount)
355                 }
356         }
357 }
358
359 func TestSpendUTXOArguments(t *testing.T) {
360         hexXpub, err := hex.DecodeString("ba76bb52574b3f40315f2c01f1818a9072ced56e9d4b68acbef56a4d0077d08e5e34837963e4cdc54eb251aa34aad01e6ae48b140f6a2743fbb0a0abd9cf8aac")
361         if err != nil {
362                 t.Fatal(err)
363         }
364
365         var xpub chainkd.XPub
366         copy(xpub[:], hexXpub)
367
368         rawTxSig := rawTxSigArgument{RootXPub: xpub, Path: []chainjson.HexBytes{{1, 1, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 0, 0, 0, 0}}}
369         rawTxSigMsg, err := json.Marshal(rawTxSig)
370         if err != nil {
371                 t.Fatal(err)
372         }
373
374         data := dataArgument{Value: "7468697320697320612074657374"}
375         dataMsg, err := json.Marshal(data)
376         if err != nil {
377                 t.Fatal(err)
378         }
379
380         cases := []struct {
381                 rawAction  string
382                 wantResult *spendUTXOAction
383         }{
384                 {
385                         rawAction: `{ "type": "spend_account_unspent_output", "output_id": "e304de887423e4e684e483f5ae65236d47018b56cac94ef3fb8b5dd40c897e11",
386                                 "arguments": [{"type": "raw_tx_signature", "raw_data": {"derivation_path": ["010100000000000000", "0100000000000000"],
387                     "xpub": "ba76bb52574b3f40315f2c01f1818a9072ced56e9d4b68acbef56a4d0077d08e5e34837963e4cdc54eb251aa34aad01e6ae48b140f6a2743fbb0a0abd9cf8aac"}}]}`,
388                         wantResult: &spendUTXOAction{
389                                 OutputID: &bc.Hash{16358444424161912038, 9575923798912607085, 5116523856555233011, 18125684290607480337},
390                                 Arguments: []contractArgument{
391                                         {
392                                                 Type:    "raw_tx_signature",
393                                                 RawData: rawTxSigMsg,
394                                         },
395                                 },
396                         },
397                 },
398                 {
399                         rawAction: `{ "type": "spend_account_unspent_output", "output_id": "8669b5c2e0701ec1ca45cd413e46c4f1d5f794f9d9144f904f3e7da8c68c6410",
400                                 "arguments": [{"type": "data", "raw_data": {"value": "7468697320697320612074657374"}}]}`,
401                         wantResult: &spendUTXOAction{
402                                 OutputID: &bc.Hash{9685472322230689473, 14575281449155871985, 15417955650135936912, 5710139541391434768},
403                                 Arguments: []contractArgument{
404                                         {
405                                                 Type:    "data",
406                                                 RawData: dataMsg,
407                                         },
408                                 },
409                         },
410                 },
411                 {
412                         rawAction: `{ "type": "spend_account_unspent_output", "output_id": "8669b5c2e0701ec1ca45cd413e46c4f1d5f794f9d9144f904f3e7da8c68c6410",
413                                 "arguments": [{"type": "signature", "raw_data": {"value": "7468697320697320612074657374"}}]}`,
414                         wantResult: &spendUTXOAction{
415                                 OutputID: &bc.Hash{9685472322230689473, 14575281449155871985, 15417955650135936912, 5710139541391434768},
416                         },
417                 },
418                 {
419                         rawAction: `{ "type": "spend_account_unspent_output", "output_id": "8669b5c2e0701ec1ca45cd413e46c4f1d5f794f9d9144f904f3e7da8c68c6410"}`,
420                         wantResult: &spendUTXOAction{
421                                 OutputID:  &bc.Hash{9685472322230689473, 14575281449155871985, 15417955650135936912, 5710139541391434768},
422                                 Arguments: nil,
423                         },
424                 },
425         }
426
427         for _, c := range cases {
428                 var spendUTXOReq *spendUTXOAction
429                 if err := json.Unmarshal([]byte(c.rawAction), &spendUTXOReq); err != nil {
430                         t.Fatalf("unmarshal spendUTXOAction error:%v", err)
431                 }
432
433                 if !testutil.DeepEqual(spendUTXOReq.OutputID, c.wantResult.OutputID) {
434                         t.Fatalf("OutputID gotResult=%v, wantResult=%v", spendUTXOReq.OutputID, c.wantResult.OutputID)
435                 }
436
437                 if spendUTXOReq.Arguments == nil {
438                         if c.wantResult.Arguments != nil {
439                                 t.Fatalf("Arguments gotResult is nil, wantResult[%v] is not nil", c.wantResult.Arguments)
440                         }
441                         continue
442                 }
443
444                 for _, arg := range spendUTXOReq.Arguments {
445                         switch arg.Type {
446                         case "raw_tx_signature":
447                                 rawTxSig := &rawTxSigArgument{}
448                                 if err := json.Unmarshal(arg.RawData, rawTxSig); err != nil {
449                                         t.Fatalf("unmarshal rawTxSigArgument error:%v", err)
450                                 }
451
452                                 wantRawTxSig := &rawTxSigArgument{}
453                                 if err := json.Unmarshal(c.wantResult.Arguments[0].RawData, wantRawTxSig); err != nil {
454                                         t.Fatalf("unmarshal want rawTxSigArgument error:%v", err)
455                                 }
456
457                                 if !testutil.DeepEqual(rawTxSig, wantRawTxSig) {
458                                         t.Fatalf("rawTxSigArgument gotResult=%v, wantResult=%v", rawTxSig, wantRawTxSig)
459                                 }
460
461                         case "data":
462                                 data := &dataArgument{}
463                                 if err := json.Unmarshal(arg.RawData, data); err != nil {
464                                         t.Fatalf("unmarshal dataArgument error:%v", err)
465                                 }
466
467                                 wantData := &dataArgument{}
468                                 if err := json.Unmarshal(c.wantResult.Arguments[0].RawData, wantData); err != nil {
469                                         t.Fatalf("unmarshal want dataArgument error:%v", err)
470                                 }
471
472                                 if !testutil.DeepEqual(data, wantData) {
473                                         t.Fatalf("dataArgument gotResult=%v, wantResult=%v", data, wantData)
474                                 }
475
476                         default:
477                                 if arg.Type == "raw_tx_signature" || arg.Type == "data" {
478                                         t.Fatalf("argument type [%v] is not exist", arg.Type)
479                                 }
480                         }
481                 }
482         }
483 }