forked from hubble-exchange/hubblenet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
orderbook_test.go
1131 lines (1092 loc) · 53.2 KB
/
orderbook_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package evm
import (
"context"
"crypto/ecdsa"
"math/big"
"testing"
"time"
"github.com/ava-labs/avalanchego/snow/choices"
"github.com/ava-labs/avalanchego/snow/consensus/snowman"
"github.com/ava-labs/subnet-evm/accounts/abi"
"github.com/ava-labs/subnet-evm/core/types"
"github.com/ava-labs/subnet-evm/plugin/evm/orderbook"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
var (
genesisJSON string
orderBookABI abi.ABI
alice, bob common.Address
aliceKey, bobKey *ecdsa.PrivateKey
orderBookABIStr string = `{
"abi": [
{
"anonymous": false,
"inputs": [],
"name": "EIP712DomainChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint8",
"name": "version",
"type": "uint8"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "orderHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "string",
"name": "err",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
"name": "toLiquidate",
"type": "uint256"
}
],
"name": "LiquidationError",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "orderHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "bytes",
"name": "signature",
"type": "bytes"
},
{
"indexed": false,
"internalType": "uint256",
"name": "fillAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "openInterestNotional",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "relayer",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"name": "LiquidationOrderMatched",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "orderHash",
"type": "bytes32"
},
{
"components": [
{
"internalType": "uint256",
"name": "ammIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"internalType": "int256",
"name": "baseAssetQuantity",
"type": "int256"
},
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "salt",
"type": "uint256"
},
{
"internalType": "bool",
"name": "reduceOnly",
"type": "bool"
},
{
"internalType": "bool",
"name": "postOnly",
"type": "bool"
}
],
"indexed": false,
"internalType": "struct IOrderBook.Order",
"name": "order",
"type": "tuple"
},
{
"indexed": false,
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"name": "OrderAccepted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "orderHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"name": "OrderCancelled",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "orderHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "string",
"name": "err",
"type": "string"
}
],
"name": "OrderMatchingError",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "orderHash0",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "orderHash1",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "fillAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "openInterestNotional",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "relayer",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"name": "OrdersMatched",
"type": "event"
},
{
"inputs": [],
"name": "ORDER_TYPEHASH",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint256",
"name": "ammIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"internalType": "int256",
"name": "baseAssetQuantity",
"type": "int256"
},
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "salt",
"type": "uint256"
},
{
"internalType": "bool",
"name": "reduceOnly",
"type": "bool"
},
{
"internalType": "bool",
"name": "postOnly",
"type": "bool"
}
],
"internalType": "struct IOrderBook.Order",
"name": "order",
"type": "tuple"
}
],
"name": "cancelOrder",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "eip712Domain",
"outputs": [
{
"internalType": "bytes1",
"name": "fields",
"type": "bytes1"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "version",
"type": "string"
},
{
"internalType": "uint256",
"name": "chainId",
"type": "uint256"
},
{
"internalType": "address",
"name": "verifyingContract",
"type": "address"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "uint256[]",
"name": "extensions",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint256",
"name": "ammIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"internalType": "int256",
"name": "baseAssetQuantity",
"type": "int256"
},
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "salt",
"type": "uint256"
},
{
"internalType": "bool",
"name": "reduceOnly",
"type": "bool"
},
{
"internalType": "bool",
"name": "postOnly",
"type": "bool"
}
],
"internalType": "struct IOrderBook.Order[2]",
"name": "orders",
"type": "tuple[2]"
},
{
"internalType": "int256",
"name": "fillAmount",
"type": "int256"
}
],
"name": "executeMatchedOrders",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint256",
"name": "ammIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"internalType": "int256",
"name": "baseAssetQuantity",
"type": "int256"
},
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "salt",
"type": "uint256"
},
{
"internalType": "bool",
"name": "reduceOnly",
"type": "bool"
},
{
"internalType": "bool",
"name": "postOnly",
"type": "bool"
}
],
"internalType": "struct IOrderBook.Order",
"name": "order",
"type": "tuple"
},
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
}
],
"name": "executeTestOrder",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getLastTradePrices",
"outputs": [
{
"internalType": "uint256[]",
"name": "lastTradePrices",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint256",
"name": "ammIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"internalType": "int256",
"name": "baseAssetQuantity",
"type": "int256"
},
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "salt",
"type": "uint256"
},
{
"internalType": "bool",
"name": "reduceOnly",
"type": "bool"
},
{
"internalType": "bool",
"name": "postOnly",
"type": "bool"
}
],
"internalType": "struct IOrderBook.Order",
"name": "order",
"type": "tuple"
}
],
"name": "getOrderHash",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "version",
"type": "string"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "lastPrices",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"components": [
{
"internalType": "uint256",
"name": "ammIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"internalType": "int256",
"name": "baseAssetQuantity",
"type": "int256"
},
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "salt",
"type": "uint256"
},
{
"internalType": "bool",
"name": "reduceOnly",
"type": "bool"
},
{
"internalType": "bool",
"name": "postOnly",
"type": "bool"
}
],
"internalType": "struct IOrderBook.Order",
"name": "order",
"type": "tuple"
},
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "toLiquidate",
"type": "uint256"
}
],
"name": "liquidateAndExecuteOrder",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "numAmms",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "orderInfo",
"outputs": [
{
"internalType": "uint256",
"name": "blockPlaced",
"type": "uint256"
},
{
"internalType": "int256",
"name": "filledAmount",
"type": "int256"
},
{
"internalType": "enum IOrderBook.OrderStatus",
"name": "status",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint256",
"name": "ammIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"internalType": "int256",
"name": "baseAssetQuantity",
"type": "int256"
},
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "salt",
"type": "uint256"
},
{
"internalType": "bool",
"name": "reduceOnly",
"type": "bool"
},
{
"internalType": "bool",
"name": "postOnly",
"type": "bool"
}
],
"internalType": "struct IOrderBook.Order",
"name": "order",
"type": "tuple"
}
],
"name": "placeOrder",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "positions",
"outputs": [
{
"internalType": "int256",
"name": "size",
"type": "int256"
},
{
"internalType": "uint256",
"name": "openNotional",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_num",
"type": "uint256"
}
],
"name": "setNumAMMs",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "settleFunding",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint256",
"name": "ammIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "trader",
"type": "address"
},
{
"internalType": "int256",
"name": "baseAssetQuantity",
"type": "int256"
},
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "salt",
"type": "uint256"
},
{
"internalType": "bool",
"name": "reduceOnly",
"type": "bool"
},
{
"internalType": "bool",
"name": "postOnly",
"type": "bool"
}
],
"internalType": "struct IOrderBook.Order",
"name": "order",
"type": "tuple"
},
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "verifySigner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
}
]
}`
orderBookAddress common.Address = common.HexToAddress("0x03000000000000000000000000000000000000b3")
_1e18 *big.Int = big.NewInt(1e18)
_1e6 *big.Int = big.NewInt(1e6)
)
func init() {
var err error
genesisJSON = `{"config":{"chainId":321123,"homesteadBlock":0,"eip150Block":0,"eip150Hash":"0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0","eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0,"istanbulBlock":0,"muirGlacierBlock":0,"SubnetEVMTimestamp":0,"feeConfig":{"gasLimit":500000000,"targetBlockRate":1,"minBaseFee":60000000000,"targetGas":10000000,"baseFeeChangeDenominator":50,"minBlockGasCost":0,"maxBlockGasCost":0,"blockGasCostStep":10000}},"alloc":{"835cE0760387BC894E91039a88A00b6a69E65D94":{"balance":"0xD3C21BCECCEDA1000000"},"8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC":{"balance":"0xD3C21BCECCEDA1000000"},"55ee05dF718f1a5C1441e76190EB1a19eE2C9430":{"balance":"0xD3C21BCECCEDA1000000"},"4Cf2eD3665F6bFA95cE6A11CFDb7A2EF5FC1C7E4":{"balance":"0xD3C21BCECCEDA1000000"},"f39Fd6e51aad88F6F4ce6aB8827279cffFb92266":{"balance":"0xD3C21BCECCEDA1000000"},"70997970C51812dc3A010C7d01b50e0d17dc79C8":{"balance":"0xD3C21BCECCEDA1000000"},"3C44CdDdB6a900fa2b585dd299e03d12FA4293BC":{"balance":"0xD3C21BCECCEDA1000000"},"0x03000000000000000000000000000000000000b3":{"balance":"0x0","code":"0x608060405234801561001057600080fd5b506004361061010b5760003560e01c8063508bac1f116100a25780639b809602116100715780639b809602146102aa578063e47c2384146102c6578063e684d718146102f7578063ed83d79c14610328578063f973a209146103325761010b565b8063508bac1f1461021c5780637114f7f814610238578063715d587c1461025657806384b0196e146102865761010b565b80633245dea5116100de5780633245dea51461019857806342c1f8a4146101c85780634cd88b76146101e45780634e545b4d146102005761010b565b8063238e203f146101105780632695cf011461014257806327d57a9e1461015e5780632cc751151461017c575b600080fd5b61012a60048036038101906101259190611a7b565b610350565b60405161013993929190611b51565b60405180910390f35b61015c60048036038101906101579190611e75565b610387565b005b6101666103c6565b6040516101739190611ed2565b60405180910390f35b61019660048036038101906101919190611fa3565b6103cc565b005b6101b260048036038101906101ad9190611fe5565b6106bc565b6040516101bf9190611ed2565b60405180910390f35b6101e260048036038101906101dd9190611fe5565b6106d4565b005b6101fe60048036038101906101f991906120b3565b6106de565b005b61021a6004803603810190610215919061212b565b61082a565b005b6102366004803603810190610231919061212b565b6109c9565b005b610240610ab8565b60405161024d9190612216565b60405180910390f35b610270600480360381019061026b919061212b565b610b5e565b60405161027d9190612247565b60405180910390f35b61028e610bbb565b6040516102a19796959493929190612334565b60405180910390f35b6102c460048036038101906102bf91906123b8565b610cbc565b005b6102e060048036038101906102db9190611e75565b610e7b565b6040516102ee92919061243e565b60405180910390f35b610311600480360381019061030c9190612467565b610e9d565b60405161031f9291906124a7565b60405180910390f35b610330610ece565b005b61033a610ed0565b6040516103479190612247565b60405180910390f35b60356020528060005260406000206000915090508060000154908060010154908060020160009054906101000a900460ff16905083565b600061039883838560400151610ef7565b5090506103ae81846040015185604001516110dc565b6103c1838460400151856060015161116c565b505050565b60385481565b6000826000600281106103e2576103e16124d0565b5b6020020151604001511361042b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104229061254b565b60405180910390fd5b600082600160028110610441576104406124d0565b5b6020020151604001511261048a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610481906125b7565b60405180910390fd5b600081136104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c490612623565b60405180910390fd5b816001600281106104e1576104e06124d0565b5b602002015160600151826000600281106104fe576104fd6124d0565b5b6020020151606001511015610548576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053f9061268f565b60405180910390fd5b600061056b83600060028110610561576105606124d0565b5b6020020151610b5e565b9050600061059084600160028110610586576105856124d0565b5b6020020151610b5e565b90506105b98284866000600281106105ab576105aa6124d0565b5b6020020151604001516110dc565b6105e981846105c7906126de565b866001600281106105db576105da6124d0565b5b6020020151604001516110dc565b6000846000600281106105ff576105fe6124d0565b5b602002015160600151905061062d85600060028110610621576106206124d0565b5b6020020151858361116c565b61065985600160028110610644576106436124d0565b5b602002015185610653906126de565b8361116c565b81837faf4b403d9952e032974b549a4abad80faca307b0acc6e34d7e0b8c274d504590610685876114d5565b84856106908a6114d5565b61069a9190612727565b33426040516106ad959493929190612781565b60405180910390a35050505050565b60376020528060005260406000206000915090505481565b8060388190555050565b60008060019054906101000a900460ff1615905080801561070f5750600160008054906101000a900460ff1660ff16105b8061073c575061071e30611522565b15801561073b5750600160008054906101000a900460ff1660ff16145b5b61077b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161077290612846565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156107b8576001600060016101000a81548160ff0219169083151502179055505b6107c28383611545565b6107cc60016106d4565b80156108255760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498600160405161081c91906128b8565b60405180910390a15b505050565b806020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461089c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108939061291f565b60405180910390fd5b60006108a782610b5e565b9050600160038111156108bd576108bc611ada565b5b6035600083815260200190815260200160002060020160009054906101000a900460ff1660038111156108f3576108f2611ada565b5b14610933576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161092a9061298b565b60405180910390fd5b60036035600083815260200190815260200160002060020160006101000a81548160ff0219169083600381111561096d5761096c611ada565b5b021790555080826020015173ffffffffffffffffffffffffffffffffffffffff167f26b214029d2b6a3a3bb2ae7cc0a5d4c9329a86381429e16dc45b3633cf83d369426040516109bd9190611ed2565b60405180910390a35050565b60006109d482610b5e565b905060405180606001604052804381526020016000815260200160016003811115610a0257610a01611ada565b5b81525060356000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020160006101000a81548160ff02191690836003811115610a5757610a56611ada565b5b021790555090505080826020015173ffffffffffffffffffffffffffffffffffffffff167f70efd0c97c9e59c5cbc4bd4e40365b942df3603cd71c223f6940e3fca16356358442604051610aac929190612a66565b60405180910390a35050565b606060385467ffffffffffffffff811115610ad657610ad5611b9e565b5b604051908082528060200260200182016040528015610b045781602001602082028036833780820191505090505b50905060005b603854811015610b5a576037600082815260200190815260200160002054828281518110610b3b57610b3a6124d0565b5b6020026020010181815250508080610b5290612a90565b915050610b0a565b5090565b6000610bb47f0a2e4d36552888a97d5a8975ad22b04e90efe5ea0a8abb97691b63b431eb25d260001b83604051602001610b99929190612ad9565b604051602081830303815290604052805190602001206115a2565b9050919050565b6000606080600080600060606000801b600154148015610bdf57506000801b600254145b610c1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1590612b4f565b60405180910390fd5b610c266115bc565b610c2e61164e565b46306000801b600067ffffffffffffffff811115610c4f57610c4e611b9e565b5b604051908082528060200260200182016040528015610c7d5781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b670de0b6b3a7640000818460600151610cd59190612727565b610cdf9190612b9e565b603660008560000151815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000828254610d459190612bcf565b92505081905550610d55816116e0565b603660008560000151815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000016000828254610dbb9190612c03565b925050819055506000610dd78484610dd2856116e0565b610ef7565b509050610df181610de7846116e0565b86604001516110dc565b610e0884610dfe846116e0565b866060015161116c565b808573ffffffffffffffffffffffffffffffffffffffff167fd7a2e338b47db7ba2c25b55a69d8eb13126b1ec669de521cd1985aae9ee32ca185858860600151878a60600151610e589190612727565b3342604051610e6c96959493929190612cec565b60405180910390a35050505050565b6000806000610e8985610b5e565b905084602001518192509250509250929050565b6036602052816000526040600020602052806000526040600020600091509150508060000154908060010154905082565b565b7f0a2e4d36552888a97d5a8975ad22b04e90efe5ea0a8abb97691b63b431eb25d260001b81565b6000806000610f068686610e7b565b91505060016003811115610f1d57610f1c611ada565b5b6035600083815260200190815260200160002060020160009054906101000a900460ff166003811115610f5357610f52611ada565b5b14610f93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8a90612da0565b60405180910390fd5b6000848760400151610fa59190612dc0565b13610fe5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdc90612f23565b60405180910390fd5b60008460356000848152602001908152602001600020600101546110099190612dc0565b121561104a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104190612f8f565b60405180910390fd5b611057866040015161174d565b611076603560008481526020019081526020016000206001015461174d565b13156110b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ae90613021565b60405180910390fd5b8060356000838152602001908152602001600020600001549250925050935093915050565b816035600085815260200190815260200160002060010160008282546111029190613041565b9250508190555080603560008581526020019081526020016000206001015414156111675760026035600085815260200190815260200160002060020160006101000a81548160ff0219169083600381111561116157611160611ada565b5b02179055505b505050565b6000670de0b6b3a7640000826111896111848661174d565b6114d5565b6111939190612727565b61119d9190612b9e565b905060008460200151905060008560000151905060385481106111f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ec90613121565b60405180910390fd5b6000856036600084815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001546112569190612dc0565b126112ca57826036600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008282546112be9190613141565b9250508190555061144b565b826036600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101541061139357826036600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008282546113879190612bcf565b9250508190555061144a565b6036600082815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154836113f29190612bcf565b6036600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055505b5b846036600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282546114ae9190613041565b92505081905550836037600083815260200190815260200160002081905550505050505050565b60008082121561151a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611511906131e3565b60405180910390fd5b819050919050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16611594576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158b90613275565b60405180910390fd5b61159e828261176f565b5050565b60006115b56115af611804565b83611813565b9050919050565b6060600380546115cb906132c4565b80601f01602080910402602001604051908101604052809291908181526020018280546115f7906132c4565b80156116445780601f1061161957610100808354040283529160200191611644565b820191906000526020600020905b81548152906001019060200180831161162757829003601f168201915b5050505050905090565b60606004805461165d906132c4565b80601f0160208091040260200160405190810160405280929190818152602001828054611689906132c4565b80156116d65780601f106116ab576101008083540402835291602001916116d6565b820191906000526020600020905b8154815290600101906020018083116116b957829003601f168201915b5050505050905090565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821115611745576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173c90613368565b60405180910390fd5b819050919050565b6000808212156117665781611761906126de565b611768565b815b9050919050565b600060019054906101000a900460ff166117be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117b590613275565b60405180910390fd5b81600390805190602001906117d492919061198e565b5080600490805190602001906117eb92919061198e565b506000801b6001819055506000801b6002819055505050565b600061180e611854565b905090565b60006040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61187f6118b8565b611887611923565b463060405160200161189d959493929190613388565b60405160208183030381529060405280519060200120905090565b6000806118c36115bc565b90506000815111156118df578080519060200120915050611920565b600060015490506000801b81146118fa578092505050611920565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470925050505b90565b60008061192e61164e565b905060008151111561194a57808051906020012091505061198b565b600060025490506000801b811461196557809250505061198b565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470925050505b90565b82805461199a906132c4565b90600052602060002090601f0160209004810192826119bc5760008555611a03565b82601f106119d557805160ff1916838001178555611a03565b82800160010185558215611a03579182015b82811115611a025782518255916020019190600101906119e7565b5b509050611a109190611a14565b5090565b5b80821115611a2d576000816000905550600101611a15565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b611a5881611a45565b8114611a6357600080fd5b50565b600081359050611a7581611a4f565b92915050565b600060208284031215611a9157611a90611a3b565b5b6000611a9f84828501611a66565b91505092915050565b6000819050919050565b611abb81611aa8565b82525050565b6000819050919050565b611ad481611ac1565b82525050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110611b1a57611b19611ada565b5b50565b6000819050611b2b82611b09565b919050565b6000611b3b82611b1d565b9050919050565b611b4b81611b30565b82525050565b6000606082019050611b666000830186611ab2565b611b736020830185611acb565b611b806040830184611b42565b949350505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611bd682611b8d565b810181811067ffffffffffffffff82111715611bf557611bf4611b9e565b5b80604052505050565b6000611c08611a31565b9050611c148282611bcd565b919050565b611c2281611aa8565b8114611c2d57600080fd5b50565b600081359050611c3f81611c19565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611c7082611c45565b9050919050565b611c8081611c65565b8114611c8b57600080fd5b50565b600081359050611c9d81611c77565b92915050565b611cac81611ac1565b8114611cb757600080fd5b50565b600081359050611cc981611ca3565b92915050565b60008115159050919050565b611ce481611ccf565b8114611cef57600080fd5b50565b600081359050611d0181611cdb565b92915050565b600060e08284031215611d1d57611d1c611b88565b5b611d2760e0611bfe565b90506000611d3784828501611c30565b6000830152506020611d4b84828501611c8e565b6020830152506040611d5f84828501611cba565b6040830152506060611d7384828501611c30565b6060830152506080611d8784828501611c30565b60808301525060a0611d9b84828501611cf2565b60a08301525060c0611daf84828501611cf2565b60c08301525092915050565b600080fd5b600080fd5b600067ffffffffffffffff821115611de057611ddf611b9e565b5b611de982611b8d565b9050602081019050919050565b82818337600083830152505050565b6000611e18611e1384611dc5565b611bfe565b905082815260208101848484011115611e3457611e33611dc0565b5b611e3f848285611df6565b509392505050565b600082601f830112611e5c57611e5b611dbb565b5b8135611e6c848260208601611e05565b91505092915050565b6000806101008385031215611e8d57611e8c611a3b565b5b6000611e9b85828601611d07565b92505060e083013567ffffffffffffffff811115611ebc57611ebb611a40565b5b611ec885828601611e47565b9150509250929050565b6000602082019050611ee76000830184611ab2565b92915050565b600067ffffffffffffffff821115611f0857611f07611b9e565b5b602082029050919050565b600080fd5b6000611f2b611f2684611eed565b611bfe565b90508060e08402830185811115611f4557611f44611f13565b5b835b81811015611f6e5780611f5a8882611d07565b84526020840193505060e081019050611f47565b5050509392505050565b600082601f830112611f8d57611f8c611dbb565b5b6002611f9a848285611f18565b91505092915050565b6000806101e08385031215611fbb57611fba611a3b565b5b6000611fc985828601611f78565b9250506101c0611fdb85828601611cba565b9150509250929050565b600060208284031215611ffb57611ffa611a3b565b5b600061200984828501611c30565b91505092915050565b600067ffffffffffffffff82111561202d5761202c611b9e565b5b61203682611b8d565b9050602081019050919050565b600061205661205184612012565b611bfe565b90508281526020810184848401111561207257612071611dc0565b5b61207d848285611df6565b509392505050565b600082601f83011261209a57612099611dbb565b5b81356120aa848260208601612043565b91505092915050565b600080604083850312156120ca576120c9611a3b565b5b600083013567ffffffffffffffff8111156120e8576120e7611a40565b5b6120f485828601612085565b925050602083013567ffffffffffffffff81111561211557612114611a40565b5b61212185828601612085565b9150509250929050565b600060e0828403121561214157612140611a3b565b5b600061214f84828501611d07565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61218d81611aa8565b82525050565b600061219f8383612184565b60208301905092915050565b6000602082019050919050565b60006121c382612158565b6121cd8185612163565b93506121d883612174565b8060005b838110156122095781516121f08882612193565b97506121fb836121ab565b9250506001810190506121dc565b5085935050505092915050565b6000602082019050818103600083015261223081846121b8565b905092915050565b61224181611a45565b82525050565b600060208201905061225c6000830184612238565b92915050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b61229781612262565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b838110156122d75780820151818401526020810190506122bc565b838111156122e6576000848401525b50505050565b60006122f78261229d565b61230181856122a8565b93506123118185602086016122b9565b61231a81611b8d565b840191505092915050565b61232e81611c65565b82525050565b600060e082019050612349600083018a61228e565b818103602083015261235b81896122ec565b9050818103604083015261236f81886122ec565b905061237e6060830187611ab2565b61238b6080830186612325565b61239860a0830185612238565b81810360c08301526123aa81846121b8565b905098975050505050505050565b60008060008061014085870312156123d3576123d2611a3b565b5b60006123e187828801611c8e565b94505060206123f287828801611d07565b93505061010085013567ffffffffffffffff81111561241457612413611a40565b5b61242087828801611e47565b92505061012061243287828801611c30565b91505092959194509250565b60006040820190506124536000830185612325565b6124606020830184612238565b9392505050565b6000806040838503121561247e5761247d611a3b565b5b600061248c85828601611c30565b925050602061249d85828601611c8e565b9150509250929050565b60006040820190506124bc6000830185611acb565b6124c96020830184611ab2565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4f425f6f726465725f305f69735f6e6f745f6c6f6e6700000000000000000000600082015250565b60006125356016836122a8565b9150612540826124ff565b602082019050919050565b6000602082019050818103600083015261256481612528565b9050919050565b7f4f425f6f726465725f315f69735f6e6f745f73686f7274000000000000000000600082015250565b60006125a16017836122a8565b91506125ac8261256b565b602082019050919050565b600060208201905081810360008301526125d081612594565b9050919050565b7f4f425f66696c6c416d6f756e745f69735f6e6567000000000000000000000000600082015250565b600061260d6014836122a8565b9150612618826125d7565b602082019050919050565b6000602082019050818103600083015261263c81612600565b9050919050565b7f4f425f6f72646572735f646f5f6e6f745f6d6174636800000000000000000000600082015250565b60006126796016836122a8565b915061268482612643565b602082019050919050565b600060208201905081810360008301526126a88161266c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006126e982611ac1565b91507f800000000000000000000000000000000000000000000000000000000000000082141561271c5761271b6126af565b5b816000039050919050565b600061273282611aa8565b915061273d83611aa8565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612776576127756126af565b5b828202905092915050565b600060a0820190506127966000830188611ab2565b6127a36020830187611ab2565b6127b06040830186611ab2565b6127bd6060830185612325565b6127ca6080830184611ab2565b9695505050505050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000612830602e836122a8565b915061283b826127d4565b604082019050919050565b6000602082019050818103600083015261285f81612823565b9050919050565b6000819050919050565b600060ff82169050919050565b6000819050919050565b60006128a261289d61289884612866565b61287d565b612870565b9050919050565b6128b281612887565b82525050565b60006020820190506128cd60008301846128a9565b92915050565b7f4f425f73656e6465725f69735f6e6f745f747261646572000000000000000000600082015250565b60006129096017836122a8565b9150612914826128d3565b602082019050919050565b60006020820190508181036000830152612938816128fc565b9050919050565b7f4f425f4f726465725f646f65735f6e6f745f6578697374000000000000000000600082015250565b60006129756017836122a8565b91506129808261293f565b602082019050919050565b600060208201905081810360008301526129a481612968565b9050919050565b6129b481611c65565b82525050565b6129c381611ac1565b82525050565b6129d281611ccf565b82525050565b60e0820160008201516129ee6000850182612184565b506020820151612a0160208501826129ab565b506040820151612a1460408501826129ba565b506060820151612a276060850182612184565b506080820151612a3a6080850182612184565b5060a0820151612a4d60a08501826129c9565b5060c0820151612a6060c08501826129c9565b50505050565b600061010082019050612a7c60008301856129d8565b612a8960e0830184611ab2565b9392505050565b6000612a9b82611aa8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612ace57612acd6126af565b5b600182019050919050565b600061010082019050612aef6000830185612238565b612afc60208301846129d8565b9392505050565b7f4549503731323a20556e696e697469616c697a65640000000000000000000000600082015250565b6000612b396015836122a8565b9150612b4482612b03565b602082019050919050565b60006020820190508181036000830152612b6881612b2c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612ba982611aa8565b9150612bb483611aa8565b925082612bc457612bc3612b6f565b5b828204905092915050565b6000612bda82611aa8565b9150612be583611aa8565b925082821015612bf857612bf76126af565b5b828203905092915050565b6000612c0e82611ac1565b9150612c1983611ac1565b9250827f800000000000000000000000000000000000000000000000000000000000000001821260008412151615612c5457612c536126af565b5b827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018213600084121615612c8c57612c8b6126af565b5b828203905092915050565b600081519050919050565b600082825260208201905092915050565b6000612cbe82612c97565b612cc88185612ca2565b9350612cd88185602086016122b9565b612ce181611b8d565b840191505092915050565b600060c0820190508181036000830152612d068189612cb3565b9050612d156020830188611ab2565b612d226040830187611ab2565b612d2f6060830186611ab2565b612d3c6080830185612325565b612d4960a0830184611ab2565b979650505050505050565b7f4f425f696e76616c69645f6f7264657200000000000000000000000000000000600082015250565b6000612d8a6010836122a8565b9150612d9582612d54565b602082019050919050565b60006020820190508181036000830152612db981612d7d565b9050919050565b6000612dcb82611ac1565b9150612dd683611ac1565b9250827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482116000841360008413161615612e1557612e146126af565b5b817f80000000000000000000000000000000000000000000000000000000000000000583126000841260008413161615612e5257612e516126af565b5b827f80000000000000000000000000000000000000000000000000000000000000000582126000841360008412161615612e8f57612e8e6126af565b5b827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0582126000841260008412161615612ecc57612ecb6126af565b5b828202905092915050565b7f4f425f66696c6c5f616e645f626173655f7369676e5f6e6f745f6d6174636800600082015250565b6000612f0d601f836122a8565b9150612f1882612ed7565b602082019050919050565b60006020820190508181036000830152612f3c81612f00565b9050919050565b7f4f425f696e76616c69645f66696c6c416d6f756e740000000000000000000000600082015250565b6000612f796015836122a8565b9150612f8482612f43565b602082019050919050565b60006020820190508181036000830152612fa881612f6c565b9050919050565b7f4f425f66696c6c65645f616d6f756e745f6869676865725f7468616e5f6f726460008201527f65725f6261736500000000000000000000000000000000000000000000000000602082015250565b600061300b6027836122a8565b915061301682612faf565b604082019050919050565b6000602082019050818103600083015261303a81612ffe565b9050919050565b600061304c82611ac1565b915061305783611ac1565b9250817f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03831360008312151615613092576130916126af565b5b817f80000000000000000000000000000000000000000000000000000000000000000383126000831216156130ca576130c96126af565b5b828201905092915050565b7f4f425f706c656173655f77686974656c6973745f6e65775f616d6d0000000000600082015250565b600061310b601b836122a8565b9150613116826130d5565b602082019050919050565b6000602082019050818103600083015261313a816130fe565b9050919050565b600061314c82611aa8565b915061315783611aa8565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561318c5761318b6126af565b5b828201905092915050565b7f53616665436173743a2076616c7565206d75737420626520706f736974697665600082015250565b60006131cd6020836122a8565b91506131d882613197565b602082019050919050565b600060208201905081810360008301526131fc816131c0565b9050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061325f602b836122a8565b915061326a82613203565b604082019050919050565b6000602082019050818103600083015261328e81613252565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806132dc57607f821691505b602082108114156132f0576132ef613295565b5b50919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e206160008201527f6e20696e74323536000000000000000000000000000000000000000000000000602082015250565b60006133526028836122a8565b915061335d826132f6565b604082019050919050565b6000602082019050818103600083015261338181613345565b9050919050565b600060a08201905061339d6000830188612238565b6133aa6020830187612238565b6133b76040830186612238565b6133c46060830185611ab2565b6133d16080830184612325565b969550505050505056fea26469706673582212200276ef85738145c532230c22fad4f9296689988ccee3dbc3efc448b09151466064736f6c63430008090033"},"0x03000000000000000000000000000000000000b2":{"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106100365760003560e01c806326e04f9d1461003b578063468f02d214610059575b600080fd5b610043610077565b604051610050919061010b565b60405180910390f35b61006161007d565b60405161006e91906101ee565b60405180910390f35b600c5481565b6060600167ffffffffffffffff81111561009a57610099610210565b5b6040519080825280602002602001820160405280156100c85781602001602082028036833780820191505090505b50905062989680816000815181106100e3576100e261023f565b5b60200260200101818152505090565b6000819050919050565b610105816100f2565b82525050565b600060208201905061012060008301846100fc565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b61016581610152565b82525050565b6000610177838361015c565b60208301905092915050565b6000602082019050919050565b600061019b82610126565b6101a58185610131565b93506101b083610142565b8060005b838110156101e15781516101c8888261016b565b97506101d383610183565b9250506001810190506101b4565b5085935050505092915050565b600060208201905081810360008301526102088184610190565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212204b2bb44fa7c6b4529a24bfb7bf0eb8f7f52f80902916e5021c3b7e81b638d0f564736f6c63430008090033","storage":{"0x000000000000000000000000000000000000000000000000000000000000000C":"0x01"}}},"nonce":"0x0","timestamp":"0x0","extraData":"0x00","gasLimit":"500000000","difficulty":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","coinbase":"0x0000000000000000000000000000000000000000","number":"0x0","gasUsed":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`
orderBookABI, err = abi.FromSolidityJson(orderBookABIStr)
if err != nil {
panic(err)
}
aliceKey, _ = crypto.HexToECDSA("56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027")
bobKey, _ = crypto.HexToECDSA("31b571bf6894a248831ff937bb49f7754509fe93bbd2517c9c73c4144c0e97dc")
alice = crypto.PubkeyToAddress(aliceKey.PublicKey)
bob = crypto.PubkeyToAddress(bobKey.PublicKey)
}
func createPlaceOrderTx(t *testing.T, vm *VM, trader common.Address, privateKey *ecdsa.PrivateKey, size *big.Int, price *big.Int, salt *big.Int) common.Hash {
nonce := vm.txPool.Nonce(trader)
order := struct {
AmmIndex *big.Int `json:"ammIndex"`
Trader common.Address `json:"trader"`
BaseAssetQuantity *big.Int `json:"baseAssetQuantity"`
Price *big.Int `json:"price"`
Salt *big.Int `json:"salt"`
ReduceOnly bool `json:"reduceOnly"`
PostOnly bool `json:"postOnly"`
}{
AmmIndex: big.NewInt(0),
Trader: trader,
BaseAssetQuantity: big.NewInt(0).Mul(size, _1e18),
Price: big.NewInt(0).Mul(price, _1e6),
Salt: salt,
ReduceOnly: false,
PostOnly: false,
}
data, err := orderBookABI.Pack("placeOrder", order)
if err != nil {
t.Fatalf("orderBookABI.Pack failed: %v", err)
}
tx := types.NewTransaction(nonce, orderBookAddress, big.NewInt(0), 8000000, big.NewInt(500000000000), data)
signer := types.NewLondonSigner(vm.chainConfig.ChainID)
signedTx, err := types.SignTx(tx, signer, privateKey)
if err != nil {
t.Fatalf("types.SignTx failed: %v", err)
}
errs := vm.txPool.AddRemotesSync([]*types.Transaction{signedTx})
for _, err := range errs {
if err != nil {
t.Fatalf("lop.txPool.AddOrderBookTx failed: %v", err)
}
}
return signedTx.Hash()
}
// A
// / \
// B C
// vm1 proposes block A containing order 1
// block A is accepted by vm1 and vm2
// vm1 proposes block B containing order 2
// vm1 and vm2 set preference to block B
// vm2 proposes block C containing order 2 & order 3
// vm1 and vm2 set preference to block C
// reorg happens when vm1 accepts block C
func TestHubbleLogs(t *testing.T) {
// Create two VMs which will agree on block A and then
// build the two distinct preferred chains above
ctx := context.Background()
issuer1, vm1, _, _ := GenesisVM(t, true, genesisJSON, "{\"pruning-enabled\":true,\"node-type\":\"kitkat\"}", "")
issuer2, vm2, _, _ := GenesisVM(t, true, genesisJSON, "{\"pruning-enabled\":true,\"node-type\":\"kitkat\"}", "")
defer func() {
if err := vm1.Shutdown(ctx); err != nil {
t.Fatal(err)
}
if err := vm2.Shutdown(ctx); err != nil {
t.Fatal(err)
}
}()
// long and short order
createPlaceOrderTx(t, vm1, alice, aliceKey, big.NewInt(5), big.NewInt(10), big.NewInt(101))
<-issuer1
// include alice's long order
blocksA := buildBlockAndSetPreference(t, vm1, vm2) // block A - both vms accept
accept(t, blocksA...)
createPlaceOrderTx(t, vm1, bob, bobKey, big.NewInt(-5), big.NewInt(10), big.NewInt(102))
<-issuer1
// bob's short order
buildBlockAndSetPreference(t, vm1) // block B - vm1 only
// build block C parallel to block B
createPlaceOrderTx(t, vm2, bob, bobKey, big.NewInt(-5), big.NewInt(10), big.NewInt(102)) // order 2
createPlaceOrderTx(t, vm2, alice, aliceKey, big.NewInt(5), big.NewInt(11), big.NewInt(104)) // order 3
<-issuer2
vm2BlockC := buildBlockAndSetPreference(t, vm2)[0] // block C - vm2 only for now
vm1BlockC := parseBlock(t, vm1, vm2BlockC)
setPreference(t, vm1BlockC, vm1)
accept(t, vm1BlockC) // reorg happens here
accept(t, vm2BlockC)
time.Sleep(time.Second)