OSDN Git Service

Paging (#234)
[bytom/vapor.git] / account / builder_test.go
1 package account
2
3 import (
4         "encoding/json"
5         "testing"
6         "time"
7
8         "github.com/vapor/blockchain/signers"
9         "github.com/vapor/blockchain/txbuilder"
10         "github.com/vapor/consensus"
11         "github.com/vapor/crypto/ed25519/chainkd"
12         "github.com/vapor/protocol/bc"
13         "github.com/vapor/testutil"
14 )
15
16 func TestReserveBtmUtxoChain(t *testing.T) {
17         chainTxUtxoNum = 3
18         utxos := []*UTXO{}
19         m := mockAccountManager(t)
20         for i := uint64(1); i <= 20; i++ {
21                 utxo := &UTXO{
22                         OutputID:  bc.Hash{V0: i},
23                         AccountID: "TestAccountID",
24                         AssetID:   *consensus.BTMAssetID,
25                         Amount:    i * chainTxMergeGas,
26                 }
27                 utxos = append(utxos, utxo)
28
29                 data, err := json.Marshal(utxo)
30                 if err != nil {
31                         t.Fatal(err)
32                 }
33
34                 m.db.Set(StandardUTXOKey(utxo.OutputID), data)
35         }
36
37         cases := []struct {
38                 amount uint64
39                 want   []uint64
40                 err    bool
41         }{
42                 {
43                         amount: 1 * chainTxMergeGas,
44                         want:   []uint64{1},
45                 },
46                 {
47                         amount: 888888 * chainTxMergeGas,
48                         want:   []uint64{},
49                         err:    true,
50                 },
51                 {
52                         amount: 7 * chainTxMergeGas,
53                         want:   []uint64{4, 3, 1},
54                 },
55                 {
56                         amount: 15 * chainTxMergeGas,
57                         want:   []uint64{5, 4, 3, 2, 1, 6},
58                 },
59                 {
60                         amount: 163 * chainTxMergeGas,
61                         want:   []uint64{20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 2, 1, 3},
62                 },
63         }
64
65         for i, c := range cases {
66                 m.utxoKeeper.expireReservation(time.Unix(999999999, 0))
67                 utxos, err := m.reserveBtmUtxoChain(&txbuilder.TemplateBuilder{}, "TestAccountID", c.amount, false)
68
69                 if err != nil != c.err {
70                         t.Fatalf("case %d got err %v want err = %v", i, err, c.err)
71                 }
72
73                 got := []uint64{}
74                 for _, utxo := range utxos {
75                         got = append(got, utxo.Amount/chainTxMergeGas)
76                 }
77
78                 if !testutil.DeepEqual(got, c.want) {
79                         t.Fatalf("case %d got %d want %d", i, got, c.want)
80                 }
81         }
82
83 }
84
85 func TestBuildBtmTxChain(t *testing.T) {
86         chainTxUtxoNum = 3
87         m := mockAccountManager(t)
88         cases := []struct {
89                 inputUtxo  []uint64
90                 wantInput  [][]uint64
91                 wantOutput [][]uint64
92                 wantUtxo   uint64
93         }{
94                 {
95                         inputUtxo:  []uint64{5},
96                         wantInput:  [][]uint64{},
97                         wantOutput: [][]uint64{},
98                         wantUtxo:   5 * chainTxMergeGas,
99                 },
100                 {
101                         inputUtxo: []uint64{5, 4},
102                         wantInput: [][]uint64{
103                                 []uint64{5, 4},
104                         },
105                         wantOutput: [][]uint64{
106                                 []uint64{8},
107                         },
108                         wantUtxo: 8 * chainTxMergeGas,
109                 },
110                 {
111                         inputUtxo: []uint64{5, 4, 1, 1},
112                         wantInput: [][]uint64{
113                                 []uint64{5, 4, 1},
114                                 []uint64{1, 9},
115                         },
116                         wantOutput: [][]uint64{
117                                 []uint64{9},
118                                 []uint64{9},
119                         },
120                         wantUtxo: 9 * chainTxMergeGas,
121                 },
122                 {
123                         inputUtxo: []uint64{22, 123, 53, 234, 23, 4, 2423, 24, 23, 43, 34, 234, 234, 24},
124                         wantInput: [][]uint64{
125                                 []uint64{22, 123, 53},
126                                 []uint64{234, 23, 4},
127                                 []uint64{2423, 24, 23},
128                                 []uint64{43, 34, 234},
129                                 []uint64{234, 24, 197},
130                                 []uint64{260, 2469, 310},
131                                 []uint64{454, 3038},
132                         },
133                         wantOutput: [][]uint64{
134                                 []uint64{197},
135                                 []uint64{260},
136                                 []uint64{2469},
137                                 []uint64{310},
138                                 []uint64{454},
139                                 []uint64{3038},
140                                 []uint64{3491},
141                         },
142                         wantUtxo: 3491 * chainTxMergeGas,
143                 },
144         }
145
146         acct, err := m.Create([]chainkd.XPub{testutil.TestXPub}, 1, "testAccount", signers.BIP0044)
147         if err != nil {
148                 t.Fatal(err)
149         }
150
151         acp, err := m.CreateAddress(acct.ID, false)
152         if err != nil {
153                 t.Fatal(err)
154         }
155
156         for caseIndex, c := range cases {
157                 utxos := []*UTXO{}
158                 for _, amount := range c.inputUtxo {
159                         utxos = append(utxos, &UTXO{
160                                 Amount:         amount * chainTxMergeGas,
161                                 AssetID:        *consensus.BTMAssetID,
162                                 Address:        acp.Address,
163                                 ControlProgram: acp.ControlProgram,
164                         })
165                 }
166
167                 tpls, gotUtxo, err := m.buildBtmTxChain(utxos, acct.Signer)
168                 if err != nil {
169                         t.Fatal(err)
170                 }
171
172                 for i, tpl := range tpls {
173                         gotInput := []uint64{}
174                         for _, input := range tpl.Transaction.Inputs {
175                                 gotInput = append(gotInput, input.Amount()/chainTxMergeGas)
176                         }
177
178                         gotOutput := []uint64{}
179                         for _, output := range tpl.Transaction.Outputs {
180                                 gotOutput = append(gotOutput, output.AssetAmount().Amount/chainTxMergeGas)
181                         }
182
183                         if !testutil.DeepEqual(c.wantInput[i], gotInput) {
184                                 t.Fatalf("case %d tx %d input got %d want %d", caseIndex, i, gotInput, c.wantInput[i])
185                         }
186                         if !testutil.DeepEqual(c.wantOutput[i], gotOutput) {
187                                 t.Fatalf("case %d tx %d output got %d want %d", caseIndex, i, gotOutput, c.wantOutput[i])
188                         }
189                 }
190
191                 if c.wantUtxo != gotUtxo.Amount {
192                         t.Fatalf("case %d got utxo=%d want utxo=%d", caseIndex, gotUtxo.Amount, c.wantUtxo)
193                 }
194         }
195
196 }
197
198 func TestMergeSpendAction(t *testing.T) {
199         testBTM := &bc.AssetID{}
200         if err := testBTM.UnmarshalText([]byte("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); err != nil {
201                 t.Fatal(err)
202         }
203
204         testAssetID1 := &bc.AssetID{}
205         if err := testAssetID1.UnmarshalText([]byte("50ec80b6bc48073f6aa8fa045131a71213c33f3681203b15ddc2e4b81f1f4730")); err != nil {
206                 t.Fatal(err)
207         }
208
209         testAssetID2 := &bc.AssetID{}
210         if err := testAssetID2.UnmarshalText([]byte("43c6946d092b2959c1a82e90b282c68fca63e66de289048f6acd6cea9383c79c")); err != nil {
211                 t.Fatal(err)
212         }
213
214         cases := []struct {
215                 testActions     []txbuilder.Action
216                 wantActions     []txbuilder.Action
217                 testActionCount int
218                 wantActionCount int
219         }{
220                 {
221                         testActions: []txbuilder.Action{
222                                 txbuilder.Action(&spendAction{
223                                         AssetAmount: bc.AssetAmount{
224                                                 AssetId: testBTM,
225                                                 Amount:  100,
226                                         },
227                                         AccountID: "test_account",
228                                 }),
229                                 txbuilder.Action(&spendAction{
230                                         AssetAmount: bc.AssetAmount{
231                                                 AssetId: testBTM,
232                                                 Amount:  200,
233                                         },
234                                         AccountID: "test_account",
235                                 }),
236                                 txbuilder.Action(&spendAction{
237                                         AssetAmount: bc.AssetAmount{
238                                                 AssetId: testBTM,
239                                                 Amount:  300,
240                                         },
241                                         AccountID: "test_account",
242                                 }),
243                                 txbuilder.Action(&spendAction{
244                                         AssetAmount: bc.AssetAmount{
245                                                 AssetId: testAssetID1,
246                                                 Amount:  300,
247                                         },
248                                         AccountID: "test_account",
249                                 }),
250                         },
251                         wantActions: []txbuilder.Action{
252                                 txbuilder.Action(&spendAction{
253                                         AssetAmount: bc.AssetAmount{
254                                                 AssetId: testBTM,
255                                                 Amount:  600,
256                                         },
257                                         AccountID: "test_account",
258                                 }),
259                                 txbuilder.Action(&spendAction{
260                                         AssetAmount: bc.AssetAmount{
261                                                 AssetId: testAssetID1,
262                                                 Amount:  300,
263                                         },
264                                         AccountID: "test_account",
265                                 }),
266                         },
267                         testActionCount: 4,
268                         wantActionCount: 2,
269                 },
270                 {
271                         testActions: []txbuilder.Action{
272                                 txbuilder.Action(&spendAction{
273                                         AssetAmount: bc.AssetAmount{
274                                                 AssetId: testBTM,
275                                                 Amount:  100,
276                                         },
277                                         AccountID: "test_account",
278                                 }),
279                                 txbuilder.Action(&spendAction{
280                                         AssetAmount: bc.AssetAmount{
281                                                 AssetId: testAssetID1,
282                                                 Amount:  200,
283                                         },
284                                         AccountID: "test_account",
285                                 }),
286                                 txbuilder.Action(&spendAction{
287                                         AssetAmount: bc.AssetAmount{
288                                                 AssetId: testBTM,
289                                                 Amount:  500,
290                                         },
291                                         AccountID: "test_account",
292                                 }),
293                                 txbuilder.Action(&spendAction{
294                                         AssetAmount: bc.AssetAmount{
295                                                 AssetId: testAssetID1,
296                                                 Amount:  300,
297                                         },
298                                         AccountID: "test_account",
299                                 }),
300                         },
301                         wantActions: []txbuilder.Action{
302                                 txbuilder.Action(&spendAction{
303                                         AssetAmount: bc.AssetAmount{
304                                                 AssetId: testBTM,
305                                                 Amount:  600,
306                                         },
307                                         AccountID: "test_account",
308                                 }),
309                                 txbuilder.Action(&spendAction{
310                                         AssetAmount: bc.AssetAmount{
311                                                 AssetId: testAssetID1,
312                                                 Amount:  500,
313                                         },
314                                         AccountID: "test_account",
315                                 }),
316                         },
317                         testActionCount: 4,
318                         wantActionCount: 2,
319                 },
320                 {
321                         testActions: []txbuilder.Action{
322                                 txbuilder.Action(&spendAction{
323                                         AssetAmount: bc.AssetAmount{
324                                                 AssetId: testBTM,
325                                                 Amount:  100,
326                                         },
327                                         AccountID: "test_account",
328                                 }),
329                                 txbuilder.Action(&spendAction{
330                                         AssetAmount: bc.AssetAmount{
331                                                 AssetId: testAssetID1,
332                                                 Amount:  200,
333                                         },
334                                         AccountID: "test_account",
335                                 }),
336                                 txbuilder.Action(&spendAction{
337                                         AssetAmount: bc.AssetAmount{
338                                                 AssetId: testAssetID2,
339                                                 Amount:  300,
340                                         },
341                                         AccountID: "test_account",
342                                 }),
343                                 txbuilder.Action(&spendAction{
344                                         AssetAmount: bc.AssetAmount{
345                                                 AssetId: testAssetID1,
346                                                 Amount:  300,
347                                         },
348                                         AccountID: "test_account",
349                                 }),
350                                 txbuilder.Action(&spendAction{
351                                         AssetAmount: bc.AssetAmount{
352                                                 AssetId: testAssetID2,
353                                                 Amount:  500,
354                                         },
355                                         AccountID: "test_account",
356                                 }),
357                         },
358                         wantActions: []txbuilder.Action{
359                                 txbuilder.Action(&spendAction{
360                                         AssetAmount: bc.AssetAmount{
361                                                 AssetId: testBTM,
362                                                 Amount:  100,
363                                         },
364                                         AccountID: "test_account",
365                                 }),
366                                 txbuilder.Action(&spendAction{
367                                         AssetAmount: bc.AssetAmount{
368                                                 AssetId: testAssetID1,
369                                                 Amount:  500,
370                                         },
371                                         AccountID: "test_account",
372                                 }),
373                                 txbuilder.Action(&spendAction{
374                                         AssetAmount: bc.AssetAmount{
375                                                 AssetId: testAssetID2,
376                                                 Amount:  800,
377                                         },
378                                         AccountID: "test_account",
379                                 }),
380                         },
381                         testActionCount: 5,
382                         wantActionCount: 3,
383                 },
384                 {
385                         testActions: []txbuilder.Action{
386                                 txbuilder.Action(&spendAction{
387                                         AssetAmount: bc.AssetAmount{
388                                                 AssetId: testBTM,
389                                                 Amount:  100,
390                                         },
391                                         AccountID: "test_account",
392                                 }),
393                                 txbuilder.Action(&spendAction{
394                                         AssetAmount: bc.AssetAmount{
395                                                 AssetId: testBTM,
396                                                 Amount:  200,
397                                         },
398                                         AccountID: "test_account1",
399                                 }),
400                                 txbuilder.Action(&spendAction{
401                                         AssetAmount: bc.AssetAmount{
402                                                 AssetId: testBTM,
403                                                 Amount:  500,
404                                         },
405                                         AccountID: "test_account",
406                                 }),
407                                 txbuilder.Action(&spendAction{
408                                         AssetAmount: bc.AssetAmount{
409                                                 AssetId: testAssetID1,
410                                                 Amount:  300,
411                                         },
412                                         AccountID: "test_account1",
413                                 }),
414                         },
415                         wantActions: []txbuilder.Action{
416                                 txbuilder.Action(&spendAction{
417                                         AssetAmount: bc.AssetAmount{
418                                                 AssetId: testBTM,
419                                                 Amount:  600,
420                                         },
421                                         AccountID: "test_account",
422                                 }),
423                                 txbuilder.Action(&spendAction{
424                                         AssetAmount: bc.AssetAmount{
425                                                 AssetId: testBTM,
426                                                 Amount:  200,
427                                         },
428                                         AccountID: "test_account1",
429                                 }),
430                                 txbuilder.Action(&spendAction{
431                                         AssetAmount: bc.AssetAmount{
432                                                 AssetId: testAssetID1,
433                                                 Amount:  300,
434                                         },
435                                         AccountID: "test_account1",
436                                 }),
437                         },
438                         testActionCount: 4,
439                         wantActionCount: 3,
440                 },
441                 {
442                         testActions: []txbuilder.Action{
443                                 txbuilder.Action(&spendUTXOAction{
444                                         OutputID: &bc.Hash{V0: 128},
445                                 }),
446                                 txbuilder.Action(&spendAction{
447                                         AssetAmount: bc.AssetAmount{
448                                                 AssetId: testBTM,
449                                                 Amount:  100,
450                                         },
451                                         AccountID: "test_account",
452                                 }),
453                                 txbuilder.Action(&spendAction{
454                                         AssetAmount: bc.AssetAmount{
455                                                 AssetId: testAssetID1,
456                                                 Amount:  200,
457                                         },
458                                         AccountID: "test_account1",
459                                 }),
460                                 txbuilder.Action(&spendUTXOAction{
461                                         OutputID: &bc.Hash{V0: 256},
462                                 }),
463                                 txbuilder.Action(&spendAction{
464                                         AssetAmount: bc.AssetAmount{
465                                                 AssetId: testAssetID2,
466                                                 Amount:  300,
467                                         },
468                                         AccountID: "test_account2",
469                                 }),
470                         },
471                         wantActions: []txbuilder.Action{
472                                 txbuilder.Action(&spendUTXOAction{
473                                         OutputID: &bc.Hash{V0: 128},
474                                 }),
475                                 txbuilder.Action(&spendAction{
476                                         AssetAmount: bc.AssetAmount{
477                                                 AssetId: testBTM,
478                                                 Amount:  100,
479                                         },
480                                         AccountID: "test_account",
481                                 }),
482                                 txbuilder.Action(&spendAction{
483                                         AssetAmount: bc.AssetAmount{
484                                                 AssetId: testAssetID1,
485                                                 Amount:  200,
486                                         },
487                                         AccountID: "test_account1",
488                                 }),
489                                 txbuilder.Action(&spendUTXOAction{
490                                         OutputID: &bc.Hash{V0: 256},
491                                 }),
492                                 txbuilder.Action(&spendAction{
493                                         AssetAmount: bc.AssetAmount{
494                                                 AssetId: testAssetID2,
495                                                 Amount:  300,
496                                         },
497                                         AccountID: "test_account2",
498                                 }),
499                         },
500                         testActionCount: 5,
501                         wantActionCount: 5,
502                 },
503         }
504
505         for _, c := range cases {
506                 gotActions := MergeSpendAction(c.testActions)
507
508                 gotMap := make(map[string]uint64)
509                 wantMap := make(map[string]uint64)
510                 for _, got := range gotActions {
511                         switch got := got.(type) {
512                         case *spendAction:
513                                 gotKey := got.AssetId.String() + got.AccountID
514                                 gotMap[gotKey] = got.Amount
515                         default:
516                                 continue
517                         }
518                 }
519
520                 for _, want := range c.wantActions {
521                         switch want := want.(type) {
522                         case *spendAction:
523                                 wantKey := want.AssetId.String() + want.AccountID
524                                 wantMap[wantKey] = want.Amount
525                         default:
526                                 continue
527                         }
528                 }
529
530                 for key := range gotMap {
531                         if gotMap[key] != wantMap[key] {
532                                 t.Fatalf("gotMap[%s]=%v, wantMap[%s]=%v", key, gotMap[key], key, wantMap[key])
533                         }
534                 }
535
536                 if len(gotActions) != c.wantActionCount {
537                         t.Fatalf("number of gotActions=%d, wantActions=%d", len(gotActions), c.wantActionCount)
538                 }
539         }
540 }
541
542 func TestCalcMergeGas(t *testing.T) {
543         chainTxUtxoNum = 10
544         cases := []struct {
545                 utxoNum int
546                 gas     uint64
547         }{
548                 {
549                         utxoNum: 0,
550                         gas:     0,
551                 },
552                 {
553                         utxoNum: 1,
554                         gas:     0,
555                 },
556                 {
557                         utxoNum: 9,
558                         gas:     chainTxMergeGas,
559                 },
560                 {
561                         utxoNum: 10,
562                         gas:     chainTxMergeGas,
563                 },
564                 {
565                         utxoNum: 11,
566                         gas:     chainTxMergeGas * 2,
567                 },
568                 {
569                         utxoNum: 20,
570                         gas:     chainTxMergeGas * 3,
571                 },
572                 {
573                         utxoNum: 21,
574                         gas:     chainTxMergeGas * 3,
575                 },
576                 {
577                         utxoNum: 74,
578                         gas:     chainTxMergeGas * 9,
579                 },
580         }
581
582         for i, c := range cases {
583                 gas := calcMergeGas(c.utxoNum)
584                 if gas != c.gas {
585                         t.Fatalf("case %d got %d want %d", i, gas, c.gas)
586                 }
587         }
588 }